Introduce ArgsParser to write parsed protos to TraceStorage

The logic for interning parsed key strings and writing the key-value
pair into TraceStorage is duplicated several times. Introduce a new
class to consolidate the repeated code.

Bug: 332714237
Test: presubmit
Change-Id: I5de1ab3a1ddcfe3c1882a60c4aea5d678379ab01
diff --git a/Android.bp b/Android.bp
index b379ef7..ad476e1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12371,6 +12371,7 @@
     name: "perfetto_src_trace_processor_importers_proto_minimal",
     srcs: [
         "src/trace_processor/importers/proto/active_chrome_processes_tracker.cc",
+        "src/trace_processor/importers/proto/args_parser.cc",
         "src/trace_processor/importers/proto/chrome_string_lookup.cc",
         "src/trace_processor/importers/proto/chrome_system_probes_module.cc",
         "src/trace_processor/importers/proto/chrome_system_probes_parser.cc",
@@ -12436,7 +12437,6 @@
         "src/trace_processor/importers/proto/winscope/shell_transitions_tracker.cc",
         "src/trace_processor/importers/proto/winscope/surfaceflinger_layers_parser.cc",
         "src/trace_processor/importers/proto/winscope/surfaceflinger_transactions_parser.cc",
-        "src/trace_processor/importers/proto/winscope/winscope_args_parser.cc",
         "src/trace_processor/importers/proto/winscope/winscope_module.cc",
     ],
 }
diff --git a/BUILD b/BUILD
index 55ad910..b8494798 100644
--- a/BUILD
+++ b/BUILD
@@ -1744,8 +1744,6 @@
         "src/trace_processor/importers/proto/winscope/surfaceflinger_layers_parser.h",
         "src/trace_processor/importers/proto/winscope/surfaceflinger_transactions_parser.cc",
         "src/trace_processor/importers/proto/winscope/surfaceflinger_transactions_parser.h",
-        "src/trace_processor/importers/proto/winscope/winscope_args_parser.cc",
-        "src/trace_processor/importers/proto/winscope/winscope_args_parser.h",
         "src/trace_processor/importers/proto/winscope/winscope_module.cc",
         "src/trace_processor/importers/proto/winscope/winscope_module.h",
     ],
@@ -1874,6 +1872,8 @@
     srcs = [
         "src/trace_processor/importers/proto/active_chrome_processes_tracker.cc",
         "src/trace_processor/importers/proto/active_chrome_processes_tracker.h",
+        "src/trace_processor/importers/proto/args_parser.cc",
+        "src/trace_processor/importers/proto/args_parser.h",
         "src/trace_processor/importers/proto/chrome_string_lookup.cc",
         "src/trace_processor/importers/proto/chrome_string_lookup.h",
         "src/trace_processor/importers/proto/chrome_system_probes_module.cc",
diff --git a/src/trace_processor/importers/proto/BUILD.gn b/src/trace_processor/importers/proto/BUILD.gn
index 18a617a..11df5b7 100644
--- a/src/trace_processor/importers/proto/BUILD.gn
+++ b/src/trace_processor/importers/proto/BUILD.gn
@@ -18,6 +18,8 @@
   sources = [
     "active_chrome_processes_tracker.cc",
     "active_chrome_processes_tracker.h",
+    "args_parser.cc",
+    "args_parser.h",
     "chrome_string_lookup.cc",
     "chrome_string_lookup.h",
     "chrome_system_probes_module.cc",
diff --git a/src/trace_processor/importers/proto/args_parser.cc b/src/trace_processor/importers/proto/args_parser.cc
new file mode 100644
index 0000000..bdd34f8
--- /dev/null
+++ b/src/trace_processor/importers/proto/args_parser.cc
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/trace_processor/importers/proto/args_parser.h"
+
+#include "perfetto/ext/base/base64.h"
+#include "src/trace_processor/importers/json/json_utils.h"
+
+namespace perfetto::trace_processor {
+
+using BoundInserter = ArgsTracker::BoundInserter;
+
+ArgsParser::ArgsParser(
+    int64_t packet_timestamp,
+    BoundInserter& inserter,
+    TraceStorage& storage,
+    PacketSequenceStateGeneration* sequence_state,
+    bool support_json)
+    : support_json_(support_json),
+      packet_timestamp_(packet_timestamp),
+      sequence_state_(sequence_state),
+      inserter_(inserter),
+      storage_(storage) {}
+
+ArgsParser::~ArgsParser() = default;
+
+void ArgsParser::AddInteger(const Key& key, int64_t value) {
+  inserter_.AddArg(storage_.InternString(base::StringView(key.flat_key)),
+                   storage_.InternString(base::StringView(key.key)),
+                   Variadic::Integer(value));
+}
+
+void ArgsParser::AddUnsignedInteger(const Key& key, uint64_t value) {
+  inserter_.AddArg(storage_.InternString(base::StringView(key.flat_key)),
+                   storage_.InternString(base::StringView(key.key)),
+                   Variadic::UnsignedInteger(value));
+}
+
+void ArgsParser::AddString(const Key& key,
+                                    const protozero::ConstChars& value) {
+  inserter_.AddArg(storage_.InternString(base::StringView(key.flat_key)),
+                   storage_.InternString(base::StringView(key.key)),
+                   Variadic::String(storage_.InternString(value)));
+}
+
+void ArgsParser::AddString(const Key& key, const std::string& value) {
+  inserter_.AddArg(
+      storage_.InternString(base::StringView(key.flat_key)),
+      storage_.InternString(base::StringView(key.key)),
+      Variadic::String(storage_.InternString(base::StringView(value))));
+}
+
+void ArgsParser::AddDouble(const Key& key, double value) {
+  inserter_.AddArg(storage_.InternString(base::StringView(key.flat_key)),
+                   storage_.InternString(base::StringView(key.key)),
+                   Variadic::Real(value));
+}
+
+void ArgsParser::AddPointer(const Key& key, const void* value) {
+  inserter_.AddArg(storage_.InternString(base::StringView(key.flat_key)),
+                   storage_.InternString(base::StringView(key.key)),
+                   Variadic::Pointer(reinterpret_cast<uintptr_t>(value)));
+}
+
+void ArgsParser::AddBoolean(const Key& key, bool value) {
+  inserter_.AddArg(storage_.InternString(base::StringView(key.flat_key)),
+                   storage_.InternString(base::StringView(key.key)),
+                   Variadic::Boolean(value));
+}
+
+void ArgsParser::AddBytes(const Key& key,
+                                   const protozero::ConstBytes& value) {
+  std::string b64_data = base::Base64Encode(value.data, value.size);
+  AddString(key, b64_data);
+}
+
+bool ArgsParser::AddJson(const Key& key,
+                                  const protozero::ConstChars& value) {
+  if (!support_json_)
+    PERFETTO_FATAL("Unexpected JSON value when parsing data");
+
+  auto json_value = json::ParseJsonString(value);
+  if (!json_value)
+    return false;
+  return json::AddJsonValueToArgs(*json_value, base::StringView(key.flat_key),
+                                  base::StringView(key.key), &storage_,
+                                  &inserter_);
+}
+
+void ArgsParser::AddNull(const Key& key) {
+  inserter_.AddArg(storage_.InternString(base::StringView(key.flat_key)),
+                   storage_.InternString(base::StringView(key.key)),
+                   Variadic::Null());
+}
+
+size_t ArgsParser::GetArrayEntryIndex(const std::string& array_key) {
+  return inserter_.GetNextArrayEntryIndex(
+      storage_.InternString(base::StringView(array_key)));
+}
+
+size_t ArgsParser::IncrementArrayEntryIndex(
+    const std::string& array_key) {
+  return inserter_.IncrementArrayEntryIndex(
+      storage_.InternString(base::StringView(array_key)));
+}
+
+int64_t ArgsParser::packet_timestamp() {
+  return packet_timestamp_;
+}
+
+PacketSequenceStateGeneration* ArgsParser::seq_state() {
+  return sequence_state_;
+}
+
+InternedMessageView* ArgsParser::GetInternedMessageView(
+    uint32_t field_id,
+    uint64_t iid) {
+  if (!sequence_state_)
+    return nullptr;
+  return sequence_state_->GetInternedMessageView(field_id, iid);
+}
+
+}  // namespace perfetto:trace_processor
diff --git a/src/trace_processor/importers/proto/winscope/winscope_args_parser.h b/src/trace_processor/importers/proto/args_parser.h
similarity index 60%
rename from src/trace_processor/importers/proto/winscope/winscope_args_parser.h
rename to src/trace_processor/importers/proto/args_parser.h
index a0dfa46..7cd1578 100644
--- a/src/trace_processor/importers/proto/winscope/winscope_args_parser.h
+++ b/src/trace_processor/importers/proto/args_parser.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,22 +14,28 @@
  * limitations under the License.
  */
 
-#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_WINSCOPE_WINSCOPE_ARGS_PARSER_H_
-#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_WINSCOPE_WINSCOPE_ARGS_PARSER_H_
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ARGS_PARSER_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ARGS_PARSER_H_
 
 #include "src/trace_processor/importers/common/args_tracker.h"
+#include "src/trace_processor/importers/proto/packet_sequence_state_generation.h"
 #include "src/trace_processor/types/trace_processor_context.h"
 #include "src/trace_processor/util/proto_to_args_parser.h"
 
-namespace perfetto {
-namespace trace_processor {
+namespace perfetto::trace_processor {
 
-class WinscopeArgsParser : public util::ProtoToArgsParser::Delegate {
+// A ProtoToArgsParser::Delegate that writes the parsed proto data into
+// TraceStorage after interning key strings.
+class ArgsParser : public util::ProtoToArgsParser::Delegate {
  public:
   using Key = util::ProtoToArgsParser::Key;
 
-  WinscopeArgsParser(ArgsTracker::BoundInserter& inserter,
-                     TraceStorage& storage);
+  ArgsParser(int64_t packet_timestamp,
+                      ArgsTracker::BoundInserter& inserter,
+                      TraceStorage& storage,
+                      PacketSequenceStateGeneration* sequence_state = nullptr,
+                      bool support_json = false);
+  ~ArgsParser() override;
   void AddInteger(const Key&, int64_t) override;
   void AddUnsignedInteger(const Key&, uint64_t) override;
   void AddString(const Key&, const protozero::ConstChars&) override;
@@ -37,10 +43,12 @@
   void AddDouble(const Key&, double) override;
   void AddPointer(const Key&, const void*) override;
   void AddBoolean(const Key&, bool) override;
+  void AddBytes(const Key&, const protozero::ConstBytes&) override;
   bool AddJson(const Key&, const protozero::ConstChars&) override;
   void AddNull(const Key&) override;
   size_t GetArrayEntryIndex(const std::string& array_key) override;
   size_t IncrementArrayEntryIndex(const std::string& array_key) override;
+  int64_t packet_timestamp() override;
   PacketSequenceStateGeneration* seq_state() override;
 
  protected:
@@ -48,11 +56,13 @@
                                               uint64_t iid) override;
 
  private:
+  const bool support_json_;
+  const int64_t packet_timestamp_;
+  PacketSequenceStateGeneration* const sequence_state_;
   ArgsTracker::BoundInserter& inserter_;
   TraceStorage& storage_;
 };
 
-}  // namespace trace_processor
-}  // namespace perfetto
+}  // namespace perfetto::trace_processor
 
-#endif  // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_WINSCOPE_WINSCOPE_ARGS_PARSER_H_
+#endif  // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_ARGS_PARSER_H_
diff --git a/src/trace_processor/importers/proto/statsd_module.cc b/src/trace_processor/importers/proto/statsd_module.cc
index e925b5a..62faf01 100644
--- a/src/trace_processor/importers/proto/statsd_module.cc
+++ b/src/trace_processor/importers/proto/statsd_module.cc
@@ -23,6 +23,7 @@
 #include "src/trace_processor/importers/common/machine_tracker.h"
 #include "src/trace_processor/importers/common/slice_tracker.h"
 #include "src/trace_processor/importers/common/track_tracker.h"
+#include "src/trace_processor/importers/proto/args_parser.h"
 #include "src/trace_processor/importers/proto/packet_sequence_state_generation.h"
 #include "src/trace_processor/sorter/trace_sorter.h"
 #include "src/trace_processor/storage/stats.h"
@@ -37,111 +38,6 @@
 
 constexpr const char* kAtomProtoName = ".android.os.statsd.Atom";
 
-using BoundInserter = ArgsTracker::BoundInserter;
-
-class InserterDelegate : public util::ProtoToArgsParser::Delegate {
- public:
-  InserterDelegate(BoundInserter& inserter, TraceStorage& storage)
-      : inserter_(inserter), storage_(storage) {}
-  ~InserterDelegate() override = default;
-
-  using Key = util::ProtoToArgsParser::Key;
-
-  void AddInteger(const Key& key, int64_t value) override {
-    StringId flat_key_id =
-        storage_.InternString(base::StringView(key.flat_key));
-    StringId key_id = storage_.InternString(base::StringView(key.key));
-    Variadic variadic_val = Variadic::Integer(value);
-    inserter_.AddArg(flat_key_id, key_id, variadic_val);
-  }
-
-  void AddUnsignedInteger(const Key& key, uint64_t value) override {
-    StringId flat_key_id =
-        storage_.InternString(base::StringView(key.flat_key));
-    StringId key_id = storage_.InternString(base::StringView(key.key));
-    Variadic variadic_val = Variadic::UnsignedInteger(value);
-    inserter_.AddArg(flat_key_id, key_id, variadic_val);
-  }
-
-  void AddString(const Key& key, const protozero::ConstChars& value) override {
-    StringId flat_key_id =
-        storage_.InternString(base::StringView(key.flat_key));
-    StringId key_id = storage_.InternString(base::StringView(key.key));
-    Variadic variadic_val = Variadic::String(storage_.InternString(value));
-    inserter_.AddArg(flat_key_id, key_id, variadic_val);
-  }
-
-  void AddString(const Key& key, const std::string& value) override {
-    StringId flat_key_id =
-        storage_.InternString(base::StringView(key.flat_key));
-    StringId key_id = storage_.InternString(base::StringView(key.key));
-    Variadic variadic_val =
-        Variadic::String(storage_.InternString(base::StringView(value)));
-    inserter_.AddArg(flat_key_id, key_id, variadic_val);
-  }
-
-  void AddDouble(const Key& key, double value) override {
-    StringId flat_key_id =
-        storage_.InternString(base::StringView(key.flat_key));
-    StringId key_id = storage_.InternString(base::StringView(key.key));
-    Variadic variadic_val = Variadic::Real(value);
-    inserter_.AddArg(flat_key_id, key_id, variadic_val);
-  }
-
-  void AddPointer(const Key& key, const void* value) override {
-    StringId flat_key_id =
-        storage_.InternString(base::StringView(key.flat_key));
-    StringId key_id = storage_.InternString(base::StringView(key.key));
-    Variadic variadic_val =
-        Variadic::Pointer(reinterpret_cast<uintptr_t>(value));
-    inserter_.AddArg(flat_key_id, key_id, variadic_val);
-  }
-
-  void AddBoolean(const Key& key, bool value) override {
-    StringId flat_key_id =
-        storage_.InternString(base::StringView(key.flat_key));
-    StringId key_id = storage_.InternString(base::StringView(key.key));
-    Variadic variadic_val = Variadic::Boolean(value);
-    inserter_.AddArg(flat_key_id, key_id, variadic_val);
-  }
-
-  bool AddJson(const Key&, const protozero::ConstChars&) override {
-    PERFETTO_FATAL("Unexpected JSON value when parsing statsd data");
-  }
-
-  void AddNull(const Key& key) override {
-    StringId flat_key_id =
-        storage_.InternString(base::StringView(key.flat_key));
-    StringId key_id = storage_.InternString(base::StringView(key.key));
-    Variadic variadic_val = Variadic::Null();
-    inserter_.AddArg(flat_key_id, key_id, variadic_val);
-  }
-
-  size_t GetArrayEntryIndex(const std::string& array_key) override {
-    base::ignore_result(array_key);
-    return 0;
-  }
-
-  size_t IncrementArrayEntryIndex(const std::string& array_key) override {
-    base::ignore_result(array_key);
-    return 0;
-  }
-
-  PacketSequenceStateGeneration* seq_state() override { return nullptr; }
-
- protected:
-  InternedMessageView* GetInternedMessageView(uint32_t field_id,
-                                              uint64_t iid) override {
-    base::ignore_result(field_id);
-    base::ignore_result(iid);
-    return nullptr;
-  }
-
- private:
-  BoundInserter& inserter_;
-  TraceStorage& storage_;
-};
-
 // If we don't know about the atom format put whatever details we
 // can. This has the following restrictions:
 // - We can't tell the difference between double, fixed64, sfixed64
@@ -296,7 +192,7 @@
   }
   SliceId slice = opt_slice.value();
   auto inserter = context_->args_tracker->AddArgsTo(slice);
-  InserterDelegate delegate(inserter, *context_->storage.get());
+  ArgsParser delegate(ts, inserter, *context_->storage.get());
 
   const auto& fields = pool_.descriptor()->fields();
   const auto& field_it = fields.find(nested_field_id);
diff --git a/src/trace_processor/importers/proto/track_event_parser.cc b/src/trace_processor/importers/proto/track_event_parser.cc
index 09ef474..27e9a13 100644
--- a/src/trace_processor/importers/proto/track_event_parser.cc
+++ b/src/trace_processor/importers/proto/track_event_parser.cc
@@ -32,6 +32,7 @@
 #include "src/trace_processor/importers/common/process_tracker.h"
 #include "src/trace_processor/importers/common/track_tracker.h"
 #include "src/trace_processor/importers/json/json_utils.h"
+#include "src/trace_processor/importers/proto/args_parser.h"
 #include "src/trace_processor/importers/proto/packet_analyzer.h"
 #include "src/trace_processor/importers/proto/profile_packet_utils.h"
 #include "src/trace_processor/importers/proto/stack_profile_sequence_state.h"
@@ -73,103 +74,6 @@
 constexpr int64_t kPendingThreadDuration = -1;
 constexpr int64_t kPendingThreadInstructionDelta = -1;
 
-class TrackEventArgsParser : public util::ProtoToArgsParser::Delegate {
- public:
-  TrackEventArgsParser(int64_t packet_timestamp,
-                       BoundInserter& inserter,
-                       TraceStorage& storage,
-                       PacketSequenceStateGeneration& sequence_state)
-      : packet_timestamp_(packet_timestamp),
-        inserter_(inserter),
-        storage_(storage),
-        sequence_state_(sequence_state) {}
-
-  ~TrackEventArgsParser() override;
-
-  using Key = util::ProtoToArgsParser::Key;
-
-  void AddInteger(const Key& key, int64_t value) final {
-    inserter_.AddArg(storage_.InternString(base::StringView(key.flat_key)),
-                     storage_.InternString(base::StringView(key.key)),
-                     Variadic::Integer(value));
-  }
-  void AddUnsignedInteger(const Key& key, uint64_t value) final {
-    inserter_.AddArg(storage_.InternString(base::StringView(key.flat_key)),
-                     storage_.InternString(base::StringView(key.key)),
-                     Variadic::UnsignedInteger(value));
-  }
-  void AddString(const Key& key, const protozero::ConstChars& value) final {
-    inserter_.AddArg(storage_.InternString(base::StringView(key.flat_key)),
-                     storage_.InternString(base::StringView(key.key)),
-                     Variadic::String(storage_.InternString(value)));
-  }
-  void AddString(const Key& key, const std::string& value) final {
-    inserter_.AddArg(
-        storage_.InternString(base::StringView(key.flat_key)),
-        storage_.InternString(base::StringView(key.key)),
-        Variadic::String(storage_.InternString(base::StringView(value))));
-  }
-  void AddDouble(const Key& key, double value) final {
-    inserter_.AddArg(storage_.InternString(base::StringView(key.flat_key)),
-                     storage_.InternString(base::StringView(key.key)),
-                     Variadic::Real(value));
-  }
-  void AddPointer(const Key& key, const void* value) final {
-    inserter_.AddArg(storage_.InternString(base::StringView(key.flat_key)),
-                     storage_.InternString(base::StringView(key.key)),
-                     Variadic::Pointer(reinterpret_cast<uintptr_t>(value)));
-  }
-  void AddBoolean(const Key& key, bool value) final {
-    inserter_.AddArg(storage_.InternString(base::StringView(key.flat_key)),
-                     storage_.InternString(base::StringView(key.key)),
-                     Variadic::Boolean(value));
-  }
-  void AddBytes(const Key& key, const protozero::ConstBytes& value) final {
-    std::string b64_data = base::Base64Encode(value.data, value.size);
-    AddString(key, b64_data);
-  }
-  bool AddJson(const Key& key, const protozero::ConstChars& value) final {
-    auto json_value = json::ParseJsonString(value);
-    if (!json_value)
-      return false;
-    return json::AddJsonValueToArgs(*json_value, base::StringView(key.flat_key),
-                                    base::StringView(key.key), &storage_,
-                                    &inserter_);
-  }
-  void AddNull(const Key& key) final {
-    inserter_.AddArg(storage_.InternString(base::StringView(key.flat_key)),
-                     storage_.InternString(base::StringView(key.key)),
-                     Variadic::Null());
-  }
-
-  size_t GetArrayEntryIndex(const std::string& array_key) final {
-    return inserter_.GetNextArrayEntryIndex(
-        storage_.InternString(base::StringView(array_key)));
-  }
-
-  size_t IncrementArrayEntryIndex(const std::string& array_key) final {
-    return inserter_.IncrementArrayEntryIndex(
-        storage_.InternString(base::StringView(array_key)));
-  }
-
-  InternedMessageView* GetInternedMessageView(uint32_t field_id,
-                                              uint64_t iid) final {
-    return sequence_state_.GetInternedMessageView(field_id, iid);
-  }
-
-  int64_t packet_timestamp() final { return packet_timestamp_; }
-
-  PacketSequenceStateGeneration* seq_state() final { return &sequence_state_; }
-
- private:
-  int64_t packet_timestamp_;
-  BoundInserter& inserter_;
-  TraceStorage& storage_;
-  PacketSequenceStateGeneration& sequence_state_;
-};
-
-TrackEventArgsParser::~TrackEventArgsParser() = default;
-
 // Paths on Windows use backslash rather than slash as a separator.
 // Normalise the paths by replacing backslashes with slashes to make it
 // easier to write cross-platform scripts.
@@ -1225,8 +1129,8 @@
       }
     }
 
-    TrackEventArgsParser args_writer(ts_, *inserter, *storage_,
-                                     *sequence_state_);
+    ArgsParser args_writer(ts_, *inserter, *storage_, sequence_state_,
+                                    /*support_json=*/true);
     int unknown_extensions = 0;
     log_errors(parser_->args_parser_.ParseMessage(
         blob_, ".perfetto.protos.TrackEvent", &parser_->reflect_fields_,
diff --git a/src/trace_processor/importers/proto/winscope/BUILD.gn b/src/trace_processor/importers/proto/winscope/BUILD.gn
index 09b7b77..593b749 100644
--- a/src/trace_processor/importers/proto/winscope/BUILD.gn
+++ b/src/trace_processor/importers/proto/winscope/BUILD.gn
@@ -28,8 +28,6 @@
     "surfaceflinger_layers_parser.h",
     "surfaceflinger_transactions_parser.cc",
     "surfaceflinger_transactions_parser.h",
-    "winscope_args_parser.cc",
-    "winscope_args_parser.h",
     "winscope_module.cc",
     "winscope_module.h",
   ]
diff --git a/src/trace_processor/importers/proto/winscope/shell_transitions_parser.cc b/src/trace_processor/importers/proto/winscope/shell_transitions_parser.cc
index 68d2a82..1b3cda0 100644
--- a/src/trace_processor/importers/proto/winscope/shell_transitions_parser.cc
+++ b/src/trace_processor/importers/proto/winscope/shell_transitions_parser.cc
@@ -19,8 +19,8 @@
 
 #include "protos/perfetto/trace/android/shell_transition.pbzero.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
+#include "src/trace_processor/importers/proto/args_parser.h"
 #include "src/trace_processor/importers/proto/winscope/winscope.descriptor.h"
-#include "src/trace_processor/importers/proto/winscope/winscope_args_parser.h"
 #include "src/trace_processor/storage/trace_storage.h"
 #include "src/trace_processor/types/trace_processor_context.h"
 
@@ -49,7 +49,8 @@
   }
 
   auto inserter = context_->args_tracker->AddArgsTo(row_id);
-  WinscopeArgsParser writer(inserter, *context_->storage.get());
+  ArgsParser writer(/*timestamp=*/0, inserter,
+                             *context_->storage.get());
   base::Status status = args_parser_.ParseMessage(
       blob, kShellTransitionsProtoName, nullptr /* parse all fields */, writer);
 
diff --git a/src/trace_processor/importers/proto/winscope/surfaceflinger_layers_parser.cc b/src/trace_processor/importers/proto/winscope/surfaceflinger_layers_parser.cc
index ebe370c..20687e4 100644
--- a/src/trace_processor/importers/proto/winscope/surfaceflinger_layers_parser.cc
+++ b/src/trace_processor/importers/proto/winscope/surfaceflinger_layers_parser.cc
@@ -18,8 +18,8 @@
 
 #include "protos/perfetto/trace/android/surfaceflinger_layers.pbzero.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
+#include "src/trace_processor/importers/proto/args_parser.h"
 #include "src/trace_processor/importers/proto/winscope/winscope.descriptor.h"
-#include "src/trace_processor/importers/proto/winscope/winscope_args_parser.h"
 #include "src/trace_processor/types/trace_processor_context.h"
 
 namespace perfetto {
@@ -44,7 +44,7 @@
           .id;
 
   auto inserter = context_->args_tracker->AddArgsTo(snapshot_id);
-  WinscopeArgsParser writer(inserter, *context_->storage.get());
+  ArgsParser writer(timestamp, inserter, *context_->storage);
   base::Status status =
       args_parser_.ParseMessage(blob, kLayersSnapshotProtoName,
                                 &kLayersSnapshotFieldsToArgsParse, writer);
@@ -55,11 +55,12 @@
   protos::pbzero::LayersProto::Decoder layers_decoder(
       snapshot_decoder.layers().data, snapshot_decoder.layers().size);
   for (auto it = layers_decoder.layers(); it; ++it) {
-    ParseLayer(*it, snapshot_id);
+    ParseLayer(timestamp, *it, snapshot_id);
   }
 }
 
 void SurfaceFlingerLayersParser::ParseLayer(
+    int64_t timestamp,
     protozero::ConstBytes blob,
     tables::SurfaceFlingerLayersSnapshotTable::Id snapshot_id) {
   tables::SurfaceFlingerLayerTable::Row layer;
@@ -69,7 +70,7 @@
 
   ArgsTracker tracker(context_);
   auto inserter = tracker.AddArgsTo(layerId);
-  WinscopeArgsParser writer(inserter, *context_->storage.get());
+  ArgsParser writer(timestamp, inserter, *context_->storage);
   base::Status status = args_parser_.ParseMessage(
       blob, kLayerProtoName, nullptr /* parse all fields */, writer);
   if (!status.ok()) {
diff --git a/src/trace_processor/importers/proto/winscope/surfaceflinger_layers_parser.h b/src/trace_processor/importers/proto/winscope/surfaceflinger_layers_parser.h
index 866cbae..07aea28 100644
--- a/src/trace_processor/importers/proto/winscope/surfaceflinger_layers_parser.h
+++ b/src/trace_processor/importers/proto/winscope/surfaceflinger_layers_parser.h
@@ -39,7 +39,7 @@
       ".perfetto.protos.LayersSnapshotProto";
   static constexpr auto* kLayerProtoName = ".perfetto.protos.LayerProto";
 
-  void ParseLayer(protozero::ConstBytes blob,
+  void ParseLayer(int64_t timestamp, protozero::ConstBytes blob,
                   tables::SurfaceFlingerLayersSnapshotTable::Id);
 
   TraceProcessorContext* const context_;
diff --git a/src/trace_processor/importers/proto/winscope/surfaceflinger_transactions_parser.cc b/src/trace_processor/importers/proto/winscope/surfaceflinger_transactions_parser.cc
index ae3a3e9..c2c5638 100644
--- a/src/trace_processor/importers/proto/winscope/surfaceflinger_transactions_parser.cc
+++ b/src/trace_processor/importers/proto/winscope/surfaceflinger_transactions_parser.cc
@@ -18,8 +18,8 @@
 
 #include "protos/perfetto/trace/android/surfaceflinger_transactions.pbzero.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
+#include "src/trace_processor/importers/proto/args_parser.h"
 #include "src/trace_processor/importers/proto/winscope/winscope.descriptor.h"
-#include "src/trace_processor/importers/proto/winscope/winscope_args_parser.h"
 #include "src/trace_processor/storage/trace_storage.h"
 #include "src/trace_processor/types/trace_processor_context.h"
 
@@ -43,7 +43,7 @@
 
   ArgsTracker tracker(context_);
   auto inserter = tracker.AddArgsTo(rowId);
-  WinscopeArgsParser writer(inserter, *context_->storage.get());
+  ArgsParser writer(timestamp, inserter, *context_->storage.get());
   base::Status status =
       args_parser_.ParseMessage(blob, kTransactionTraceEntryProtoName,
                                 nullptr /* parse all fields */, writer);
diff --git a/src/trace_processor/importers/proto/winscope/winscope_args_parser.cc b/src/trace_processor/importers/proto/winscope/winscope_args_parser.cc
deleted file mode 100644
index aa4ff3e..0000000
--- a/src/trace_processor/importers/proto/winscope/winscope_args_parser.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.
- */
-
-#include "src/trace_processor/importers/proto/winscope/winscope_args_parser.h"
-
-namespace perfetto {
-namespace trace_processor {
-
-WinscopeArgsParser::WinscopeArgsParser(ArgsTracker::BoundInserter& inserter,
-                                       TraceStorage& storage)
-    : inserter_{inserter}, storage_{storage} {}
-
-void WinscopeArgsParser::AddInteger(const Key& key, int64_t value) {
-  const auto flat_key_id =
-      storage_.InternString(base::StringView(key.flat_key));
-  const auto key_id = storage_.InternString(base::StringView(key.key));
-  const auto variadic_val = Variadic::Integer(value);
-  inserter_.AddArg(flat_key_id, key_id, variadic_val);
-}
-
-void WinscopeArgsParser::AddUnsignedInteger(const Key& key, uint64_t value) {
-  const auto flat_key_id =
-      storage_.InternString(base::StringView(key.flat_key));
-  const auto key_id = storage_.InternString(base::StringView(key.key));
-  const auto variadic_val = Variadic::UnsignedInteger(value);
-  inserter_.AddArg(flat_key_id, key_id, variadic_val);
-}
-
-void WinscopeArgsParser::AddString(const Key& key,
-                                   const protozero::ConstChars& value) {
-  const auto flat_key_id =
-      storage_.InternString(base::StringView(key.flat_key));
-  const auto key_id = storage_.InternString(base::StringView(key.key));
-  const auto variadic_val = Variadic::String(storage_.InternString(value));
-  inserter_.AddArg(flat_key_id, key_id, variadic_val);
-}
-
-void WinscopeArgsParser::AddString(const Key& key, const std::string& value) {
-  const auto flat_key_id =
-      storage_.InternString(base::StringView(key.flat_key));
-  const auto key_id = storage_.InternString(base::StringView(key.key));
-  const auto variadic_val =
-      Variadic::String(storage_.InternString(base::StringView(value)));
-  inserter_.AddArg(flat_key_id, key_id, variadic_val);
-}
-
-void WinscopeArgsParser::AddDouble(const Key& key, double value) {
-  const auto flat_key_id =
-      storage_.InternString(base::StringView(key.flat_key));
-  const auto key_id = storage_.InternString(base::StringView(key.key));
-  const auto variadic_val = Variadic::Real(value);
-  inserter_.AddArg(flat_key_id, key_id, variadic_val);
-}
-
-void WinscopeArgsParser::AddPointer(const Key& key, const void* value) {
-  const auto flat_key_id =
-      storage_.InternString(base::StringView(key.flat_key));
-  const auto key_id = storage_.InternString(base::StringView(key.key));
-  const auto variadic_val =
-      Variadic::Pointer(reinterpret_cast<uintptr_t>(value));
-  inserter_.AddArg(flat_key_id, key_id, variadic_val);
-}
-
-void WinscopeArgsParser::AddBoolean(const Key& key, bool value) {
-  const auto flat_key_id =
-      storage_.InternString(base::StringView(key.flat_key));
-  const auto key_id = storage_.InternString(base::StringView(key.key));
-  const auto variadic_val = Variadic::Boolean(value);
-  inserter_.AddArg(flat_key_id, key_id, variadic_val);
-}
-
-bool WinscopeArgsParser::AddJson(const Key&, const protozero::ConstChars&) {
-  PERFETTO_FATAL("Unexpected JSON value when parsing SurfaceFlinger data");
-}
-
-void WinscopeArgsParser::AddNull(const Key& key) {
-  const auto flat_key_id =
-      storage_.InternString(base::StringView(key.flat_key));
-  const auto key_id = storage_.InternString(base::StringView(key.key));
-  const auto variadic_val = Variadic::Null();
-  inserter_.AddArg(flat_key_id, key_id, variadic_val);
-}
-
-size_t WinscopeArgsParser::GetArrayEntryIndex(const std::string& array_key) {
-  return inserter_.GetNextArrayEntryIndex(
-      storage_.InternString(base::StringView(array_key)));
-}
-
-size_t WinscopeArgsParser::IncrementArrayEntryIndex(
-    const std::string& array_key) {
-  return inserter_.IncrementArrayEntryIndex(
-      storage_.InternString(base::StringView(array_key)));
-}
-
-PacketSequenceStateGeneration* WinscopeArgsParser::seq_state() {
-  return nullptr;
-}
-
-InternedMessageView* WinscopeArgsParser::GetInternedMessageView(
-    uint32_t field_id,
-    uint64_t iid) {
-  base::ignore_result(field_id);
-  base::ignore_result(iid);
-  return nullptr;
-}
-
-}  // namespace trace_processor
-}  // namespace perfetto
diff --git a/src/trace_processor/importers/proto/winscope/winscope_module.cc b/src/trace_processor/importers/proto/winscope/winscope_module.cc
index 8d7e037..4bf2723 100644
--- a/src/trace_processor/importers/proto/winscope/winscope_module.cc
+++ b/src/trace_processor/importers/proto/winscope/winscope_module.cc
@@ -17,8 +17,8 @@
 #include "src/trace_processor/importers/proto/winscope/winscope_module.h"
 #include "protos/perfetto/trace/android/winscope_extensions.pbzero.h"
 #include "protos/perfetto/trace/android/winscope_extensions_impl.pbzero.h"
+#include "src/trace_processor/importers/proto/args_parser.h"
 #include "src/trace_processor/importers/proto/winscope/winscope.descriptor.h"
-#include "src/trace_processor/importers/proto/winscope/winscope_args_parser.h"
 
 namespace perfetto {
 namespace trace_processor {
@@ -109,7 +109,7 @@
 
   ArgsTracker tracker(context_);
   auto inserter = tracker.AddArgsTo(rowId);
-  WinscopeArgsParser writer(inserter, *context_->storage.get());
+  ArgsParser writer(timestamp, inserter, *context_->storage.get());
   base::Status status =
       args_parser_.ParseMessage(blob, kInputMethodClientsProtoName,
                                 nullptr /* parse all fields */, writer);
@@ -130,7 +130,7 @@
 
   ArgsTracker tracker(context_);
   auto inserter = tracker.AddArgsTo(rowId);
-  WinscopeArgsParser writer(inserter, *context_->storage.get());
+  ArgsParser writer(timestamp, inserter, *context_->storage.get());
   base::Status status =
       args_parser_.ParseMessage(blob, kInputMethodManagerServiceProtoName,
                                 nullptr /* parse all fields */, writer);
@@ -149,7 +149,7 @@
 
   ArgsTracker tracker(context_);
   auto inserter = tracker.AddArgsTo(rowId);
-  WinscopeArgsParser writer(inserter, *context_->storage.get());
+  ArgsParser writer(timestamp, inserter, *context_->storage.get());
   base::Status status =
       args_parser_.ParseMessage(blob, kInputMethodServiceProtoName,
                                 nullptr /* parse all fields */, writer);