ftrace_reader: Move some code for generating the protos into tools/

We put too much code into src/ when refactoring the ftrace format
reader code. This puts some of the stuff we don't really need back
under tools/.

Bug: 71844955
Change-Id: I75cd18c7faedcab7806e83f93238b282341a0a68
diff --git a/Android.bp b/Android.bp
index 868e196..5c7706f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -34,7 +34,6 @@
     "src/ftrace_reader/format_parser.cc",
     "src/ftrace_reader/ftrace_controller.cc",
     "src/ftrace_reader/ftrace_procfs.cc",
-    "src/ftrace_reader/ftrace_to_proto.cc",
     "src/ftrace_reader/proto_translation_table.cc",
     "src/ipc/buffered_frame_deserializer.cc",
     "src/ipc/client_impl.cc",
@@ -774,8 +773,6 @@
     "src/ftrace_reader/ftrace_controller.cc",
     "src/ftrace_reader/ftrace_controller_unittest.cc",
     "src/ftrace_reader/ftrace_procfs.cc",
-    "src/ftrace_reader/ftrace_to_proto.cc",
-    "src/ftrace_reader/ftrace_to_proto_unittest.cc",
     "src/ftrace_reader/proto_translation_table.cc",
     "src/ftrace_reader/proto_translation_table_unittest.cc",
     "src/ftrace_reader/test/scattered_stream_delegate_for_testing.cc",
@@ -822,6 +819,8 @@
     "src/tracing/test/aligned_buffer_test.cc",
     "src/tracing/test/test_shared_memory.cc",
     "src/tracing/test/tracing_integration_test.cc",
+    "tools/ftrace_proto_gen/ftrace_proto_gen.cc",
+    "tools/ftrace_proto_gen/ftrace_proto_gen_unittest.cc",
     "tools/sanitizers_unittests/sanitizers_unittest.cc",
   ],
   shared_libs: [
diff --git a/BUILD.gn b/BUILD.gn
index 2787f6e..7cc1af7 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -52,6 +52,7 @@
     "src/ipc:perfetto_ipc_unittests",
     "src/protozero:protozero_unittests",
     "src/tracing:tracing_unittests",
+    "tools/ftrace_proto_gen:ftrace_proto_gen_unittests",
   ]
   if (!build_with_chromium) {
     deps += [ "tools/sanitizers_unittests" ]
diff --git a/include/perfetto/ftrace_reader/BUILD.gn b/include/perfetto/ftrace_reader/BUILD.gn
index 4547f2f..afa9ebc 100644
--- a/include/perfetto/ftrace_reader/BUILD.gn
+++ b/include/perfetto/ftrace_reader/BUILD.gn
@@ -19,6 +19,5 @@
   sources = [
     "format_parser.h",
     "ftrace_controller.h",
-    "ftrace_to_proto.h",
   ]
 }
diff --git a/include/perfetto/ftrace_reader/format_parser.h b/include/perfetto/ftrace_reader/format_parser.h
index d8eaf1e..4ee0883 100644
--- a/include/perfetto/ftrace_reader/format_parser.h
+++ b/include/perfetto/ftrace_reader/format_parser.h
@@ -17,11 +17,42 @@
 #ifndef INCLUDE_PERFETTO_FTRACE_READER_FORMAT_PARSER_H_
 #define INCLUDE_PERFETTO_FTRACE_READER_FORMAT_PARSER_H_
 
+#include <stdint.h>
 #include <string>
 
+#include <iosfwd>
+#include <iostream>
+#include <string>
+#include <tuple>
+#include <vector>
+
 namespace perfetto {
 
-struct FtraceEvent;
+struct FtraceEvent {
+  struct Field {
+    std::string type_and_name;
+    uint16_t offset;
+    uint16_t size;
+    bool is_signed;
+
+    bool operator==(const Field& other) const {
+      return std::tie(type_and_name, offset, size, is_signed) ==
+             std::tie(other.type_and_name, other.offset, other.size,
+                      other.is_signed);
+    }
+  };
+
+  std::string name;
+  int id;
+  std::vector<Field> common_fields;
+  std::vector<Field> fields;
+};
+
+std::string GetNameFromTypeAndName(const std::string& type_and_name);
+
+// Allow gtest to pretty print FtraceEvent::Field.
+::std::ostream& operator<<(::std::ostream& os, const FtraceEvent::Field&);
+void PrintTo(const FtraceEvent::Field& args, ::std::ostream* os);
 
 bool ParseFtraceEvent(const std::string& input, FtraceEvent* output = nullptr);
 
diff --git a/include/perfetto/ftrace_reader/ftrace_to_proto.h b/include/perfetto/ftrace_reader/ftrace_to_proto.h
deleted file mode 100644
index ec476a5..0000000
--- a/include/perfetto/ftrace_reader/ftrace_to_proto.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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_FTRACE_READER_FTRACE_TO_PROTO_H_
-#define INCLUDE_PERFETTO_FTRACE_READER_FTRACE_TO_PROTO_H_
-
-#include <stdint.h>
-
-#include <iosfwd>
-#include <iostream>
-#include <string>
-#include <tuple>
-#include <vector>
-
-namespace perfetto {
-
-struct FtraceEvent {
-  struct Field {
-    std::string type_and_name;
-    uint16_t offset;
-    uint16_t size;
-    bool is_signed;
-
-    bool operator==(const Field& other) const {
-      return std::tie(type_and_name, offset, size, is_signed) ==
-             std::tie(other.type_and_name, other.offset, other.size,
-                      other.is_signed);
-    }
-  };
-
-  std::string name;
-  int id;
-  std::vector<Field> common_fields;
-  std::vector<Field> fields;
-};
-
-struct Proto {
-  struct Field {
-    std::string type;
-    std::string name;
-    uint32_t number;
-  };
-  std::string name;
-  std::vector<Field> fields;
-
-  std::string ToString();
-};
-
-bool GenerateProto(const FtraceEvent& format, Proto* proto_out);
-std::string InferProtoType(const FtraceEvent::Field& field);
-std::string GetNameFromTypeAndName(const std::string& type_and_name);
-
-// Allow gtest to pretty print FtraceEvent::Field.
-::std::ostream& operator<<(::std::ostream& os, const FtraceEvent::Field&);
-void PrintTo(const FtraceEvent::Field& args, ::std::ostream* os);
-
-}  // namespace perfetto
-
-#endif  // INCLUDE_PERFETTO_FTRACE_READER_FTRACE_TO_PROTO_H_
diff --git a/protos/ftrace/print.proto b/protos/ftrace/print.proto
index bc06016..67bec86 100644
--- a/protos/ftrace/print.proto
+++ b/protos/ftrace/print.proto
@@ -1,4 +1,5 @@
-// Autogenerated by ../../src/ftrace_reader/ftrace_to_proto.cc do not edit.
+// Autogenerated by ../../tools/ftrace_proto_gen/ftrace_proto_gen.cc do not
+// edit.
 syntax = "proto2";
 option optimize_for = LITE_RUNTIME;
 package perfetto.protos;
diff --git a/protos/ftrace/sched_switch.proto b/protos/ftrace/sched_switch.proto
index 8fd4247..490f697 100644
--- a/protos/ftrace/sched_switch.proto
+++ b/protos/ftrace/sched_switch.proto
@@ -1,4 +1,5 @@
-// Autogenerated by ../../src/ftrace_reader/ftrace_to_proto.cc do not edit.
+// Autogenerated by ../../tools/ftrace_proto_gen/ftrace_proto_gen.cc do not
+// edit.
 syntax = "proto2";
 option optimize_for = LITE_RUNTIME;
 package perfetto.protos;
diff --git a/src/ftrace_reader/BUILD.gn b/src/ftrace_reader/BUILD.gn
index 8534419..d81a3de 100644
--- a/src/ftrace_reader/BUILD.gn
+++ b/src/ftrace_reader/BUILD.gn
@@ -44,7 +44,6 @@
     "event_info_unittest.cc",
     "format_parser_unittest.cc",
     "ftrace_controller_unittest.cc",
-    "ftrace_to_proto_unittest.cc",
     "proto_translation_table_unittest.cc",
   ]
 }
@@ -102,7 +101,6 @@
     "ftrace_controller.cc",
     "ftrace_procfs.cc",
     "ftrace_procfs.h",
-    "ftrace_to_proto.cc",
     "proto_translation_table.cc",
     "proto_translation_table.h",
   ]
diff --git a/src/ftrace_reader/format_parser.cc b/src/ftrace_reader/format_parser.cc
index dc38232..a4b4e6c 100644
--- a/src/ftrace_reader/format_parser.cc
+++ b/src/ftrace_reader/format_parser.cc
@@ -21,10 +21,11 @@
 #include <iosfwd>
 #include <iostream>
 #include <memory>
+#include <regex>
+#include <string>
 #include <vector>
 
 #include "perfetto/base/utils.h"
-#include "perfetto/ftrace_reader/ftrace_to_proto.h"
 
 namespace perfetto {
 namespace {
@@ -39,8 +40,45 @@
   return name.compare(0, strlen(kCommonFieldPrefix), kCommonFieldPrefix) == 0;
 }
 
+bool IsCIdentifier(const std::string& s) {
+  for (const char c : s) {
+    if (!(std::isalnum(c) || c == '_'))
+      return false;
+  }
+  return s.size() > 0 && !std::isdigit(s[0]);
+}
+
 }  // namespace
 
+// For example:
+// "int foo" -> "foo"
+// "u8 foo[(int)sizeof(struct blah)]" -> "foo"
+// "char[] foo[16]" -> "foo"
+// "something_went_wrong" -> ""
+// "" -> ""
+std::string GetNameFromTypeAndName(const std::string& type_and_name) {
+  size_t right = type_and_name.size();
+  if (right == 0)
+    return "";
+
+  if (type_and_name[type_and_name.size() - 1] == ']') {
+    right = type_and_name.rfind('[');
+    if (right == std::string::npos)
+      return "";
+  }
+
+  size_t left = type_and_name.rfind(' ', right);
+  if (left == std::string::npos)
+    return "";
+  left++;
+
+  std::string result = type_and_name.substr(left, right - left);
+  if (!IsCIdentifier(result))
+    return "";
+
+  return result;
+}
+
 bool ParseFtraceEvent(const std::string& input, FtraceEvent* output) {
   std::unique_ptr<char[], base::FreeDeleter> input_copy(strdup(input.c_str()));
   char* s = input_copy.get();
diff --git a/src/ftrace_reader/format_parser_unittest.cc b/src/ftrace_reader/format_parser_unittest.cc
index 1ea34b4..a31601c 100644
--- a/src/ftrace_reader/format_parser_unittest.cc
+++ b/src/ftrace_reader/format_parser_unittest.cc
@@ -17,7 +17,6 @@
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "perfetto/ftrace_reader/ftrace_to_proto.h"
 
 namespace perfetto {
 namespace {
@@ -124,5 +123,24 @@
   }
 }
 
+TEST(FtraceEventParser, GetNameFromTypeAndName) {
+  EXPECT_EQ(GetNameFromTypeAndName("int foo"), "foo");
+  EXPECT_EQ(GetNameFromTypeAndName("int foo_bar"), "foo_bar");
+  EXPECT_EQ(GetNameFromTypeAndName("const char * foo"), "foo");
+  EXPECT_EQ(GetNameFromTypeAndName("const char foo[64]"), "foo");
+  EXPECT_EQ(GetNameFromTypeAndName("char[] foo[16]"), "foo");
+  EXPECT_EQ(GetNameFromTypeAndName("u8 foo[(int)sizeof(struct blah)]"), "foo");
+
+  EXPECT_EQ(GetNameFromTypeAndName(""), "");
+  EXPECT_EQ(GetNameFromTypeAndName("]"), "");
+  EXPECT_EQ(GetNameFromTypeAndName("["), "");
+  EXPECT_EQ(GetNameFromTypeAndName(" "), "");
+  EXPECT_EQ(GetNameFromTypeAndName(" []"), "");
+  EXPECT_EQ(GetNameFromTypeAndName(" ]["), "");
+  EXPECT_EQ(GetNameFromTypeAndName("char"), "");
+  EXPECT_EQ(GetNameFromTypeAndName("char *"), "");
+  EXPECT_EQ(GetNameFromTypeAndName("char 42"), "");
+}
+
 }  // namespace
 }  // namespace perfetto
diff --git a/src/ftrace_reader/proto_translation_table.cc b/src/ftrace_reader/proto_translation_table.cc
index 9a88888..53973ca 100644
--- a/src/ftrace_reader/proto_translation_table.cc
+++ b/src/ftrace_reader/proto_translation_table.cc
@@ -22,7 +22,6 @@
 #include "event_info.h"
 #include "ftrace_procfs.h"
 #include "perfetto/ftrace_reader/format_parser.h"
-#include "perfetto/ftrace_reader/ftrace_to_proto.h"
 
 #include "protos/ftrace/ftrace_event_bundle.pbzero.h"
 
@@ -108,7 +107,7 @@
 
 }  // namespace
 
-// This is similar but different from InferProtoType (see ftrace_to_proto.cc).
+// This is similar but different from InferProtoType (see format_parser.cc).
 // TODO(hjd): Fold FtraceEvent(::Field) into Event.
 bool InferFtraceType(const std::string& type_and_name,
                      size_t size,
diff --git a/tools/ftrace_proto_gen/BUILD.gn b/tools/ftrace_proto_gen/BUILD.gn
index 49d50b7..11502e3 100644
--- a/tools/ftrace_proto_gen/BUILD.gn
+++ b/tools/ftrace_proto_gen/BUILD.gn
@@ -12,11 +12,36 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+source_set("ftrace_proto_gen_unittests") {
+  testonly = true
+  deps = [
+    ":ftrace_proto_gen_src",
+    "../../gn:default_deps",
+    "../../gn:gtest_deps",
+  ]
+  sources = [
+    "ftrace_proto_gen_unittest.cc",
+  ]
+}
+
+source_set("ftrace_proto_gen_src") {
+  sources = [
+    "ftrace_proto_gen.cc",
+    "ftrace_proto_gen.h",
+  ]
+  deps = [
+    "../../gn:default_deps",
+    "../../src/base",
+    "../../src/ftrace_reader",
+  ]
+}
+
 executable("ftrace_proto_gen") {
   sources = [
     "main.cc",
   ]
   deps = [
+    ":ftrace_proto_gen_src",
     "../../gn:default_deps",
     "../../src/base",
     "../../src/ftrace_reader",
diff --git a/src/ftrace_reader/ftrace_to_proto.cc b/tools/ftrace_proto_gen/ftrace_proto_gen.cc
similarity index 75%
rename from src/ftrace_reader/ftrace_to_proto.cc
rename to tools/ftrace_proto_gen/ftrace_proto_gen.cc
index 344ea8f..e918a6c 100644
--- a/src/ftrace_reader/ftrace_to_proto.cc
+++ b/tools/ftrace_proto_gen/ftrace_proto_gen.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -14,24 +14,15 @@
  * limitations under the License.
  */
 
-#include "perfetto/ftrace_reader/ftrace_to_proto.h"
+#include "ftrace_proto_gen.h"
 
 #include <regex>
 #include <set>
-#include <sstream>
 #include <string>
-#include <vector>
 
 namespace perfetto {
-namespace {
 
-bool IsCIdentifier(const std::string& s) {
-  for (const char c : s) {
-    if (!(std::isalnum(c) || c == '_'))
-      return false;
-  }
-  return s.size() > 0 && !std::isdigit(s[0]);
-}
+namespace {
 
 std::string ToCamelCase(const std::string& s) {
   std::string result;
@@ -58,35 +49,6 @@
 
 }  // namespace
 
-// For example:
-// "int foo" -> "foo"
-// "u8 foo[(int)sizeof(struct blah)]" -> "foo"
-// "char[] foo[16]" -> "foo"
-// "something_went_wrong" -> ""
-// "" -> ""
-std::string GetNameFromTypeAndName(const std::string& type_and_name) {
-  size_t right = type_and_name.size();
-  if (right == 0)
-    return "";
-
-  if (type_and_name[type_and_name.size() - 1] == ']') {
-    right = type_and_name.rfind('[');
-    if (right == std::string::npos)
-      return "";
-  }
-
-  size_t left = type_and_name.rfind(' ', right);
-  if (left == std::string::npos)
-    return "";
-  left++;
-
-  std::string result = type_and_name.substr(left, right - left);
-  if (!IsCIdentifier(result))
-    return "";
-
-  return result;
-}
-
 std::string InferProtoType(const FtraceEvent::Field& field) {
   // Fixed length strings: "char foo[16]"
   if (std::regex_match(field.type_and_name, std::regex(R"(char \w+\[\d+\])")))
diff --git a/tools/ftrace_proto_gen/ftrace_proto_gen.h b/tools/ftrace_proto_gen/ftrace_proto_gen.h
new file mode 100644
index 0000000..67fac85
--- /dev/null
+++ b/tools/ftrace_proto_gen/ftrace_proto_gen.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string>
+#include <vector>
+
+#include "perfetto/ftrace_reader/format_parser.h"
+
+namespace perfetto {
+
+struct Proto {
+  struct Field {
+    std::string type;
+    std::string name;
+    uint32_t number;
+  };
+  std::string name;
+  std::vector<Field> fields;
+
+  std::string ToString();
+};
+
+std::string ToString(const Proto& proto);
+bool GenerateProto(const FtraceEvent& format, Proto* proto_out);
+std::string InferProtoType(const FtraceEvent::Field& field);
+
+}  // namespace perfetto
diff --git a/src/ftrace_reader/ftrace_to_proto_unittest.cc b/tools/ftrace_proto_gen/ftrace_proto_gen_unittest.cc
similarity index 61%
rename from src/ftrace_reader/ftrace_to_proto_unittest.cc
rename to tools/ftrace_proto_gen/ftrace_proto_gen_unittest.cc
index 724b028..cbe295e 100644
--- a/src/ftrace_reader/ftrace_to_proto_unittest.cc
+++ b/tools/ftrace_proto_gen/ftrace_proto_gen_unittest.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * 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.
@@ -14,31 +14,12 @@
  * limitations under the License.
  */
 
-#include "perfetto/ftrace_reader/ftrace_to_proto.h"
+#include "ftrace_proto_gen.h"
 #include "gtest/gtest.h"
 
 namespace perfetto {
 namespace {
 
-TEST(FtraceEventParser, GetNameFromTypeAndName) {
-  EXPECT_EQ(GetNameFromTypeAndName("int foo"), "foo");
-  EXPECT_EQ(GetNameFromTypeAndName("int foo_bar"), "foo_bar");
-  EXPECT_EQ(GetNameFromTypeAndName("const char * foo"), "foo");
-  EXPECT_EQ(GetNameFromTypeAndName("const char foo[64]"), "foo");
-  EXPECT_EQ(GetNameFromTypeAndName("char[] foo[16]"), "foo");
-  EXPECT_EQ(GetNameFromTypeAndName("u8 foo[(int)sizeof(struct blah)]"), "foo");
-
-  EXPECT_EQ(GetNameFromTypeAndName(""), "");
-  EXPECT_EQ(GetNameFromTypeAndName("]"), "");
-  EXPECT_EQ(GetNameFromTypeAndName("["), "");
-  EXPECT_EQ(GetNameFromTypeAndName(" "), "");
-  EXPECT_EQ(GetNameFromTypeAndName(" []"), "");
-  EXPECT_EQ(GetNameFromTypeAndName(" ]["), "");
-  EXPECT_EQ(GetNameFromTypeAndName("char"), "");
-  EXPECT_EQ(GetNameFromTypeAndName("char *"), "");
-  EXPECT_EQ(GetNameFromTypeAndName("char 42"), "");
-}
-
 TEST(FtraceEventParser, InferProtoType) {
   using Field = FtraceEvent::Field;
   EXPECT_EQ(InferProtoType(Field{"char * foo", 2, 0, false}), "string");
diff --git a/tools/ftrace_proto_gen/main.cc b/tools/ftrace_proto_gen/main.cc
index 506160c..b2e8b9f 100644
--- a/tools/ftrace_proto_gen/main.cc
+++ b/tools/ftrace_proto_gen/main.cc
@@ -19,8 +19,8 @@
 #include <sstream>
 #include <string>
 
+#include "ftrace_proto_gen.h"
 #include "perfetto/ftrace_reader/format_parser.h"
-#include "perfetto/ftrace_reader/ftrace_to_proto.h"
 
 int main(int argc, const char** argv) {
   if (argc != 3) {