// 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::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>

// 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 = unsigned 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

namespace perfetto {
namespace base {

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 {

// Do not add new usages of kPageSize, consider using GetSysPageSize() below.
// TODO(primiano): over time the semantic of kPageSize became too ambiguous.
// Strictly speaking, this constant is incorrect on some new devices where the
// page size can be 16K (e.g., crbug.com/1116576). Unfortunately too much code
// ended up depending on kPageSize for purposes that are not strictly related
// with the kernel's mm subsystem.
constexpr size_t kPageSize = 4096;

// Returns the system's page size. Use this when dealing with mmap, madvise and
// similar mm-related syscalls.
uint32_t GetSysPageSize();

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).
template <size_t alignment>
constexpr size_t AlignUp(size_t size) {
  static_assert((alignment & (alignment - 1)) == 0, "alignment must be a pow2");
  return (size + alignment - 1) & ~(alignment - 1);
}

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);

// 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/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_

// 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.
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
// Windows.h typedefs HANDLE to void*. We use void* here to avoid leaking
// Windows.h through our headers.
using PlatformHandle = void*;

// 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;
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_
// 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 <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;
#else
using FileOpenMode = mode_t;
#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);

}  // 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/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/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

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);
}

}  // 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,
                             unsigned long address,
                             unsigned long size,
                             const char* description);
}

#define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description)   \
  AnnotateBenignRaceSized(__FILE__, __LINE__,                             \
                          reinterpret_cast<unsigned long>(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_DRAIN), /*unused*/ \
  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 > 0u);
  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::shared_ptr<T*>(new 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::shared_ptr<T*>(new 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/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>
#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;
}

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"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
namespace {
std::string GetTempName() {
  char name[] = "perfetto-XXXXXX";
  PERFETTO_CHECK(_mktemp_s(name, sizeof(name)) == 0);
  return name;
}
}  // namespace
#endif

namespace perfetto {
namespace base {

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_ = GetSysTempDir() + "\\" + GetTempName();
  // 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_ = GetSysTempDir() + "\\" + GetTempName();
  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
/*
 * 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/base/build_config.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>
#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)

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;
}
#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.
 */

// 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"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#else
#include <unistd.h>
#endif

namespace perfetto {
namespace base {

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

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() {
  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);
}

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));
}

#else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

void SleepMicroseconds(unsigned interval_us) {
  ::usleep(static_cast<useconds_t>(interval_us));
}

#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;
}

}  // 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 {

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
}

uint32_t GetSysPageSize() {
  ignore_result(kPageSize);  // Just to keep the amalgamated build happy.
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  static std::atomic<uint32_t> page_size{0};
  // This function might be called in hot paths. Avoid calling getpagesize() all
  // the times, in many implementations getpagesize() calls sysconf() which is
  // not cheap.
  uint32_t cached_value = page_size.load(std::memory_order_relaxed);
  if (PERFETTO_UNLIKELY(cached_value == 0)) {
    cached_value = static_cast<uint32_t>(getpagesize());
    page_size.store(cached_value, std::memory_order_relaxed);
  }
  return cached_value;
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  return static_cast<uint32_t>(vm_page_size);
#else
  return 4096;
#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_
/*
 * 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 <random>

// gen_amalgamated expanded: #include "perfetto/base/time.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

// See https://www.ietf.org/rfc/rfc4122.txt
Uuid Uuidv4() {
  static std::minstd_rand rng(static_cast<uint32_t>(GetBootTimeNs().count()));
  Uuid uuid;
  auto& data = *uuid.data();

  for (size_t i = 0; i < 16; ++i)
    data[i] = static_cast<uint8_t>(rng());

  // version:
  data[6] = (data[6] & 0x0f) | 0x40;
  // clock_seq_hi_and_reserved:
  data[8] = (data[8] & 0x3f) | 0x80;

  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.
  void Wait();

  // Signal the event, waking up blocked waiters.
  void Notify();

 private:
  std::mutex mutex_;
  std::condition_variable event_;
  bool notified_ = false;
};

}  // 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() {
  std::unique_lock<std::mutex> lock(mutex_);
  return event_.wait(lock, [this] { return notified_; });
}

void WaitableEvent::Notify() {
  std::unique_lock<std::mutex> lock(mutex_);
  notified_ = true;
  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_
// 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"

#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;
}

#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) 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
// 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_;
};

}  // namespace gen_helpers
}  // namespace internal
}  // namespace protozero

#endif  // 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.
 */

// 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();
}

}  // 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 {

#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;
  size_already_written_ = 0;
  nested_message_ = nullptr;
  finalized_ = false;
#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) {
  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) {
  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 (finalized_)
    return size_;

  if (nested_message_)
    EndNestedMessage();

  // Write the length of the nested message a posteriori, using a leading-zero
  // redundant varint encoding.
  if (size_field_) {
    PERFETTO_DCHECK(!finalized_);
    PERFETTO_DCHECK(size_ < proto_utils::kMaxMessageLength);
    PERFETTO_DCHECK(size_ >= size_already_written_);
    proto_utils::WriteRedundantVarInt(size_ - size_already_written_,
                                      size_field_);
    size_field_ = nullptr;
  }

  finalized_ = true;
#if PERFETTO_DCHECK_IS_ON()
  if (handle_)
    handle_->reset_message();
#endif

  return size_;
}

Message* Message::BeginNestedMessageInternal(uint32_t 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();
  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.
      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
// 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_
/*
 * 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
// 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_
/*
 * 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"

namespace protozero {

CppMessageObj::~CppMessageObj() = default;

}  // namespace protozero
// gen_amalgamated begin source: gen/protos/perfetto/common/android_energy_consumer_descriptor.gen.cc
// 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 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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && energy_consumer_id_ == other.energy_consumer_id_
   && ordinal_ == other.ordinal_
   && type_ == other.type_
   && 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 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 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 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_MAX_ID = 63,
};
}  // namespace perfetto
}  // namespace protos
}  // namespace gen

#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
// 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 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,
  };

  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); }

 private:
  uint32_t page_{};
  uint32_t chunk_{};
  uint32_t target_buffer_{};

  // 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_COMMIT_DATA_REQUEST_PROTO_CPP_H_
// 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 unknown_fields_ == other.unknown_fields_
   && chunks_to_move_ == other.chunks_to_move_
   && chunks_to_patch_ == other.chunks_to_patch_
   && 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 unknown_fields_ == other.unknown_fields_
   && target_buffer_ == other.target_buffer_
   && writer_id_ == other.writer_id_
   && chunk_id_ == other.chunk_id_
   && patches_ == other.patches_
   && 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 unknown_fields_ == other.unknown_fields_
   && offset_ == other.offset_
   && 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 unknown_fields_ == other.unknown_fields_
   && page_ == other.page_
   && chunk_ == other.chunk_
   && target_buffer_ == other.target_buffer_;
}

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;
      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);
  }

  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 unknown_fields_ == other.unknown_fields_
   && name_ == other.name_
   && id_ == other.id_
   && will_notify_on_stop_ == other.will_notify_on_stop_
   && will_notify_on_start_ == other.will_notify_on_start_
   && handles_incremental_state_clear_ == other.handles_incremental_state_clear_
   && gpu_counter_descriptor_ == other.gpu_counter_descriptor_
   && track_event_descriptor_ == other.track_event_descriptor_
   && 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 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 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 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 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,
  };

  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); }

 private:
  bool packed_{};

  // 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 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 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 unknown_fields_ == other.unknown_fields_
   && name_ == other.name_
   && 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 unknown_fields_ == other.unknown_fields_
   && name_ == other.name_
   && value_ == other.value_
   && 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 unknown_fields_ == other.unknown_fields_
   && name_ == other.name_
   && 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 unknown_fields_ == other.unknown_fields_
   && name_ == other.name_
   && number_ == other.number_
   && label_ == other.label_
   && type_ == other.type_
   && type_name_ == other.type_name_
   && extendee_ == other.extendee_
   && default_value_ == other.default_value_
   && options_ == other.options_
   && 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 unknown_fields_ == other.unknown_fields_
   && packed_ == other.packed_;
}

bool FieldOptions::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 /* packed */:
        field.get(&packed_);
        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);
  }

  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 unknown_fields_ == other.unknown_fields_
   && name_ == other.name_
   && field_ == other.field_
   && extension_ == other.extension_
   && nested_type_ == other.nested_type_
   && enum_type_ == other.enum_type_
   && oneof_decl_ == other.oneof_decl_
   && reserved_range_ == other.reserved_range_
   && 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 unknown_fields_ == other.unknown_fields_
   && start_ == other.start_
   && 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 unknown_fields_ == other.unknown_fields_
   && name_ == other.name_
   && package_ == other.package_
   && dependency_ == other.dependency_
   && public_dependency_ == other.public_dependency_
   && weak_dependency_ == other.weak_dependency_
   && message_type_ == other.message_type_
   && enum_type_ == other.enum_type_
   && 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 unknown_fields_ == other.unknown_fields_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && name_ == other.name_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && specs_ == other.specs_
   && blocks_ == other.blocks_
   && min_sampling_period_ns_ == other.min_sampling_period_ns_
   && max_sampling_period_ns_ == other.max_sampling_period_ns_
   && 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 unknown_fields_ == other.unknown_fields_
   && block_id_ == other.block_id_
   && block_capacity_ == other.block_capacity_
   && name_ == other.name_
   && description_ == other.description_
   && 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 unknown_fields_ == other.unknown_fields_
   && counter_id_ == other.counter_id_
   && name_ == other.name_
   && description_ == other.description_
   && int_peak_value_ == other.int_peak_value_
   && double_peak_value_ == other.double_peak_value_
   && numerator_units_ == other.numerator_units_
   && denominator_units_ == other.denominator_units_
   && select_by_default_ == other.select_by_default_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && instance_state_changes_ == other.instance_state_changes_
   && all_data_sources_started_ == other.all_data_sources_started_
   && 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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && producer_name_ == other.producer_name_
   && data_source_name_ == other.data_source_name_
   && 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 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 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 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 unknown_fields_ == other.unknown_fields_
   && type_ == other.type_
   && config_ == other.config_
   && config1_ == other.config1_
   && 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 unknown_fields_ == other.unknown_fields_
   && name_ == other.name_
   && 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 unknown_fields_ == other.unknown_fields_
   && frequency_ == other.frequency_
   && period_ == other.period_
   && counter_ == other.counter_
   && tracepoint_ == other.tracepoint_
   && raw_event_ == other.raw_event_
   && timestamp_clock_ == other.timestamp_clock_
   && 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/sys_stats_counters.gen.cc
// 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,
};
}  // namespace perfetto
}  // namespace protos
}  // namespace gen

#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
// 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 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,
  };

  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); }

 private:
  uint64_t input_packets_{};
  uint64_t input_bytes_{};
  uint64_t output_bytes_{};
  uint64_t errors_{};
  uint64_t time_taken_ns_{};

  // 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 TraceStats_WriterStats : public ::protozero::CppMessageObj {
 public:
  enum FieldNumbers {
    kSequenceIdFieldNumber = 1,
    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); }

  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_{};
  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<4> _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 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 unknown_fields_ == other.unknown_fields_
   && buffer_stats_ == other.buffer_stats_
   && chunk_payload_histogram_def_ == other.chunk_payload_histogram_def_
   && writer_stats_ == other.writer_stats_
   && producers_connected_ == other.producers_connected_
   && producers_seen_ == other.producers_seen_
   && data_sources_registered_ == other.data_sources_registered_
   && data_sources_seen_ == other.data_sources_seen_
   && tracing_sessions_ == other.tracing_sessions_
   && total_buffers_ == other.total_buffers_
   && chunks_discarded_ == other.chunks_discarded_
   && patches_discarded_ == other.patches_discarded_
   && invalid_packets_ == other.invalid_packets_
   && filter_stats_ == other.filter_stats_
   && flushes_requested_ == other.flushes_requested_
   && flushes_succeeded_ == other.flushes_succeeded_
   && flushes_failed_ == other.flushes_failed_
   && 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 unknown_fields_ == other.unknown_fields_
   && input_packets_ == other.input_packets_
   && input_bytes_ == other.input_bytes_
   && output_bytes_ == other.output_bytes_
   && errors_ == other.errors_
   && time_taken_ns_ == other.time_taken_ns_;
}

bool TraceStats_FilterStats::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 /* 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;
      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);
  }

  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 unknown_fields_ == other.unknown_fields_
   && sequence_id_ == other.sequence_id_
   && chunk_payload_histogram_counts_ == other.chunk_payload_histogram_counts_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && buffer_size_ == other.buffer_size_
   && bytes_written_ == other.bytes_written_
   && bytes_overwritten_ == other.bytes_overwritten_
   && bytes_read_ == other.bytes_read_
   && padding_bytes_written_ == other.padding_bytes_written_
   && padding_bytes_cleared_ == other.padding_bytes_cleared_
   && chunks_written_ == other.chunks_written_
   && chunks_rewritten_ == other.chunks_rewritten_
   && chunks_overwritten_ == other.chunks_overwritten_
   && chunks_discarded_ == other.chunks_discarded_
   && chunks_read_ == other.chunks_read_
   && chunks_committed_out_of_order_ == other.chunks_committed_out_of_order_
   && write_wrap_count_ == other.write_wrap_count_
   && patches_succeeded_ == other.patches_succeeded_
   && patches_failed_ == other.patches_failed_
   && readaheads_succeeded_ == other.readaheads_succeeded_
   && readaheads_failed_ == other.readaheads_failed_
   && abi_violations_ == other.abi_violations_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && has_query_capabilities_ == other.has_query_capabilities_
   && observable_events_ == other.observable_events_
   && has_trace_config_output_path_ == other.has_trace_config_output_path_
   && 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 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,
  };

  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); }

 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_{};

  // 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 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 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 unknown_fields_ == other.unknown_fields_
   && producers_ == other.producers_
   && data_sources_ == other.data_sources_
   && tracing_sessions_ == other.tracing_sessions_
   && supports_tracing_sessions_ == other.supports_tracing_sessions_
   && num_sessions_ == other.num_sessions_
   && num_sessions_started_ == other.num_sessions_started_
   && 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 unknown_fields_ == other.unknown_fields_
   && id_ == other.id_
   && consumer_uid_ == other.consumer_uid_
   && state_ == other.state_
   && unique_session_name_ == other.unique_session_name_
   && buffer_size_kb_ == other.buffer_size_kb_
   && duration_ms_ == other.duration_ms_
   && num_data_sources_ == other.num_data_sources_
   && start_realtime_ns_ == other.start_realtime_ns_;
}

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;
      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);
  }

  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 unknown_fields_ == other.unknown_fields_
   && ds_descriptor_ == other.ds_descriptor_
   && 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 unknown_fields_ == other.unknown_fields_
   && id_ == other.id_
   && name_ == other.name_
   && pid_ == other.pid_
   && uid_ == other.uid_
   && 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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && name_ == other.name_
   && description_ == other.description_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && 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_log_config.gen.cc
// 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 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 unknown_fields_ == other.unknown_fields_
   && log_ids_ == other.log_ids_
   && min_prio_ == other.min_prio_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && 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_system_property_config.gen.cc
// 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 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 unknown_fields_ == other.unknown_fields_
   && poll_ms_ == other.poll_ms_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && poll_ms_ == other.poll_ms_
   && aggregation_threshold_ == other.aggregation_threshold_
   && intern_limit_ == other.intern_limit_
   && drop_local_port_ == other.drop_local_port_
   && drop_remote_port_ == other.drop_remote_port_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && 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/surfaceflinger_layers_config.gen.cc
// 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,
};
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_MIN = SurfaceFlingerLayersConfig_Mode_MODE_UNSPECIFIED;
  static constexpr auto Mode_MAX = SurfaceFlingerLayersConfig_Mode_MODE_DUMP;
  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 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 unknown_fields_ == other.unknown_fields_
   && mode_ == other.mode_
   && 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/ftrace/ftrace_config.gen.cc
// 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,
    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,
  };

  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_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); }

 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_{};
  ::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_{};

  // Allows to preserve unknown protobuf fields for compatibility
  // with future versions of .proto files.
  std::string unknown_fields_;

  std::bitset<26> _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 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 unknown_fields_ == other.unknown_fields_
   && ftrace_events_ == other.ftrace_events_
   && atrace_categories_ == other.atrace_categories_
   && atrace_apps_ == other.atrace_apps_
   && buffer_size_kb_ == other.buffer_size_kb_
   && drain_period_ms_ == other.drain_period_ms_
   && compact_sched_ == other.compact_sched_
   && print_filter_ == other.print_filter_
   && symbolize_ksyms_ == other.symbolize_ksyms_
   && ksyms_mem_policy_ == other.ksyms_mem_policy_
   && initialize_ksyms_synchronously_for_testing_ == other.initialize_ksyms_synchronously_for_testing_
   && throttle_rss_stat_ == other.throttle_rss_stat_
   && disable_generic_events_ == other.disable_generic_events_
   && syscall_events_ == other.syscall_events_
   && enable_function_graph_ == other.enable_function_graph_
   && function_filters_ == other.function_filters_
   && function_graph_roots_ == other.function_graph_roots_
   && preserve_ftrace_buffer_ == other.preserve_ftrace_buffer_
   && use_monotonic_raw_clock_ == other.use_monotonic_raw_clock_
   && instance_name_ == other.instance_name_;
}

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 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;
      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 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);
  }

  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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && prefix_ == other.prefix_
   && atrace_msg_ == other.atrace_msg_
   && 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 unknown_fields_ == other.unknown_fields_
   && type_ == other.type_
   && 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 unknown_fields_ == other.unknown_fields_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && counter_period_ns_ == other.counter_period_ns_
   && counter_ids_ == other.counter_ids_
   && instrumented_sampling_ == other.instrumented_sampling_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && track_driver_memory_usage_ == other.track_driver_memory_usage_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && scan_interval_ms_ == other.scan_interval_ms_
   && scan_delay_ms_ == other.scan_delay_ms_
   && scan_batch_size_ == other.scan_batch_size_
   && do_not_scan_ == other.do_not_scan_
   && scan_mount_points_ == other.scan_mount_points_
   && 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 unknown_fields_ == other.unknown_fields_
   && mountpoint_ == other.mountpoint_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && output_ == other.output_
   && 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 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,
};

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 BatteryCounters_MIN = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED;
  static constexpr auto BatteryCounters_MAX = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG;
  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 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 unknown_fields_ == other.unknown_fields_
   && battery_poll_ms_ == other.battery_poll_ms_
   && battery_counters_ == other.battery_counters_
   && collect_power_rails_ == other.collect_power_rails_
   && collect_energy_estimation_breakdown_ == other.collect_energy_estimation_breakdown_
   && 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 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,
  };

  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); }

 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_{};

  // 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_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
// 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 unknown_fields_ == other.unknown_fields_
   && quirks_ == other.quirks_
   && scan_all_processes_on_start_ == other.scan_all_processes_on_start_
   && record_thread_names_ == other.record_thread_names_
   && proc_stats_poll_ms_ == other.proc_stats_poll_ms_
   && proc_stats_cache_ttl_ms_ == other.proc_stats_cache_ttl_ms_
   && resolve_process_fds_ == other.resolve_process_fds_
   && scan_smaps_rollup_ == other.scan_smaps_rollup_;
}

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;
      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);
  }

  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 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 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 unknown_fields_ == other.unknown_fields_
   && sampling_interval_bytes_ == other.sampling_interval_bytes_
   && adaptive_sampling_shmem_threshold_ == other.adaptive_sampling_shmem_threshold_
   && adaptive_sampling_max_sampling_interval_bytes_ == other.adaptive_sampling_max_sampling_interval_bytes_
   && process_cmdline_ == other.process_cmdline_
   && pid_ == other.pid_
   && target_installed_by_ == other.target_installed_by_
   && heaps_ == other.heaps_
   && exclude_heaps_ == other.exclude_heaps_
   && stream_allocations_ == other.stream_allocations_
   && heap_sampling_intervals_ == other.heap_sampling_intervals_
   && all_heaps_ == other.all_heaps_
   && all_ == other.all_
   && min_anonymous_memory_kb_ == other.min_anonymous_memory_kb_
   && max_heapprofd_memory_kb_ == other.max_heapprofd_memory_kb_
   && max_heapprofd_cpu_secs_ == other.max_heapprofd_cpu_secs_
   && skip_symbol_prefix_ == other.skip_symbol_prefix_
   && continuous_dump_config_ == other.continuous_dump_config_
   && shmem_size_bytes_ == other.shmem_size_bytes_
   && block_client_ == other.block_client_
   && block_client_timeout_us_ == other.block_client_timeout_us_
   && no_startup_ == other.no_startup_
   && no_running_ == other.no_running_
   && dump_at_max_ == other.dump_at_max_
   && disable_fork_teardown_ == other.disable_fork_teardown_
   && 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 unknown_fields_ == other.unknown_fields_
   && dump_phase_ms_ == other.dump_phase_ms_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && process_cmdline_ == other.process_cmdline_
   && pid_ == other.pid_
   && target_installed_by_ == other.target_installed_by_
   && continuous_dump_config_ == other.continuous_dump_config_
   && min_anonymous_memory_kb_ == other.min_anonymous_memory_kb_
   && dump_smaps_ == other.dump_smaps_
   && 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 unknown_fields_ == other.unknown_fields_
   && dump_phase_ms_ == other.dump_phase_ms_
   && dump_interval_ms_ == other.dump_interval_ms_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && timebase_ == other.timebase_
   && callstack_sampling_ == other.callstack_sampling_
   && ring_buffer_read_period_ms_ == other.ring_buffer_read_period_ms_
   && ring_buffer_pages_ == other.ring_buffer_pages_
   && max_enqueued_footprint_kb_ == other.max_enqueued_footprint_kb_
   && max_daemon_memory_kb_ == other.max_daemon_memory_kb_
   && remote_descriptor_timeout_ms_ == other.remote_descriptor_timeout_ms_
   && unwind_state_clear_period_ms_ == other.unwind_state_clear_period_ms_
   && target_installed_by_ == other.target_installed_by_
   && all_cpus_ == other.all_cpus_
   && sampling_frequency_ == other.sampling_frequency_
   && kernel_frames_ == other.kernel_frames_
   && target_pid_ == other.target_pid_
   && target_cmdline_ == other.target_cmdline_
   && exclude_pid_ == other.exclude_pid_
   && exclude_cmdline_ == other.exclude_cmdline_
   && 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 unknown_fields_ == other.unknown_fields_
   && scope_ == other.scope_
   && kernel_frames_ == other.kernel_frames_
   && 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 unknown_fields_ == other.unknown_fields_
   && target_pid_ == other.target_pid_
   && target_cmdline_ == other.target_cmdline_
   && exclude_pid_ == other.exclude_pid_
   && exclude_cmdline_ == other.exclude_cmdline_
   && additional_cmdline_count_ == other.additional_cmdline_count_
   && 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 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_ART_DATUM_REPORTED = 332,
  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_ODREFRESH_REPORTED = 366,
  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_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_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_BACKGROUND_DEXOPT_JOB_ENDED = 467,
  ATOM_SYNC_EXEMPTION_OCCURRED = 468,
  ATOM_AUTOFILL_PRESENTATION_EVENT_REPORTED = 469,
  ATOM_DOCK_STATE_CHANGED = 470,
  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_VIBRATION_REPORTED = 487,
  ATOM_UWB_RANGING_START = 489,
  ATOM_DISPLAY_BRIGHTNESS_CHANGED = 494,
  ATOM_ACTIVITY_ACTION_BLOCKED = 495,
  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_HEARING_AID_INFO_REPORTED = 513,
  ATOM_DEVICE_WIDE_JOB_CONSTRAINT_CHANGED = 514,
  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_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_LAUNCHER_IMPRESSION_EVENT = 547,
  ATOM_ODSIGN_REPORTED = 548,
  ATOM_ART_DEVICE_DATUM_REPORTED = 550,
  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_ART_DATUM_DELTA_REPORTED = 565,
  ATOM_MEDIA_DRM_CREATED = 568,
  ATOM_MEDIA_DRM_ERRORED = 569,
  ATOM_MEDIA_DRM_SESSION_OPENED = 570,
  ATOM_MEDIA_DRM_SESSION_CLOSED = 571,
  ATOM_PERFORMANCE_HINT_SESSION_REPORTED = 574,
  ATOM_HOTWORD_AUDIO_EGRESS_EVENT_REPORTED = 578,
  ATOM_NETWORK_VALIDATION_FAILURE_STATS_DAILY_REPORTED = 601,
  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_INCOMING_MMS = 10157,
  ATOM_OUTGOING_MMS = 10158,
  ATOM_MULTI_USER_INFO = 10160,
  ATOM_NETWORK_BPF_MAP_INFO = 10161,
  ATOM_CONNECTIVITY_STATE_SAMPLE = 10163,
  ATOM_NETWORK_SELECTION_REMATCH_REASONS_INFO = 10164,
  ATOM_NETWORK_SLICE_REQUEST_COUNT = 10168,
  ATOM_ADPF_SYSTEM_COMPONENT_INFO = 10173,
  ATOM_NOTIFICATION_MEMORY_USE = 10174,
};
}  // namespace perfetto
}  // namespace protos
}  // namespace gen

#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_ATOM_IDS_PROTO_CPP_H_
// 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 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 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 unknown_fields_ == other.unknown_fields_
   && pull_atom_id_ == other.pull_atom_id_
   && raw_pull_atom_id_ == other.raw_pull_atom_id_
   && pull_frequency_ms_ == other.pull_frequency_ms_
   && 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 unknown_fields_ == other.unknown_fields_
   && push_atom_id_ == other.push_atom_id_
   && raw_push_atom_id_ == other.raw_push_atom_id_
   && 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 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,
  };

  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); }

 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_{};

  // 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_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
// 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 unknown_fields_ == other.unknown_fields_
   && meminfo_period_ms_ == other.meminfo_period_ms_
   && meminfo_counters_ == other.meminfo_counters_
   && vmstat_period_ms_ == other.vmstat_period_ms_
   && vmstat_counters_ == other.vmstat_counters_
   && stat_period_ms_ == other.stat_period_ms_
   && stat_counters_ == other.stat_counters_
   && devfreq_period_ms_ == other.devfreq_period_ms_
   && cpufreq_period_ms_ == other.cpufreq_period_ms_
   && buddyinfo_period_ms_ == other.buddyinfo_period_ms_
   && diskstat_period_ms_ == other.diskstat_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;
      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);
  }

  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 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 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 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 unknown_fields_ == other.unknown_fields_
   && disabled_categories_ == other.disabled_categories_
   && enabled_categories_ == other.enabled_categories_
   && disabled_tags_ == other.disabled_tags_
   && enabled_tags_ == other.enabled_tags_
   && disable_incremental_timestamps_ == other.disable_incremental_timestamps_
   && timestamp_unit_multiplier_ == other.timestamp_unit_multiplier_
   && filter_debug_annotations_ == other.filter_debug_annotations_
   && enable_thread_time_sampling_ == other.enable_thread_time_sampling_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && trace_config_ == other.trace_config_
   && privacy_filtering_enabled_ == other.privacy_filtering_enabled_
   && convert_to_legacy_json_ == other.convert_to_legacy_json_
   && client_priority_ == other.client_priority_
   && 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 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 ChromeFieldTracingConfig;
class ScenarioConfig;
class NestedScenarioConfig;
class TriggerRule;
class TriggerRule_RepeatingInterval;
class TriggerRule_HistogramTrigger;
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 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 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 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_{};
};


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,
    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_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_{};
  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<7> _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_{};
};

}  // 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/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/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;
}  // 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); }

  const std::string& console_config_raw() const { return console_config_; }
  void set_console_config_raw(const std::string& raw) { console_config_ = raw; _has_field_.set(100); }

 private:
  std::string name_{};
  std::string console_config_;  // [lazy=true]

  // 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 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/chrome/chrome_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_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_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_game_intervention_list_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && scenario_name_ == other.scenario_name_
   && start_rules_ == other.start_rules_
   && stop_rules_ == other.stop_rules_
   && upload_rules_ == other.upload_rules_
   && setup_rules_ == other.setup_rules_
   && trace_config_ == other.trace_config_
   && 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 unknown_fields_ == other.unknown_fields_
   && scenario_name_ == other.scenario_name_
   && start_rules_ == other.start_rules_
   && stop_rules_ == other.stop_rules_
   && 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);
}


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 unknown_fields_ == other.unknown_fields_
   && name_ == other.name_
   && trigger_chance_ == other.trigger_chance_
   && delay_ms_ == other.delay_ms_
   && manual_trigger_name_ == other.manual_trigger_name_
   && histogram_ == other.histogram_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && period_ms_ == other.period_ms_
   && 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 unknown_fields_ == other.unknown_fields_
   && histogram_name_ == other.histogram_name_
   && min_value_ == other.min_value_
   && 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);
}

}  // 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 unknown_fields_ == other.unknown_fields_
   && name_ == other.name_
   && target_buffer_ == other.target_buffer_
   && trace_duration_ms_ == other.trace_duration_ms_
   && prefer_suspend_clock_for_duration_ == other.prefer_suspend_clock_for_duration_
   && stop_timeout_ms_ == other.stop_timeout_ms_
   && enable_extra_guardrails_ == other.enable_extra_guardrails_
   && session_initiator_ == other.session_initiator_
   && tracing_session_id_ == other.tracing_session_id_
   && ftrace_config_ == other.ftrace_config_
   && inode_file_config_ == other.inode_file_config_
   && process_stats_config_ == other.process_stats_config_
   && sys_stats_config_ == other.sys_stats_config_
   && heapprofd_config_ == other.heapprofd_config_
   && java_hprof_config_ == other.java_hprof_config_
   && android_power_config_ == other.android_power_config_
   && android_log_config_ == other.android_log_config_
   && gpu_counter_config_ == other.gpu_counter_config_
   && android_game_intervention_list_config_ == other.android_game_intervention_list_config_
   && packages_list_config_ == other.packages_list_config_
   && perf_event_config_ == other.perf_event_config_
   && vulkan_memory_config_ == other.vulkan_memory_config_
   && track_event_config_ == other.track_event_config_
   && android_polled_state_config_ == other.android_polled_state_config_
   && android_system_property_config_ == other.android_system_property_config_
   && statsd_tracing_config_ == other.statsd_tracing_config_
   && system_info_config_ == other.system_info_config_
   && chrome_config_ == other.chrome_config_
   && interceptor_config_ == other.interceptor_config_
   && network_packet_trace_config_ == other.network_packet_trace_config_
   && surfaceflinger_layers_config_ == other.surfaceflinger_layers_config_
   && legacy_config_ == other.legacy_config_
   && 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 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 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 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 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/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"

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 unknown_fields_ == other.unknown_fields_
   && name_ == other.name_
   && 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 */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &console_config_);
        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]) {
    msg->AppendString(100, console_config_);
  }

  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 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 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 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 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/chrome/chrome_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_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_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_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 unknown_fields_ == other.unknown_fields_
   && trace_config_ == other.trace_config_
   && shmem_size_kb_ == other.shmem_size_kb_
   && shmem_page_size_kb_ == other.shmem_page_size_kb_
   && num_processes_ == other.num_processes_
   && num_threads_ == other.num_threads_
   && max_events_ == other.max_events_
   && nesting_ == other.nesting_
   && steady_state_timings_ == other.steady_state_timings_
   && burst_period_ms_ == other.burst_period_ms_
   && burst_duration_ms_ == other.burst_duration_ms_
   && 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 unknown_fields_ == other.unknown_fields_
   && payload_mean_ == other.payload_mean_
   && payload_stddev_ == other.payload_stddev_
   && rate_mean_ == other.rate_mean_
   && rate_stddev_ == other.rate_stddev_
   && 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 unknown_fields_ == other.unknown_fields_
   && message_count_ == other.message_count_
   && max_messages_per_second_ == other.max_messages_per_second_
   && seed_ == other.seed_
   && message_size_ == other.message_size_
   && send_batch_on_register_ == other.send_batch_on_register_
   && 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 unknown_fields_ == other.unknown_fields_
   && field_uint32_ == other.field_uint32_
   && field_int32_ == other.field_int32_
   && field_uint64_ == other.field_uint64_
   && field_int64_ == other.field_int64_
   && field_fixed64_ == other.field_fixed64_
   && field_sfixed64_ == other.field_sfixed64_
   && field_fixed32_ == other.field_fixed32_
   && field_sfixed32_ == other.field_sfixed32_
   && field_double_ == other.field_double_
   && field_float_ == other.field_float_
   && field_sint64_ == other.field_sint64_
   && field_sint32_ == other.field_sint32_
   && field_string_ == other.field_string_
   && 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/chrome/chrome_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_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_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_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 unknown_fields_ == other.unknown_fields_
   && buffers_ == other.buffers_
   && data_sources_ == other.data_sources_
   && builtin_data_sources_ == other.builtin_data_sources_
   && duration_ms_ == other.duration_ms_
   && prefer_suspend_clock_for_duration_ == other.prefer_suspend_clock_for_duration_
   && enable_extra_guardrails_ == other.enable_extra_guardrails_
   && lockdown_mode_ == other.lockdown_mode_
   && producers_ == other.producers_
   && statsd_metadata_ == other.statsd_metadata_
   && write_into_file_ == other.write_into_file_
   && output_path_ == other.output_path_
   && file_write_period_ms_ == other.file_write_period_ms_
   && max_file_size_bytes_ == other.max_file_size_bytes_
   && guardrail_overrides_ == other.guardrail_overrides_
   && deferred_start_ == other.deferred_start_
   && flush_period_ms_ == other.flush_period_ms_
   && flush_timeout_ms_ == other.flush_timeout_ms_
   && data_source_stop_timeout_ms_ == other.data_source_stop_timeout_ms_
   && notify_traceur_ == other.notify_traceur_
   && bugreport_score_ == other.bugreport_score_
   && trigger_config_ == other.trigger_config_
   && activate_triggers_ == other.activate_triggers_
   && incremental_state_config_ == other.incremental_state_config_
   && allow_user_build_tracing_ == other.allow_user_build_tracing_
   && unique_session_name_ == other.unique_session_name_
   && compression_type_ == other.compression_type_
   && compress_from_cli_ == other.compress_from_cli_
   && incident_report_config_ == other.incident_report_config_
   && statsd_logging_ == other.statsd_logging_
   && trace_uuid_msb_ == other.trace_uuid_msb_
   && trace_uuid_lsb_ == other.trace_uuid_lsb_
   && trace_filter_ == other.trace_filter_
   && android_report_config_ == other.android_report_config_
   && 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 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 37 /* compress_from_cli */:
        field.get(&compress_from_cli_);
        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 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 37: compress_from_cli
  if (_has_field_[37]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(37, compress_from_cli_, 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 unknown_fields_ == other.unknown_fields_
   && min_delay_ms_ == other.min_delay_ms_
   && 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 unknown_fields_ == other.unknown_fields_
   && reporter_service_package_ == other.reporter_service_package_
   && reporter_service_class_ == other.reporter_service_class_
   && skip_report_ == other.skip_report_
   && 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 unknown_fields_ == other.unknown_fields_
   && bytecode_ == other.bytecode_
   && bytecode_v2_ == other.bytecode_v2_
   && 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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && policy_ == other.policy_
   && regex_pattern_ == other.regex_pattern_
   && 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 unknown_fields_ == other.unknown_fields_
   && destination_package_ == other.destination_package_
   && destination_class_ == other.destination_class_
   && privacy_level_ == other.privacy_level_
   && skip_incidentd_ == other.skip_incidentd_
   && 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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && trigger_mode_ == other.trigger_mode_
   && use_clone_snapshot_if_available_ == other.use_clone_snapshot_if_available_
   && triggers_ == other.triggers_
   && 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 4 /* 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 4: use_clone_snapshot_if_available
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, 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 unknown_fields_ == other.unknown_fields_
   && name_ == other.name_
   && producer_name_regex_ == other.producer_name_regex_
   && stop_delay_ms_ == other.stop_delay_ms_
   && max_per_24_h_ == other.max_per_24_h_
   && 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 unknown_fields_ == other.unknown_fields_
   && max_upload_per_day_bytes_ == other.max_upload_per_day_bytes_
   && 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 unknown_fields_ == other.unknown_fields_
   && triggering_alert_id_ == other.triggering_alert_id_
   && triggering_config_uid_ == other.triggering_config_uid_
   && triggering_config_id_ == other.triggering_config_id_
   && 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 unknown_fields_ == other.unknown_fields_
   && producer_name_ == other.producer_name_
   && shm_size_kb_ == other.shm_size_kb_
   && 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 unknown_fields_ == other.unknown_fields_
   && disable_clock_snapshotting_ == other.disable_clock_snapshotting_
   && disable_trace_config_ == other.disable_trace_config_
   && disable_system_info_ == other.disable_system_info_
   && disable_service_events_ == other.disable_service_events_
   && primary_trace_clock_ == other.primary_trace_clock_
   && snapshot_interval_ms_ == other.snapshot_interval_ms_
   && prefer_suspend_clock_for_snapshot_ == other.prefer_suspend_clock_for_snapshot_
   && 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 unknown_fields_ == other.unknown_fields_
   && config_ == other.config_
   && producer_name_filter_ == other.producer_name_filter_
   && 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 unknown_fields_ == other.unknown_fields_
   && size_kb_ == other.size_kb_
   && fill_policy_ == other.fill_policy_;
}

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;
      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);
  }

  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/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/android_game_intervention_list.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/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/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/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/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 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 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 unknown_fields_ == other.unknown_fields_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && 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 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/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 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 unknown_fields_ == other.unknown_fields_
   && begin_main_frame_queue_critical_estimate_delta_us_ == other.begin_main_frame_queue_critical_estimate_delta_us_
   && begin_main_frame_queue_not_critical_estimate_delta_us_ == other.begin_main_frame_queue_not_critical_estimate_delta_us_
   && begin_main_frame_start_to_ready_to_commit_estimate_delta_us_ == other.begin_main_frame_start_to_ready_to_commit_estimate_delta_us_
   && commit_to_ready_to_activate_estimate_delta_us_ == other.commit_to_ready_to_activate_estimate_delta_us_
   && prepare_tiles_estimate_delta_us_ == other.prepare_tiles_estimate_delta_us_
   && activate_estimate_delta_us_ == other.activate_estimate_delta_us_
   && 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 unknown_fields_ == other.unknown_fields_
   && source_id_ == other.source_id_
   && paused_ == other.paused_
   && num_observers_ == other.num_observers_
   && 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 unknown_fields_ == other.unknown_fields_
   && type_ == other.type_
   && source_id_ == other.source_id_
   && sequence_number_ == other.sequence_number_
   && frame_time_us_ == other.frame_time_us_
   && deadline_us_ == other.deadline_us_
   && interval_delta_us_ == other.interval_delta_us_
   && on_critical_path_ == other.on_critical_path_
   && animate_only_ == other.animate_only_
   && source_location_iid_ == other.source_location_iid_
   && source_location_ == other.source_location_
   && 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 unknown_fields_ == other.unknown_fields_
   && dropped_begin_frame_args_ == other.dropped_begin_frame_args_
   && 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 unknown_fields_ == other.unknown_fields_
   && updated_at_us_ == other.updated_at_us_
   && finished_at_us_ == other.finished_at_us_
   && state_ == other.state_
   && current_args_ == other.current_args_
   && last_args_ == other.last_args_
   && 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 unknown_fields_ == other.unknown_fields_
   && interval_delta_ == other.interval_delta_
   && now_to_deadline_delta_ == other.now_to_deadline_delta_
   && frame_time_to_now_delta_ == other.frame_time_to_now_delta_
   && frame_time_to_deadline_delta_ == other.frame_time_to_deadline_delta_
   && now_ == other.now_
   && frame_time_ == other.frame_time_
   && 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 unknown_fields_ == other.unknown_fields_
   && major_state_ == other.major_state_
   && 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 unknown_fields_ == other.unknown_fields_
   && commit_count_ == other.commit_count_
   && current_frame_number_ == other.current_frame_number_
   && last_frame_number_submit_performed_ == other.last_frame_number_submit_performed_
   && last_frame_number_draw_performed_ == other.last_frame_number_draw_performed_
   && last_frame_number_begin_main_frame_sent_ == other.last_frame_number_begin_main_frame_sent_
   && did_draw_ == other.did_draw_
   && did_send_begin_main_frame_for_current_frame_ == other.did_send_begin_main_frame_for_current_frame_
   && did_notify_begin_main_frame_not_expected_until_ == other.did_notify_begin_main_frame_not_expected_until_
   && did_notify_begin_main_frame_not_expected_soon_ == other.did_notify_begin_main_frame_not_expected_soon_
   && wants_begin_main_frame_not_expected_ == other.wants_begin_main_frame_not_expected_
   && did_commit_during_frame_ == other.did_commit_during_frame_
   && did_invalidate_layer_tree_frame_sink_ == other.did_invalidate_layer_tree_frame_sink_
   && did_perform_impl_side_invalidaion_ == other.did_perform_impl_side_invalidaion_
   && did_prepare_tiles_ == other.did_prepare_tiles_
   && consecutive_checkerboard_animations_ == other.consecutive_checkerboard_animations_
   && pending_submit_frames_ == other.pending_submit_frames_
   && submit_frames_with_current_layer_tree_frame_sink_ == other.submit_frames_with_current_layer_tree_frame_sink_
   && needs_redraw_ == other.needs_redraw_
   && needs_prepare_tiles_ == other.needs_prepare_tiles_
   && needs_begin_main_frame_ == other.needs_begin_main_frame_
   && needs_one_begin_impl_frame_ == other.needs_one_begin_impl_frame_
   && visible_ == other.visible_
   && begin_frame_source_paused_ == other.begin_frame_source_paused_
   && can_draw_ == other.can_draw_
   && resourceless_draw_ == other.resourceless_draw_
   && has_pending_tree_ == other.has_pending_tree_
   && pending_tree_is_ready_for_activation_ == other.pending_tree_is_ready_for_activation_
   && active_tree_needs_first_draw_ == other.active_tree_needs_first_draw_
   && active_tree_is_ready_to_draw_ == other.active_tree_is_ready_to_draw_
   && did_create_and_initialize_first_layer_tree_frame_sink_ == other.did_create_and_initialize_first_layer_tree_frame_sink_
   && tree_priority_ == other.tree_priority_
   && scroll_handler_state_ == other.scroll_handler_state_
   && critical_begin_main_frame_to_activate_is_fast_ == other.critical_begin_main_frame_to_activate_is_fast_
   && main_thread_missed_last_deadline_ == other.main_thread_missed_last_deadline_
   && video_needs_begin_frames_ == other.video_needs_begin_frames_
   && defer_begin_main_frame_ == other.defer_begin_main_frame_
   && last_commit_had_no_updates_ == other.last_commit_had_no_updates_
   && did_draw_in_last_frame_ == other.did_draw_in_last_frame_
   && did_submit_in_last_frame_ == other.did_submit_in_last_frame_
   && needs_impl_side_invalidation_ == other.needs_impl_side_invalidation_
   && current_pending_tree_is_impl_side_ == other.current_pending_tree_is_impl_side_
   && previous_pending_tree_was_impl_side_ == other.previous_pending_tree_was_impl_side_
   && processing_animation_worklets_for_active_tree_ == other.processing_animation_worklets_for_active_tree_
   && processing_animation_worklets_for_pending_tree_ == other.processing_animation_worklets_for_pending_tree_
   && 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 unknown_fields_ == other.unknown_fields_
   && next_action_ == other.next_action_
   && begin_impl_frame_state_ == other.begin_impl_frame_state_
   && begin_main_frame_state_ == other.begin_main_frame_state_
   && layer_tree_frame_sink_state_ == other.layer_tree_frame_sink_state_
   && 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 unknown_fields_ == other.unknown_fields_
   && state_machine_ == other.state_machine_
   && observing_begin_frame_source_ == other.observing_begin_frame_source_
   && begin_impl_frame_deadline_task_ == other.begin_impl_frame_deadline_task_
   && pending_begin_frame_task_ == other.pending_begin_frame_task_
   && skipped_last_frame_missed_exceeded_deadline_ == other.skipped_last_frame_missed_exceeded_deadline_
   && inside_action_ == other.inside_action_
   && deadline_mode_ == other.deadline_mode_
   && deadline_us_ == other.deadline_us_
   && deadline_scheduled_at_us_ == other.deadline_scheduled_at_us_
   && now_us_ == other.now_us_
   && now_to_deadline_delta_us_ == other.now_to_deadline_delta_us_
   && now_to_deadline_scheduled_at_delta_us_ == other.now_to_deadline_scheduled_at_delta_us_
   && begin_impl_frame_args_ == other.begin_impl_frame_args_
   && begin_frame_observer_state_ == other.begin_frame_observer_state_
   && begin_frame_source_state_ == other.begin_frame_source_state_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && state_ == other.state_
   && reason_ == other.reason_
   && frame_source_ == other.frame_source_
   && frame_sequence_ == other.frame_sequence_
   && affects_smoothness_ == other.affects_smoothness_
   && scroll_state_ == other.scroll_state_
   && has_main_animation_ == other.has_main_animation_
   && has_compositor_animation_ == other.has_compositor_animation_
   && has_smooth_input_main_ == other.has_smooth_input_main_
   && has_missing_content_ == other.has_missing_content_
   && layer_tree_host_id_ == other.layer_tree_host_id_
   && has_high_latency_ == other.has_high_latency_
   && frame_type_ == other.frame_type_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && name_hash_ == other.name_hash_
   && name_ == other.name_
   && sample_ == other.sample_
   && 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 unknown_fields_ == other.unknown_fields_
   && iid_ == other.iid_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && trace_id_ == other.trace_id_
   && step_ == other.step_
   && frame_tree_node_id_ == other.frame_tree_node_id_
   && component_info_ == other.component_info_
   && is_coalesced_ == other.is_coalesced_
   && gesture_scroll_id_ == other.gesture_scroll_id_
   && 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 unknown_fields_ == other.unknown_fields_
   && component_type_ == other.component_type_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && message_class_ == other.message_class_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && sent_messages_in_queue_ == other.sent_messages_in_queue_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && watcher_notify_interface_tag_ == other.watcher_notify_interface_tag_
   && ipc_hash_ == other.ipc_hash_
   && mojo_interface_tag_ == other.mojo_interface_tag_
   && mojo_interface_method_iid_ == other.mojo_interface_method_iid_
   && is_reply_ == other.is_reply_
   && payload_size_ == other.payload_size_
   && 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 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,
};

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 ProcessType_MIN = ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED;
  static constexpr auto ProcessType_MAX = ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER_EXTENSION;
  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 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 unknown_fields_ == other.unknown_fields_
   && process_type_ == other.process_type_
   && process_priority_ == other.process_priority_
   && legacy_sort_index_ == other.legacy_sort_index_
   && host_app_package_name_ == other.host_app_package_name_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && rail_mode_ == other.rail_mode_
   && is_backgrounded_ == other.is_backgrounded_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && thread_type_ == other.thread_type_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && action_ == other.action_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && dpi_ == other.dpi_
   && message_id_ == other.message_id_
   && 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 unknown_fields_ == other.unknown_fields_
   && type_ == other.type_
   && categories_ == other.categories_
   && unit_ == other.unit_
   && unit_name_ == other.unit_name_
   && unit_multiplier_ == other.unit_multiplier_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && iid_ == other.iid_
   && 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 unknown_fields_ == other.unknown_fields_
   && iid_ == other.iid_
   && 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 unknown_fields_ == other.unknown_fields_
   && name_iid_ == other.name_iid_
   && name_ == other.name_
   && bool_value_ == other.bool_value_
   && uint_value_ == other.uint_value_
   && int_value_ == other.int_value_
   && double_value_ == other.double_value_
   && pointer_value_ == other.pointer_value_
   && nested_value_ == other.nested_value_
   && legacy_json_value_ == other.legacy_json_value_
   && string_value_ == other.string_value_
   && string_value_iid_ == other.string_value_iid_
   && proto_type_name_ == other.proto_type_name_
   && proto_type_name_iid_ == other.proto_type_name_iid_
   && proto_value_ == other.proto_value_
   && dict_entries_ == other.dict_entries_
   && 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 unknown_fields_ == other.unknown_fields_
   && nested_type_ == other.nested_type_
   && dict_keys_ == other.dict_keys_
   && dict_values_ == other.dict_values_
   && array_values_ == other.array_values_
   && int_value_ == other.int_value_
   && double_value_ == other.double_value_
   && bool_value_ == other.bool_value_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && iid_ == other.iid_
   && 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 unknown_fields_ == other.unknown_fields_
   && source_location_iid_ == other.source_location_iid_
   && body_iid_ == other.body_iid_
   && 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/process_descriptor.gen.cc
// 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 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 unknown_fields_ == other.unknown_fields_
   && pid_ == other.pid_
   && cmdline_ == other.cmdline_
   && process_name_ == other.process_name_
   && process_priority_ == other.process_priority_
   && start_timestamp_ns_ == other.start_timestamp_ns_
   && chrome_process_type_ == other.chrome_process_type_
   && legacy_sort_index_ == other.legacy_sort_index_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && 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/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 unknown_fields_ == other.unknown_fields_
   && iid_ == other.iid_
   && file_name_ == other.file_name_
   && function_name_ == other.function_name_
   && 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 unknown_fields_ == other.unknown_fields_
   && iid_ == other.iid_
   && mapping_id_ == other.mapping_id_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && pid_ == other.pid_
   && tid_ == other.tid_
   && thread_name_ == other.thread_name_
   && chrome_thread_type_ == other.chrome_thread_type_
   && reference_timestamp_us_ == other.reference_timestamp_us_
   && reference_thread_time_us_ == other.reference_thread_time_us_
   && reference_thread_instruction_count_ == other.reference_thread_instruction_count_
   && 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 unknown_fields_ == other.unknown_fields_
   && uuid_ == other.uuid_
   && parent_uuid_ == other.parent_uuid_
   && name_ == other.name_
   && process_ == other.process_
   && chrome_process_ == other.chrome_process_
   && thread_ == other.thread_
   && chrome_thread_ == other.chrome_thread_
   && counter_ == other.counter_
   && 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 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 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,
    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_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<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<50> _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 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/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 unknown_fields_ == other.unknown_fields_
   && iid_ == other.iid_
   && 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 unknown_fields_ == other.unknown_fields_
   && iid_ == other.iid_
   && 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 unknown_fields_ == other.unknown_fields_
   && track_uuid_ == other.track_uuid_
   && extra_counter_track_uuids_ == other.extra_counter_track_uuids_
   && 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 unknown_fields_ == other.unknown_fields_
   && category_iids_ == other.category_iids_
   && categories_ == other.categories_
   && name_iid_ == other.name_iid_
   && name_ == other.name_
   && type_ == other.type_
   && track_uuid_ == other.track_uuid_
   && counter_value_ == other.counter_value_
   && double_counter_value_ == other.double_counter_value_
   && extra_counter_track_uuids_ == other.extra_counter_track_uuids_
   && extra_counter_values_ == other.extra_counter_values_
   && extra_double_counter_track_uuids_ == other.extra_double_counter_track_uuids_
   && extra_double_counter_values_ == other.extra_double_counter_values_
   && flow_ids_old_ == other.flow_ids_old_
   && flow_ids_ == other.flow_ids_
   && terminating_flow_ids_old_ == other.terminating_flow_ids_old_
   && terminating_flow_ids_ == other.terminating_flow_ids_
   && debug_annotations_ == other.debug_annotations_
   && task_execution_ == other.task_execution_
   && log_message_ == other.log_message_
   && cc_scheduler_state_ == other.cc_scheduler_state_
   && chrome_user_event_ == other.chrome_user_event_
   && chrome_keyed_service_ == other.chrome_keyed_service_
   && chrome_legacy_ipc_ == other.chrome_legacy_ipc_
   && chrome_histogram_sample_ == other.chrome_histogram_sample_
   && chrome_latency_info_ == other.chrome_latency_info_
   && chrome_frame_reporter_ == other.chrome_frame_reporter_
   && chrome_application_state_info_ == other.chrome_application_state_info_
   && chrome_renderer_scheduler_state_ == other.chrome_renderer_scheduler_state_
   && chrome_window_handle_event_info_ == other.chrome_window_handle_event_info_
   && chrome_content_settings_event_info_ == other.chrome_content_settings_event_info_
   && chrome_active_processes_ == other.chrome_active_processes_
   && source_location_ == other.source_location_
   && source_location_iid_ == other.source_location_iid_
   && chrome_message_pump_ == other.chrome_message_pump_
   && chrome_mojo_event_info_ == other.chrome_mojo_event_info_
   && timestamp_delta_us_ == other.timestamp_delta_us_
   && timestamp_absolute_us_ == other.timestamp_absolute_us_
   && thread_time_delta_us_ == other.thread_time_delta_us_
   && thread_time_absolute_us_ == other.thread_time_absolute_us_
   && thread_instruction_count_delta_ == other.thread_instruction_count_delta_
   && thread_instruction_count_absolute_ == other.thread_instruction_count_absolute_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && name_iid_ == other.name_iid_
   && phase_ == other.phase_
   && duration_us_ == other.duration_us_
   && thread_duration_us_ == other.thread_duration_us_
   && thread_instruction_delta_ == other.thread_instruction_delta_
   && unscoped_id_ == other.unscoped_id_
   && local_id_ == other.local_id_
   && global_id_ == other.global_id_
   && id_scope_ == other.id_scope_
   && use_async_tts_ == other.use_async_tts_
   && bind_id_ == other.bind_id_
   && bind_to_enclosing_ == other.bind_to_enclosing_
   && flow_direction_ == other.flow_direction_
   && instant_event_scope_ == other.instant_event_scope_
   && pid_override_ == other.pid_override_
   && 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_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_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/surfaceflinger_layers_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/data_source_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/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/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/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/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/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/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/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 <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()); }
  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/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 uid_t kInvalidUid = ::perfetto::base::kInvalidUid;

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);

}  // 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 in the Chunk is prefixed by a 4 bytes redundant VarInt
  // (see proto_utils.h) stating its size.
  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)            |
  //        +------------------------+
  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};

  // 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;
    }

    // Increases |packets.count| to the given |packet_count|, but only if
    // |packet_count| is larger than the current value of |packets.count|.
    // Returns the new packet count. Same atomicity guarantees as
    // IncrementPacketCount().
    uint16_t IncreasePacketCountTo(uint16_t packet_count) {
      ChunkHeader* chunk_header = header();
      auto packets = chunk_header->packets.load(std::memory_order_relaxed);
      if (packets.count < packet_count)
        packets.count = packet_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;
  };

  // Construct an instance from an existing shared memory buffer.
  SharedMemoryABI(uint8_t* start, size_t size, size_t page_size);
  SharedMemoryABI();

  void Initialize(uint8_t* start, size_t size, size_t page_size);

  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);

  // 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;
  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) {
  Initialize(start, size, page_size);
}

void SharedMemoryABI::Initialize(uint8_t* start,
                                 size_t size,
                                 size_t page_size) {
  start_ = start;
  size_ = size;
  page_size_ = page_size;
  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 =
        ((layout >> (chunk_idx * kChunkShift)) & kChunkMask);

    // 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).
    ChunkState expected_chunk_state;
    if (desired_chunk_state == kChunkComplete) {
      expected_chunk_state = kChunkBeingWritten;
    } else {
      expected_chunk_state = 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/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_
// 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 <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();

 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_).
  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/forward_decls.h"

namespace perfetto {

namespace base {
class TaskRunner;
}  // namespace base

class Consumer;
class Producer;
class SharedMemoryArbiter;
class TraceWriter;

// 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).
  // TODO(primiano): make pure virtual after various 3way patches.
  virtual void CloneSession(TracingSessionID);

  // 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) = 0;

  // 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.
  using QueryServiceStateCallback =
      std::function<void(bool success, const TracingServiceState&)>;
  virtual void QueryServiceState(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;
};

// 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 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*,
      uid_t uid,
      pid_t pid,
      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;
};

}  // 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/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:
  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,
      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);
};

}  // 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*,
                          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,
                                     size_t size_hint = 0);

  // 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;

  // --- 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::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(); }
  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;

  // 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;

  // Points to the size field of the last packet we wrote to the current chunk.
  // If the chunk was already returned, this is reset to |nullptr|.
  uint8_t* last_packet_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 "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,
    TracingService::ProducerEndpoint* producer_endpoint,
    base::TaskRunner* task_runner) {
  return std::unique_ptr<SharedMemoryArbiterImpl>(
      new SharedMemoryArbiterImpl(shared_memory->start(), shared_memory->size(),
                                  page_size, producer_endpoint, task_runner));
}

// static
std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateUnboundInstance(
    SharedMemory* shared_memory,
    size_t page_size) {
  return std::unique_ptr<SharedMemoryArbiterImpl>(new SharedMemoryArbiterImpl(
      shared_memory->start(), shared_memory->size(), page_size,
      /*producer_endpoint=*/nullptr, /*task_runner=*/nullptr));
}

SharedMemoryArbiterImpl::SharedMemoryArbiterImpl(
    void* start,
    size_t size,
    size_t page_size,
    TracingService::ProducerEndpoint* producer_endpoint,
    base::TaskRunner* task_runner)
    : producer_endpoint_(producer_endpoint),
      task_runner_(task_runner),
      shmem_abi_(reinterpret_cast<uint8_t*>(start), size, page_size),
      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,
    size_t size_hint) {
  PERFETTO_DCHECK(size_hint == 0);  // Not implemented yet.

  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;
      }
    }

    // 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;
      // 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.
      CommitDataRequest::ChunksToMove* ctm =
          commit_data_req_->add_chunks_to_move();
      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_->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)
          continue;

        SharedMemoryABI::Chunk chunk =
            shmem_abi_.GetChunkUnchecked(ctm.page(), layout, ctm.chunk());
        shmem_abi_.ReleaseChunkAsComplete(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;
  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;
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::Flush(std::function<void()> callback) {
  // Flush() cannot be called in the middle of a TracePacket.
  PERFETTO_CHECK(cur_packet_->is_finalized());

  if (cur_chunk_.is_valid()) {
    shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_), target_buffer_,
                                         &patch_list_);
  } 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});

  // |last_packet_size_field_| might have pointed into the chunk we returned.
  last_packet_size_field_ = 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());

  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_packet_->set_size_field(header);
  last_packet_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 = cur_chunk_.IncrementPacketCount();
    reached_max_packets_per_chunk_ =
        new_packet_count == ChunkHeader::Packets::kMaxCount;

    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;
  }

  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;
    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_packet_->size_field());

      // Reset the size field, since we should not write the current packet's
      // size anymore after this.
      cur_packet_->set_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_ && last_packet_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());

      // |last_packet_size_field_| should point within |cur_chunk_|'s payload.
      PERFETTO_DCHECK(last_packet_size_field_ >= cur_chunk_.payload_begin() &&
                      last_packet_size_field_ + kMessageLengthFieldSize <=
                          cur_chunk_.end());

      WriteRedundantVarInt(SharedMemoryABI::kPacketSizeDropPacket,
                           last_packet_size_field_);
    }

    if (cur_chunk_.is_valid()) {
      shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_),
                                           target_buffer_, &patch_list_);
    }

    drop_packets_ = true;
    cur_chunk_ = SharedMemoryABI::Chunk();  // Reset to an invalid chunk.
    reached_max_packets_per_chunk_ = false;
    retry_new_chunk_after_packet_ = false;
    last_packet_size_field_ = nullptr;

    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_packet_->inc_size_already_written(partial_size);
    cur_chunk_.SetFlag(ChunkHeader::kLastPacketContinuesOnNextChunk);
    WriteRedundantVarInt(partial_size, cur_packet_->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.
    shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_), target_buffer_,
                                         &patch_list_);
  }

  // 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);
  last_packet_size_field_ = nullptr;

  uint8_t* payload_begin = cur_chunk_.payload_begin();
  if (fragmenting_packet_) {
    cur_packet_->set_size_field(payload_begin);
    last_packet_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());

  // If the caller uses TakeStreamWriter(), cur_packet_->size() is not up to
  // date, only the stream writer knows the exact size.
  // cur_packet_->size_field() is still used to store the start of the fragment.
  if (cur_packet_->size_field()) {
    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_);

    WriteRedundantVarInt(partial_size, last_packet_size_field_);
  }

  cur_packet_->Reset(&protobuf_stream_writer_);
  cur_packet_->Finalize();  // To avoid the CHECK in NewTracePacket().

  // 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_);
  }
}

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];
}

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/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) = 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"

// 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;
SharedMemory::~SharedMemory() = default;
SharedMemory::Factory::~Factory() = default;
SharedMemoryArbiter::~SharedMemoryArbiter() = default;

// TODO(primiano): make pure virtual after various 3way patches.
void ConsumerEndpoint::CloneSession(TracingSessionID) {}
void Consumer::OnSessionCloned(const OnSessionClonedArgs&) {}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/console_interceptor.cc
// 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 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,
      ::perfetto::protos::pbzero::ConsoleConfig_Output,
      ConsoleConfig>;

  static constexpr FieldMetadata_Output kOutput{};
  void set_output(::perfetto::protos::pbzero::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/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 TracePacketDefaults_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/58, /*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(); }
};

class TracePacketDefaults : public ::protozero::Message {
 public:
  using Decoder = TracePacketDefaults_Decoder;
  enum : int32_t {
    kTimestampClockIdFieldNumber = 58,
    kTrackEventDefaultsFieldNumber = 11,
    kPerfSampleDefaultsFieldNumber = 12,
  };
  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);
  }

};

} // 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 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,
      ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType,
      ProcessDescriptor>;

  static constexpr FieldMetadata_ChromeProcessType kChromeProcessType{};
  void set_chrome_process_type(::perfetto::protos::pbzero::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/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 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,
      ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType,
      ThreadDescriptor>;

  static constexpr FieldMetadata_ChromeThreadType kChromeThreadType{};
  void set_chrome_thread_type(::perfetto::protos::pbzero::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.
/*
 * 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.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/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
  protos::pbzero::ConsoleConfig::Decoder config(
      args.config.interceptor_config().console_config_raw());
  if (config.has_enable_colors())
    use_colors = config.enable_colors();
  if (config.output() == protos::pbzero::ConsoleConfig::OUTPUT_STDOUT) {
    fd = STDOUT_FILENO;
  } else if (config.output() == protos::pbzero::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(
    EventContext::TracePacketHandle trace_packet,
    internal::TrackEventIncrementalState* incremental_state,
    const internal::TrackEventTlsState* tls_state)
    : 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_LIKELY(serialized_interned_data.empty()))
    return;

  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;
}

}  // 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) 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(QueryServiceStateCallback) override {}
  void QueryCapabilities(QueryCapabilitiesCallback) override {}

  void SaveTraceForBugreport(SaveTraceForBugreportCallback) override {}
  void CloneSession(TracingSessionID) 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,
                          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,
                                          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;
    DataSourceStaticState* static_state = nullptr;
  };

  static void InitializeInstance(const TracingInitArgs&);
  static void ResetForTesting();
  static void Shutdown();

  // TracingMuxer implementation.
  bool RegisterDataSource(const DataSourceDescriptor&,
                          DataSourceFactory,
                          DataSourceParams,
                          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);
    ~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) 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;

    // 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);
  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)
    : muxer_(muxer),
      backend_id_(backend_id),
      shmem_batch_commits_duration_ms_(shmem_batch_commits_duration_ms) {}

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_);
}

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) {
  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);
      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));
  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->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,
    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] {
    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;

    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->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);
    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();
    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_) {
    // 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) {
  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.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 (producer->connected_) {
    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;

    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;
  }

  consumer->service_->Flush(timeout_ms, std::move(callback));
}

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
// 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;

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/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 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,
      ::perfetto::protos::pbzero::BuiltinClock,
      ClockSnapshot>;

  static constexpr FieldMetadata_PrimaryTraceClock kPrimaryTraceClock{};
  void set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value) {
    static constexpr uint32_t field_id = FieldMetadata_PrimaryTraceClock::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kEnum>
        ::Append(*this, field_id, value);
  }
};

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.
/*
 * 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&) {}

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";

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_LIKELY(!tls_state.filter_dynamic_event_names)) {
    event_ctx.event()->set_name(event_name.value, event_name.length);
  }
}

// static
EventContext TrackEventInternal::WriteEvent(
    TraceWriterBase* trace_writer,
    TrackEventIncrementalState* incr_state,
    const 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(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::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
// 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/tracing/tracing.h"

#include <atomic>
#include <condition_variable>
#include <mutex>

// 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) {
  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();

  // 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());
    Track::process_uuid = hash.digest();
  } else {
    // Fall back to a randomly generated identifier.
    Track::process_uuid = static_cast<uint64_t>(base::Uuidv4().lsb());
  }
}

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,
  kCmdFailedToInitGuardrailState = 44,
  kCmdInvalidGuardrailState = 45,
  kCmdHitUploadLimit = 46,

  // 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,

  // 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;
};

// 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 is safe to pass around.
const char* GetVersionString();

}  // 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() "v36.1-41c5036fc"
#define PERFETTO_VERSION_SCM_REVISION() "41c5036fccb2fd51e244ba30cb650f1f84cc0726"

#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() "v0.0"
#define PERFETTO_VERSION_SCM_REVISION() "unknown"
#endif

namespace perfetto {
namespace base {

const char* GetVersionString() {
  static const char* version_str = [] {
    static constexpr size_t kMaxLen = 256;
    char* version = new char[kMaxLen + 1];
    snprintf(version, kMaxLen, "Perfetto %s (%s)", PERFETTO_VERSION_STRING(),
             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);

  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) {
  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>

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,
  };

  StringFilter() = default;

  // 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) {
    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;
  };

  StringFilter(StringFilter&&) noexcept = delete;
  StringFilter& operator=(StringFilter&&) noexcept = delete;

  bool MaybeFilterInternal(char* ptr, size_t len);

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

  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) {
  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;
    }
  }
  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:
  MessageFilter();
  explicit MessageFilter(const MessageFilter&);
  ~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);

  // 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(const uint32_t* field_ids, size_t num_fields);

  // 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_;
  }

  // Exposed only for DCHECKS in TracingServiceImpl.
  uint32_t root_msg_index() { return root_msg_index_; }

  // Retuns the helper class used to perform string filtering.
  StringFilter& string_filter() { return 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]); }

  std::unique_ptr<uint8_t[]> out_buf_;
  uint8_t* out_ = nullptr;
  uint8_t* out_end_ = nullptr;
  uint32_t root_msg_index_ = 0;

  FilterBytecodeParser filter_;
  MessageTokenizer tokenizer_;
  StringFilter string_filter_;
  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() {
  // Push a state on the stack for the implicit root message.
  stack_.emplace_back();
}

MessageFilter::MessageFilter(const MessageFilter& other)
    : root_msg_index_(other.root_msg_index_), filter_(other.filter_) {
  stack_.emplace_back();
}

MessageFilter::~MessageFilter() = default;

bool MessageFilter::LoadFilterBytecode(const void* filter_data, size_t len) {
  return filter_.Load(filter_data, len);
}

bool MessageFilter::SetFilterRoot(const uint32_t* field_ids,
                                  size_t num_fields) {
  uint32_t root_msg_idx = 0;
  for (const uint32_t* it = field_ids; it < field_ids + num_fields; ++it) {
    uint32_t field_id = *it;
    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 = 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) {
        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 = 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/core/metatrace_writer.cc
// gen_amalgamated begin header: src/tracing/core/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_CORE_METATRACE_WRITER_H_
#define SRC_TRACING_CORE_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_CORE_METATRACE_WRITER_H_
// 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;

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.
/*
 * 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/core/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/core/packet_stream_validator.cc
// gen_amalgamated begin header: src/tracing/core/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_CORE_PACKET_STREAM_VALIDATOR_H_
#define SRC_TRACING_CORE_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_CORE_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/core/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,
};

// 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/core/trace_buffer.cc
// gen_amalgamated begin header: src/tracing/core/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 <functional>
#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

// 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: src/tracing/core/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_CORE_HISTOGRAM_H_
#define SRC_TRACING_CORE_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_CORE_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_CORE_TRACE_BUFFER_H_
#define SRC_TRACING_CORE_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/slice.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
// gen_amalgamated expanded: #include "src/tracing/core/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;
    uid_t producer_uid_trusted;
    pid_t producer_pid_trusted;
    WriterID writer_id;
  };

  // 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,
                          uid_t producer_uid_trusted,
                          pid_t producer_pid_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;

  const WriterStatsMap& writer_stats() const { return writer_stats_; }
  const TraceStats::BufferStats& stats() const { return stats_; }
  size_t size() const { return size_; }

 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.
    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,
              uid_t _trusted_uid,
              pid_t _trusted_pid)
        : record_off{_record_off},
          trusted_uid{_trusted_uid},
          trusted_pid(_trusted_pid),
          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 uid_t trusted_uid;    // uid of the producer.
    const pid_t trusted_pid;    // pid of the producer.

    // 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.
    data_.EnsureCommitted(
        static_cast<size_t>(ptr + sizeof(ChunkRecord) - begin()));
    return reinterpret_cast<ChunkRecord*>(ptr);
  }

  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));
    PERFETTO_CHECK(record.size <= size_to_end());
    DcheckIsAlignedAndWithinBounds(wptr);

    // We may be writing to this area for the first time.
    data_.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_|.
  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_;

#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_CORE_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/core/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/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;
  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,
                                     uid_t producer_uid_trusted,
                                     pid_t producer_pid_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;
  }

#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;
  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,
                     producer_uid_trusted, producer_pid_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;
  }
  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, kInvalidUid, base::kInvalidPid, 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 uid_t trusted_uid = chunk_meta->trusted_uid;
    const pid_t trusted_pid = chunk_meta->trusted_pid;

    // 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, trusted_uid, trusted_pid,
                                  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, trusted_uid, trusted_pid,
                                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().

  data_.EnsureCommitted(data_.size());
  memcpy(data_.Get(), src.data_.Get(), src.data_.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/core/tracing_service_impl.cc
// gen_amalgamated begin header: src/tracing/core/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_CORE_TRACING_SERVICE_IMPL_H_
#define SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_

#include <algorithm>
#include <functional>
#include <map>
#include <memory>
#include <mutex>
#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/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,
                         uid_t uid,
                         pid_t pid,
                         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>&);
    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 uid_; }
    pid_t pid() const { return pid_; }

   private:
    friend class TracingServiceImpl;
    friend class TracingServiceImplTest;
    friend class TracingIntegrationTest;
    ProducerEndpointImpl(const ProducerEndpointImpl&) = delete;
    ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete;

    ProducerID const id_;
    const uid_t uid_;
    const pid_t pid_;
    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) 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(QueryServiceStateCallback) override;
    void QueryCapabilities(QueryCapabilitiesCallback) override;
    void SaveTraceForBugreport(SaveTraceForBugreportCallback) override;
    void CloneSession(TracingSessionID) 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.
  };

  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,
                                     uid_t,
                                     pid_t,
                                     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, const DataSourceInstanceID);
  void NotifyDataSourceStopped(ProducerID, const 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);
  void FlushAndDisableTracing(TracingSessionID);
  void FlushAndCloneSession(ConsumerEndpointImpl*, TracingSessionID);

  // 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*,
      uid_t uid,
      pid_t pid,
      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;

  // 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)
        : 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) {}
    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;

    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)) {}
  };

  // 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(ProducerID producer_id,
                                         WriterID writer_id) {
      auto key = std::make_pair(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;
          });
    }

    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.
    // TODO(rsavitski): at the time of writing, the map structure is unused
    // (even when the calling code has a key). This is also an opportunity to
    // consider an alternative data type, e.g. a map of vectors.
    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;

    // 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::pair<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 mirrored the trace config back to the trace output yet.
    bool did_emit_config = false;

    // Whether we put the system info into the trace output yet.
    bool did_emit_system_info = 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 =
        std::vector<std::pair<uint32_t /*clock_id*/, uint64_t /*ts*/>>;

    // 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;

    // 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;

  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 MaybeEmitUuidAndTraceConfig(TracingSession*, std::vector<TracePacket>*);
  void MaybeEmitSystemInfo(TracingSession*, std::vector<TracePacket>*);
  void MaybeEmitReceivedTriggers(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);
  base::Status DoCloneSession(ConsumerEndpointImpl*,
                              TracingSessionID,
                              bool final_flush_outcome,
                              base::Uuid*);

  // 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<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_CORE_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_
// 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 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,
      ::perfetto::protos::pbzero::TraceStats_FinalFlushOutcome,
      TraceStats>;

  static constexpr FieldMetadata_FinalFlushOutcome kFinalFlushOutcome{};
  void set_final_flush_outcome(::perfetto::protos::pbzero::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=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
 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(); }
};

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,
  };
  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);
  }
};

class TraceStats_WriterStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*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_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,
    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_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/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 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,
};
} // 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_MATCH_BREAK;


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";
  }
  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 = 3,
};
} // 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=*/37, /*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_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_compress_from_cli() const { return at<37>().valid(); }
  bool compress_from_cli() const { return at<37>().as_bool(); }
  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,
    kTriggerConfigFieldNumber = 17,
    kActivateTriggersFieldNumber = 18,
    kIncrementalStateConfigFieldNumber = 21,
    kAllowUserBuildTracingFieldNumber = 19,
    kUniqueSessionNameFieldNumber = 22,
    kCompressionTypeFieldNumber = 24,
    kCompressFromCliFieldNumber = 37,
    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,
      ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation,
      TraceConfig>;

  static constexpr FieldMetadata_LockdownMode kLockdownMode{};
  void set_lockdown_mode(::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation value) {
    static constexpr uint32_t field_id = FieldMetadata_LockdownMode::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kEnum>
        ::Append(*this, field_id, value);
  }

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

  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_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,
      ::perfetto::protos::pbzero::TraceConfig_CompressionType,
      TraceConfig>;

  static constexpr FieldMetadata_CompressionType kCompressionType{};
  void set_compression_type(::perfetto::protos::pbzero::TraceConfig_CompressionType value) {
    static constexpr uint32_t field_id = FieldMetadata_CompressionType::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kEnum>
        ::Append(*this, field_id, value);
  }

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

  static constexpr FieldMetadata_CompressFromCli kCompressFromCli{};
  void set_compress_from_cli(bool value) {
    static constexpr uint32_t field_id = FieldMetadata_CompressFromCli::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_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,
      ::perfetto::protos::pbzero::TraceConfig_StatsdLogging,
      TraceConfig>;

  static constexpr FieldMetadata_StatsdLogging kStatsdLogging{};
  void set_statsd_logging(::perfetto::protos::pbzero::TraceConfig_StatsdLogging value) {
    static constexpr uint32_t field_id = FieldMetadata_StatsdLogging::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kEnum>
        ::Append(*this, field_id, value);
  }

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

  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;

  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,
      ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy,
      TraceConfig_TraceFilter_StringFilterRule>;

  static constexpr FieldMetadata_Policy kPolicy{};
  void set_policy(::perfetto::protos::pbzero::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=*/4, /*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<4>().valid(); }
  bool use_clone_snapshot_if_available() const { return at<4>().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 = 4,
    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,
      ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode,
      TraceConfig_TriggerConfig>;

  static constexpr FieldMetadata_TriggerMode kTriggerMode{};
  void set_trigger_mode(::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode value) {
    static constexpr uint32_t field_id = FieldMetadata_TriggerMode::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kEnum>
        ::Append(*this, field_id, value);
  }

  using FieldMetadata_UseCloneSnapshotIfAvailable =
    ::protozero::proto_utils::FieldMetadata<
      4,
      ::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,
      ::perfetto::protos::pbzero::BuiltinClock,
      TraceConfig_BuiltinDataSource>;

  static constexpr FieldMetadata_PrimaryTraceClock kPrimaryTraceClock{};
  void set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value) {
    static constexpr uint32_t field_id = FieldMetadata_PrimaryTraceClock::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kEnum>
        ::Append(*this, field_id, value);
  }

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

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

class TraceConfig_BufferConfig : public ::protozero::Message {
 public:
  using Decoder = TraceConfig_BufferConfig_Decoder;
  enum : int32_t {
    kSizeKbFieldNumber = 1,
    kFillPolicyFieldNumber = 4,
  };
  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,
      ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy,
      TraceConfig_BufferConfig>;

  static constexpr FieldMetadata_FillPolicy kFillPolicy{};
  void set_fill_policy(::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy value) {
    static constexpr uint32_t field_id = FieldMetadata_FillPolicy::kFieldId;
    // Call the appropriate protozero::Message::Append(field_id, ...)
    // method based on the type of the field.
    ::protozero::internal::FieldWriter<
      ::protozero::proto_utils::ProtoSchemaType::kEnum>
        ::Append(*this, field_id, value);
  }
};

} // Namespace.
} // Namespace.
} // Namespace.
#endif  // Include guard.
// 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/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;

class SystemInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*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_hz() const { return at<3>().valid(); }
  int64_t hz() const { return at<3>().as_int64(); }
  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(); }
};

class SystemInfo : public ::protozero::Message {
 public:
  using Decoder = SystemInfo_Decoder;
  enum : int32_t {
    kUtsnameFieldNumber = 1,
    kAndroidBuildFingerprintFieldNumber = 2,
    kHzFieldNumber = 3,
    kTracingServiceVersionFieldNumber = 4,
    kAndroidSdkVersionFieldNumber = 5,
    kPageSizeFieldNumber = 6,
  };
  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_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);
  }

  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);
  }
};

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/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.
/*
 * 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/tracing_service_impl.h"

#include <errno.h>
#include <limits.h>
#include <string.h>

#include <cinttypes>
#include <optional>
#include <regex>
#include <unordered_set>
// gen_amalgamated expanded: #include "perfetto/base/time.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/temp_file.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/packet_stream_validator.h"
// gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
// gen_amalgamated expanded: #include "src/tracing/core/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/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]
static 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;
  }
  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,
                                    uid_t uid,
                                    pid_t pid,
                                    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_);

  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, uid, pid, 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;
}

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.");
  }

  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.
    uint32_t packet_field_id = TracePacket::kPacketFieldNumber;
    if (!trace_filter->SetFilterRoot(&packet_field_id, 1)) {
      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.compress_from_cli() &&
      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 (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;

    // 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;
      }

      bool already_setup = false;
      auto& ds_instances = tracing_session->data_source_instances;
      for (auto instance_it = ds_instances.begin();
           instance_it != ds_instances.end(); ++instance_it) {
        if (instance_it->first == it->second.producer_id &&
            instance_it->second.data_source_name ==
                cfg_data_source.config().name()) {
          already_setup = true;
          break;
        }
      }

      if (already_setup)
        continue;

      // If it wasn't previously setup, set it up now.
      // (The per-producer config is optional).
      TraceConfig::ProducerConfig producer_config;
      for (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& kv : tracing_session->data_source_instances) {
    ProducerID producer_id = kv.first;
    DataSourceInstance& data_source = kv.second;
    ProducerEndpointImpl* producer = GetProducer(producer_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) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  TracingSession* tracing_session = GetTracingSession(tsid);
  if (!tracing_session) {
    PERFETTO_DLOG("Flush() failed, invalid session ID %" PRIu64, tsid);
    return;
  }

  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_ELOG("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.
  std::map<ProducerID, std::vector<DataSourceInstanceID>> flush_map;
  for (const auto& data_source_inst : tracing_session->data_source_instances) {
    const ProducerID producer_id = data_source_inst.first;
    const DataSourceInstanceID ds_inst_id = data_source_inst.second.instance_id;
    flush_map[producer_id].push_back(ds_inst_id);
  }

  for (const auto& kv : flush_map) {
    ProducerID producer_id = kv.first;
    ProducerEndpointImpl* producer = GetProducer(producer_id);
    const std::vector<DataSourceInstanceID>& data_sources = kv.second;
    producer->Flush(flush_request_id, data_sources);
    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 (flush_map.empty())
    timeout_ms = 0;

  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostDelayedTask(
      [weak_this, tsid, 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->uid_, producer->pid_, 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);
    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);
    }
  });
}

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");
  });
}

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;
  }
  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()) {
    MaybeEmitUuidAndTraceConfig(tracing_session, &packets);
    MaybeEmitReceivedTriggers(tracing_session, &packets);
  }
  if (!tracing_session->config.builtin_data_sources().disable_system_info())
    MaybeEmitSystemInfo(tracing_session, &packets);

  // 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);

  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;
      }
      PERFETTO_DCHECK(sequence_properties.producer_id_trusted != 0);
      PERFETTO_DCHECK(sequence_properties.writer_id != 0);
      PERFETTO_DCHECK(sequence_properties.producer_uid_trusted != kInvalidUid);
      // Not checking sequence_properties.producer_pid_trusted: it is
      // base::kInvalidPid 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);
      trusted_packet->set_trusted_uid(
          static_cast<int32_t>(sequence_properties.producer_uid_trusted));
      trusted_packet->set_trusted_packet_sequence_id(
          tracing_session->GetPacketSequenceID(
              sequence_properties.producer_id_trusted,
              sequence_properties.writer_id));
      if (sequence_properties.producer_pid_trusted != base::kInvalidPid) {
        // Not supported on all platforms.
        trusted_packet->set_trusted_pid(
            static_cast<int32_t>(sequence_properties.producer_pid_trusted));
      }
      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 shoud be reset from protos.Trace to protos.TracePacket
  // by the earlier call to SetFilterRoot() in EnableTracing().
  PERFETTO_DCHECK(trace_filter.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();
    filter_input.clear();
    filter_input.resize(packet_slices.size());
    ++tracing_session->filter_input_packets;
    tracing_session->filter_input_bytes += 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).
    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;
    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 (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);
}

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()));
  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 (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
    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,
    uid_t producer_uid_trusted,
    pid_t producer_pid_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, producer_uid_trusted,
                          producer_pid_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();
  }

  // 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;

#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) {
    new_snapshot_data.push_back(std::make_pair(
        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.
  new_snapshot_data.push_back(
      std::make_pair(protos::pbzero::BUILTIN_CLOCK_BOOTTIME, wall_time_ns));
  new_snapshot_data.push_back(
      std::make_pair(protos::pbzero::BUILTIN_CLOCK_MONOTONIC, wall_time_ns));
#endif

  // 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].first ==
                    protos::gen::BUILTIN_CLOCK_BOOTTIME);

    bool update_snapshot = false;
    uint64_t old_boot_ns = (*snapshot_data)[0].second;
    uint64_t new_boot_ns = new_snapshot_data[0].second;
    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].second;
      uint64_t new_ns = new_snapshot_data[i].second;

      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.first);
    c->set_timestamp(clock_id_and_ts.second);
  }

  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 (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. However, we want to report only
    // one histogram per writer. 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). Per-buffer breakdowns would be completely useless.
    TraceBuffer::WriterStatsMap merged_stats;

    // First merge all the per-buffer histograms into one-per-writer.
    for (const BufferID buf_id : tracing_session->buffers_index) {
      const TraceBuffer* buf = GetBufferByID(buf_id);
      if (!buf)
        continue;
      for (auto it = buf->writer_stats().GetIterator(); it; ++it) {
        auto& hist = merged_stats.Insert(it.key(), {}).first->used_chunk_hist;
        hist.Merge(it.value().used_chunk_hist);
      }
    }

    // Serialize the merged per-writer histogram into the stats proto.
    bool has_written_bucket_definition = false;
    for (auto it = merged_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 for 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));
        }
      }
      auto* wri_stats = trace_stats.add_writer_stats();
      wri_stats->set_sequence_id(tracing_session->GetPacketSequenceID(p, w));
      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 (writer in merged_stats.GetIterator())
  }    // if (!disable_chunk_usage_histograms)

  return trace_stats;
}

void TracingServiceImpl::MaybeEmitUuidAndTraceConfig(
    TracingSession* tracing_session,
    std::vector<TracePacket>* packets) {
  if (tracing_session->did_emit_config)
    return;
  tracing_session->did_emit_config = true;

  {
    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());
  }

  {
    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::MaybeEmitSystemInfo(
    TracingSession* tracing_session,
    std::vector<TracePacket>* packets) {
  if (tracing_session->did_emit_system_info)
    return;
  tracing_session->did_emit_system_info = true;
  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
  auto* info = packet->set_system_info();
  info->set_tracing_service_version(base::GetVersionString());
#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);
  }
#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");
  }
  info->set_hz(sysconf(_SC_CLK_TCK));
  info->set_page_size(static_cast<uint32_t>(sysconf(_SC_PAGESIZE)));
#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 (const auto& pair : timestamped_packets)
    SerializeAndAppendPacket(packets, std::move(pair.second));
}

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) {
  PERFETTO_DCHECK_THREAD(thread_checker_);

  if (tsid == kBugreportSessionId) {
    TracingSession* session = FindTracingSessionWithMaxBugreportScore();
    if (!session) {
      consumer->consumer_->OnSessionCloned(
          {false, "No tracing sessions eligible for bugreport found", {}});
      return;
    }
    tsid = session->id;
  }

  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  auto weak_consumer = consumer->GetWeakPtr();
  Flush(tsid, 0, [weak_this, tsid, weak_consumer](bool final_flush_outcome) {
    PERFETTO_LOG("FlushAndCloneSession(%" PRIu64 ") started, success=%d", tsid,
                 final_flush_outcome);
    if (!weak_this || !weak_consumer)
      return;
    base::Uuid uuid;
    base::Status result = weak_this->DoCloneSession(&*weak_consumer, tsid,
                                                    final_flush_outcome, &uuid);
    weak_consumer->consumer_->OnSessionCloned(
        {result.ok(), result.message(), uuid});
  });
}

base::Status TracingServiceImpl::DoCloneSession(ConsumerEndpointImpl* consumer,
                                                TracingSessionID src_tsid,
                                                bool final_flush_outcome,
                                                base::Uuid* new_uuid) {
  PERFETTO_DLOG("CloneSession(%" PRIu64 ") started, consumer uid: %d", src_tsid,
                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->config.bugreport_score() <= 0 &&
      src->consumer_uid != consumer->uid_ && consumer->uid_ != 0) {
    return PERFETTO_SVC_ERR("Not allowed to clone a session from another UID");
  }

  // First clone all TraceBuffer(s). This can fail because of ENOMEM. If it
  // happens bail out early before creating any session.
  std::vector<std::pair<BufferID, std::unique_ptr<TraceBuffer>>> buf_snaps;
  buf_snaps.reserve(src->num_buffers());
  bool buf_clone_failed = false;
  for (BufferID src_buf_id : src->buffers_index) {
    TraceBuffer* src_buf = GetBufferByID(src_buf_id);
    std::unique_ptr<TraceBuffer> buf_snap = src_buf->CloneReadOnly();
    BufferID buf_global_id = buffer_ids_.Allocate();
    buf_clone_failed |= !buf_snap.get() || !buf_global_id;
    buf_snaps.emplace_back(buf_global_id, std::move(buf_snap));
  }

  // Free up allocated IDs in case of failure. No need to free the TraceBuffers,
  // as they are still owned by the temporary |buf_snaps|.
  if (buf_clone_failed) {
    for (auto& kv : buf_snaps) {
      if (kv.first)
        buffer_ids_.Free(kv.first);
    }
    return PERFETTO_SVC_ERR("Buffer allocation failed");
  }

  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 (auto& kv : buf_snaps) {
    BufferID buf_global_id = kv.first;
    std::unique_ptr<TraceBuffer>& buf = kv.second;
    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.
  cloned_session->received_triggers = src->received_triggers;
  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) {
    // Copy the trace filter.
    cloned_session->trace_filter.reset(
        new protozero::MessageFilter(*src->trace_filter));
  }

  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();
}

////////////////////////////////////////////////////////////////////////////////
// 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) {
  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);
}

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(
    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(static_cast<int>(num_started));

  for (const auto& kv : service_->producers_) {
    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_) {
    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;
    // List only tracing sessions for the calling UID (or everything for root).
    if (uid_ != 0 && uid_ != s.consumer_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());
    for (const auto& snap_kv : s.initial_clock_snapshot) {
      if (snap_kv.first == protos::pbzero::BUILTIN_CLOCK_REALTIME)
        session->set_start_realtime_ns(static_cast<int64_t>(snap_kv.second));
    }
    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_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) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  // FlushAndCloneSession will call OnSessionCloned after the async flush.
  service_->FlushAndCloneSession(this, tsid);
}

////////////////////////////////////////////////////////////////////////////////
// TracingServiceImpl::ProducerEndpointImpl implementation
////////////////////////////////////////////////////////////////////////////////

TracingServiceImpl::ProducerEndpointImpl::ProducerEndpointImpl(
    ProducerID id,
    uid_t uid,
    pid_t pid,
    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),
      uid_(uid),
      pid_(pid),
      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 =
        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_, uid_, pid_, writer_id, chunk_id, buffer_id, num_fragments,
        chunk_flags,
        /*chunk_complete=*/true, chunk.payload_begin(), chunk.payload_size());

    // 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);
  if (in_process_) {
    inproc_shmem_arbiter_.reset(new SharedMemoryArbiterImpl(
        shared_memory_->start(), shared_memory_->size(),
        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) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostTask([weak_this, flush_request_id, data_sources] {
    if (weak_this) {
      weak_this->producer_->Flush(flush_request_id, data_sources.data(),
                                  data_sources.size());
    }
  });
}

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 */);
}

}  // 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/shared_memory.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.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 {

namespace {

class InProcessShm : public SharedMemory {
 public:
  explicit InProcessShm(size_t size);
  ~InProcessShm() override;
  void* start() const override;
  size_t size() const override;

 private:
  base::PagedMemory mem_;
};

class InProcessShmFactory : public SharedMemory::Factory {
 public:
  ~InProcessShmFactory() override;
  std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) override;
};

InProcessShm::~InProcessShm() = default;

InProcessShm::InProcessShm(size_t size)
    : mem_(base::PagedMemory::Allocate(size)) {}

void* InProcessShm::start() const {
  return mem_.Get();
}

size_t InProcessShm::size() const {
  return mem_.size();
}

InProcessShmFactory::~InProcessShmFactory() = default;
std::unique_ptr<SharedMemory> InProcessShmFactory::CreateSharedMemory(
    size_t size) {
  return std::unique_ptr<SharedMemory>(new InProcessShm(size));
}

}  // namespace

// static
TracingBackend* InProcessTracingBackend::GetInstance() {
  static auto* instance = new InProcessTracingBackend();
  return instance;
}

InProcessTracingBackend::InProcessTracingBackend() {}

std::unique_ptr<ProducerEndpoint> InProcessTracingBackend::ConnectProducer(
    const ConnectProducerArgs& args) {
  PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());
  return GetOrCreateService(args.task_runner)
      ->ConnectProducer(args.producer, /*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<InProcessShmFactory> shm(new InProcessShmFactory());
    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 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 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 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,
  };

  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); }

 private:
  uint64_t 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 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 {
  };

  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;

 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 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,
  };

  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); }

 private:
  uint32_t timeout_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 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 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/chrome/chrome_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_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_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_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 unknown_fields_ == other.unknown_fields_
   && success_ == other.success_
   && error_ == other.error_
   && uuid_msb_ == other.uuid_msb_
   && 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 unknown_fields_ == other.unknown_fields_
   && session_id_ == other.session_id_;
}

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;
      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);
  }

  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 unknown_fields_ == other.unknown_fields_
   && success_ == other.success_
   && 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 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 unknown_fields_ == other.unknown_fields_
   && 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 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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_;
}

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()) {
      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 {
  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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && 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 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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && 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 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 unknown_fields_ == other.unknown_fields_
   && 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 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 unknown_fields_ == other.unknown_fields_
   && timeout_ms_ == other.timeout_ms_;
}

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;
      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);
  }

  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 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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && data_ == other.data_
   && 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 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 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 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 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 unknown_fields_ == other.unknown_fields_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && disabled_ == other.disabled_
   && 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 unknown_fields_ == other.unknown_fields_
   && trace_config_ == other.trace_config_
   && 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 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 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 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,
  };

  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); }

 private:
  std::vector<uint64_t> data_source_ids_;
  uint64_t request_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 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,
  };

  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); }

 private:
  bool using_shmem_provided_by_producer_{};
  bool direct_smb_patching_supported_{};

  // 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 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 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/chrome/chrome_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_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_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_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 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 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 unknown_fields_ == other.unknown_fields_
   && setup_tracing_ == other.setup_tracing_
   && setup_data_source_ == other.setup_data_source_
   && start_data_source_ == other.start_data_source_
   && stop_data_source_ == other.stop_data_source_
   && flush_ == other.flush_
   && 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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && data_source_ids_ == other.data_source_ids_
   && request_id_ == other.request_id_;
}

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;
      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);
  }

  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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && new_instance_id_ == other.new_instance_id_
   && 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 unknown_fields_ == other.unknown_fields_
   && new_instance_id_ == other.new_instance_id_
   && 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 unknown_fields_ == other.unknown_fields_
   && shared_buffer_page_size_kb_ == other.shared_buffer_page_size_kb_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && 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 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 unknown_fields_ == other.unknown_fields_
   && 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 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 unknown_fields_ == other.unknown_fields_
   && 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 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 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 unknown_fields_ == other.unknown_fields_
   && 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 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 unknown_fields_ == other.unknown_fields_
   && trace_writer_id_ == other.trace_writer_id_
   && 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 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 unknown_fields_ == other.unknown_fields_
   && 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 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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && using_shmem_provided_by_producer_ == other.using_shmem_provided_by_producer_
   && direct_smb_patching_supported_ == other.direct_smb_patching_supported_;
}

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;
      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);
  }

  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 unknown_fields_ == other.unknown_fields_
   && shared_memory_page_size_hint_bytes_ == other.shared_memory_page_size_hint_bytes_
   && shared_memory_size_hint_bytes_ == other.shared_memory_size_hint_bytes_
   && producer_name_ == other.producer_name_
   && smb_scraping_mode_ == other.smb_scraping_mode_
   && producer_provided_shmem_ == other.producer_provided_shmem_
   && sdk_version_ == other.sdk_version_
   && 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/wire_protocol.gen.cc
// 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_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;
  enum FieldNumbers {
    kRequestIdFieldNumber = 2,
    kMsgBindServiceFieldNumber = 3,
    kMsgBindServiceReplyFieldNumber = 4,
    kMsgInvokeMethodFieldNumber = 5,
    kMsgInvokeMethodReplyFieldNumber = 6,
    kMsgRequestErrorFieldNumber = 7,
    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(); }

  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_;
  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<8> _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 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 unknown_fields_ == other.unknown_fields_
   && request_id_ == other.request_id_
   && msg_bind_service_ == other.msg_bind_service_
   && msg_bind_service_reply_ == other.msg_bind_service_reply_
   && msg_invoke_method_ == other.msg_invoke_method_
   && msg_invoke_method_reply_ == other.msg_invoke_method_reply_
   && msg_request_error_ == other.msg_request_error_
   && 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 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 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_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 unknown_fields_ == other.unknown_fields_
   && 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 unknown_fields_ == other.unknown_fields_
   && success_ == other.success_
   && has_more_ == other.has_more_
   && 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 unknown_fields_ == other.unknown_fields_
   && service_id_ == other.service_id_
   && method_id_ == other.method_id_
   && args_proto_ == other.args_proto_
   && 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 unknown_fields_ == other.unknown_fields_
   && success_ == other.success_
   && service_id_ == other.service_id_
   && 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 unknown_fields_ == other.unknown_fields_
   && id_ == other.id_
   && 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 unknown_fields_ == other.unknown_fields_
   && 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/export.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/base/utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"

struct msghdr;

namespace perfetto {
namespace base {

// Define the SocketHandle and ScopedSocketHandle types.
// On POSIX OSes, a SocketHandle is really just an int (a file descriptor).
// On Windows, sockets are have their own type (SOCKET) which is neither a
// HANDLE nor an int. However Windows SOCKET(s) can have a event HANDLE attached
// to them (which in Perfetto is a PlatformHandle), and that can be used in
// WaitForMultipleObjects, hence in base::TaskRunner.AddFileDescriptorWatch().

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
// uintptr_t really reads as SOCKET here (Windows headers typedef to that).
// As usual we don't just use SOCKET here to avoid leaking Windows.h includes
// in our headers.
using SocketHandle = uintptr_t;  // SOCKET
int CloseSocket(SocketHandle);   // A wrapper around ::closesocket().
using ScopedSocketHandle =
    ScopedResource<SocketHandle, CloseSocket, static_cast<SocketHandle>(-1)>;
#else
using SocketHandle = int;
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.
SockFamily GetSockFamily(const char* 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);
  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));
  }
  // 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_

#include <sys/socket.h>

#ifdef AF_VSOCK
// Use system vm_socket.h if avaialbe.
#include <linux/vm_sockets.h>
#else
// 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

#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 <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;
}

#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);

  template <typename T>
  explicit DeferredBase(Deferred<T> other)
      : callback_(std::move(other.callback_)) {}

  ~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/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)
      : client_id_(client_id), uid_(uid), pid_(pid) {}

  bool operator==(const ClientInfo& other) const {
    return (client_id_ == other.client_id_ && uid_ == other.uid_);
  }
  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_; }

 private:
  ClientID client_id_ = 0;
  uid_t uid_ = kInvalidUid;
  pid_t pid_ = base::kInvalidPid;
};

}  // 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();
  }

 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_;
};

}  // 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/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;
  };
  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 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/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/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");

uid_t GetPosixPeerUid(base::UnixSocket* sock) {
#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

  // Unsupported. Must be != kInvalidUid or the PacketValidator will fail.
  base::ignore_result(sock);
  return 0;
}

pid_t GetLinuxPeerPid(base::UnixSocket* sock) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  if (sock->family() == base::SockFamily::kUnix)
    return sock->peer_pid_linux();
#endif
  base::ignore_result(sock);
  return base::kInvalidPid;  // Unsupported.
}

}  // namespace

// 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;
  }
  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 = GetPosixPeerUid(client->sock.get());
  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);

  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 = GetPosixPeerUid(client->sock.get());
  auto scoped_key = g_crash_key_uid.SetScoped(static_cast<int64_t>(peer_uid));
  service->client_info_ =
      ClientInfo(client->id, peer_uid, GetLinuxPeerPid(client->sock.get()));
  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::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 = GetPosixPeerUid(client->sock.get());
  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;
  ClientID client_id = it->second->id;

  ClientInfo client_info(client_id, GetPosixPeerUid(sock),
                         GetLinuxPeerPid(sock));
  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: src/tracing/ipc/default_socket.cc
// gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/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_EXT_TRACING_IPC_DEFAULT_SOCKET_H_
#define INCLUDE_PERFETTO_EXT_TRACING_IPC_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();

}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_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.
 */

// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/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

static_assert(kInvalidUid == ipc::kInvalidUid, "kInvalidUid mismatching");

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;
}

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)

// 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.
  static std::unique_ptr<SharedMemoryWindows> Create(size_t size);
  static std::unique_ptr<SharedMemoryWindows> Attach(const std::string& key);
  ~SharedMemoryWindows() override;
  const std::string& key() const { return key_; }

  // 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) {
  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);
  shmem_handle.reset(CreateFileMappingA(
      INVALID_HANDLE_VALUE,  // Use paging file.
      nullptr,               // Default security.
      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)));
}

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) 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(QueryServiceStateCallback) override;
  void QueryCapabilities(QueryCapabilitiesCallback) override;
  void SaveTraceForBugreport(SaveTraceForBugreportCallback) override;
  void CloneSession(TracingSessionID) 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) {
  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));
  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(
    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;
  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) {
  if (!connected_) {
    PERFETTO_DLOG("Cannot CloneSession(), not connected to tracing service");
    return;
  }

  protos::gen::CloneSessionRequest req;
  req.set_session_id(tsid);
  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"

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);

 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.
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);
  ~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);

  // 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;
  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/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_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"

#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)));
}

// 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) {
  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)));
}

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)
    : producer_(producer),
      task_runner_(task_runner),
      receive_shmem_fd_cb_fuchsia_(
          std::move(conn_args.receive_shmem_fd_cb_fuchsia)),
      ipc_channel_(
          ipc::Client::CreateInstance(std::move(conn_args), task_runner)),
      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;
  }

  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);
      });
  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) {
  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;
  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 (ipc_shared_memory) {
      // 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, 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");
    producer_->Flush(
        cmd.flush().request_id(),
        reinterpret_cast<const DataSourceInstanceID*>(data_source_ids),
        static_cast<size_t>(cmd.flush().data_source_ids().size()));
    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));
  };
  GetConsumerForCurrentRequest()->service_endpoint->Flush(req.timeout_ms(),
                                                          std::move(callback));
}

// 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&,
    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));
  };
  remote_consumer->service_endpoint->QueryServiceState(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);
  remote_consumer->service_endpoint->CloneSession(req.session_id());
}

// 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) 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/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
  }

  // ConnectProducer will call OnConnect() on the next task.
  producer->service_endpoint = core_service_->ConnectProducer(
      producer.get(), client_info.uid(), client_info.pid(), 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 using_producer_shmem =
      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);
  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) {
  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);
  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/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/ext/tracing/ipc/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/base/string_splitter.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"

#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);
  }

  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/default_socket.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/producer_ipc_client.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);
  }

  auto endpoint = ProducerIPCClient::Connect(
      GetProducerSocket(), args.producer, args.producer_name, args.task_runner,
      TracingService::ProducerSMBScrapingMode::kEnabled, shmem_size_hint,
      shmem_page_size_hint, std::move(shm), std::move(arbiter),
      ProducerIPCClient::ConnectionFlags::kRetryIfUnreachable);
  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

