tp: cleanup and reorganize docs

Change-Id: I4a5f118777b80b87e56ea9f04bae079a4a6cfe62
diff --git a/docs/toc.md b/docs/toc.md
index 0ed6a88..450e4dd 100644
--- a/docs/toc.md
+++ b/docs/toc.md
@@ -41,21 +41,20 @@
 
 * [Trace analysis](#)
   * [Trace Processor](analysis/trace-processor.md)
-  * [PerfettoSQL Syntax](analysis/perfetto-sql-syntax.md)
   * [PerfettoSQL Standard Library](analysis/stdlib-docs.autogen)
-  * [PerfettoSQL Tables](analysis/sql-tables.autogen)
-  * [PerfettoSQL Built-ins](analysis/builtin.md)
+  * [PerfettoSQL Syntax](analysis/perfetto-sql-syntax.md)
+  * [PerfettoSQL Prelude](analysis/sql-tables.autogen)
   * [PerfettoSQL Common Queries](analysis/common-queries.md)
+  * [PerfettoSQL Built-ins](analysis/builtin.md)
   * [Trace-based metrics](analysis/metrics.md)
   * [Batch Trace Processor](analysis/batch-trace-processor.md)
-  * [Stats table](analysis/sql-stats.autogen)
-  * [Pivot tables](analysis/pivot-tables.md)
 
 * [Trace visualization](#)
   * [Perfetto UI](visualization/perfetto-ui.md)
   * [Visualising large traces](visualization/large-traces.md)
   * [Deep linking to Perfetto UI](visualization/deep-linking-to-perfetto-ui.md)
   * [Perfetto UI release process](visualization/perfetto-ui-release-process.md)
+  * [Pivot tables](analysis/pivot-tables.md)
 
 * [Core concepts](#)
   * [Trace configuration](concepts/config.md)
@@ -71,6 +70,7 @@
   * [heap_profile cmdline](reference/heap_profile-cli.md)
   * [Synthetic TrackEvent](reference/synthetic-track-event.md)
   * [Android Version Notes](reference/android-version-notes.md)
+  * [Stats table](analysis/sql-stats.autogen)
 
 * [Contributing](#)
     * [Getting started](contributing/getting-started.md)
diff --git a/infra/perfetto.dev/src/gen_sql_tables_reference.js b/infra/perfetto.dev/src/gen_sql_tables_reference.js
index 72800b5..5dbaca3 100644
--- a/infra/perfetto.dev/src/gen_sql_tables_reference.js
+++ b/infra/perfetto.dev/src/gen_sql_tables_reference.js
@@ -31,180 +31,10 @@
   return comment;
 }
 
-// Returns an object describing the table as follows:
-// { name: 'HeapGraphObjectTable',
-//   cols: [ {name: 'upid',            type: 'uint32_t', optional: false },
-//           {name: 'graph_sample_ts', type: 'int64_t',  optional: false },
-function parseTableDef(tableDefName, tableDef) {
-  const tableDesc = {
-    name: '',                // The SQL table name, e.g. stack_profile_mapping.
-    cppClassName: '',        // e.g., StackProfileMappingTable.
-    defMacro: tableDefName,  // e.g., PERFETTO_TP_STACK_PROFILE_MAPPING_DEF.
-    comment: '',
-    parent: undefined,   // Will be filled afterwards in the resolution phase.
-    parentDefName: '',   // e.g., PERFETTO_TP_STACK_PROFILE_MAPPING_DEF.
-    tablegroup: 'Misc',  // From @tablegroup in comments.
-    cols: {},
-  };
-  const getOrCreateColumn = (name) => {
-    if (name in tableDesc.cols)
-      return tableDesc.cols[name];
-    tableDesc.cols[name] = {
-      name: name,
-      type: '',
-      comment: '',
-      optional: false,
-      refTableCppName: undefined,
-      joinTable: undefined,
-      joinCol: undefined,
-    };
-    return tableDesc.cols[name];
-  };
-
-  // Reserve the id and type columns so they appear first in the column list
-  // They will only be kept in case this is a root table - otherwise they will
-  // be deleted below..
-  const id = getOrCreateColumn('id');
-  const type = getOrCreateColumn('type');
-
-  let lastColumn = undefined;
-  for (const line of tableDef.split('\n')) {
-    if (line.startsWith('#define'))
-      continue;  // Skip the first line.
-    let m;
-    if (line.startsWith('//')) {
-      let comm = line.replace(/^\s*\/\/\s*/, '');
-      if (m = comm.match(/@tablegroup (.*)/)) {
-        tableDesc.tablegroup = m[1];
-        continue;
-      }
-      if (m = comm.match(/@name (\w+)/)) {
-        tableDesc.name = m[1];
-        continue;
-      }
-      if (m = comm.match(/@param\s+([^ ]+)\s*({\w+})?\s*(.*)/)) {
-        lastColumn = getOrCreateColumn(/*name=*/ m[1]);
-        lastColumn.type = (m[2] || '').replace(/(^{)|(}$)/g, '');
-        lastColumn.comment = m[3];
-        continue;
-      }
-      if (lastColumn === undefined) {
-        tableDesc.comment += `${comm}\n`;
-      } else {
-        lastColumn.comment = `${lastColumn.comment}\n${comm}`;
-      }
-      continue;
-    }
-    if (m = line.match(/^\s*NAME\((\w+)\s*,\s*"(\w+)"/)) {
-      tableDesc.cppClassName = m[1];
-      if (tableDesc.name === '') {
-        tableDesc.name = m[2];  // Set only if not overridden by @name.
-      }
-      continue;
-    }
-    if (m = line.match(/(PERFETTO_TP_ROOT_TABLE|PARENT)\((\w+)/)) {
-      if (m[1] === 'PARENT') {
-        tableDesc.parentDefName = m[2];
-      }
-      continue;
-    }
-    if (m = line.match(/^\s*C\(([^,]+)\s*,\s*(\w+)/)) {
-      const col = getOrCreateColumn(/*name=*/ m[2]);
-      col.type = m[1];
-      if (m = col.type.match(/std::optional<(.*)>/)) {
-        col.type = m[1];
-        col.optional = true;
-      }
-      if (col.type === 'StringPool::Id') {
-        col.type = 'string';
-      }
-      const sep = col.type.indexOf('::');
-      if (sep > 0) {
-        col.refTableCppName = col.type.substr(0, sep);
-      }
-      continue;
-    }
-    throw new Error(`Cannot parse line "${line}" from ${tableDefName}`);
-  }
-
-  if (tableDesc.parentDefName === '') {
-    id.type = `${tableDesc.cppClassName}::Id`;
-    type.type = 'string';
-  } else {
-    delete tableDesc.cols['id'];
-    delete tableDesc.cols['type'];
-  }
-
-  // Process {@joinable xxx} annotations.
-  const regex = /\s?\{@joinable\s*(\w+)\.(\w+)\s*\}/;
-  for (const col of Object.values(tableDesc.cols)) {
-    const m = col.comment.match(regex)
-    if (m) {
-      col.joinTable = m[1];
-      col.joinCol = m[2];
-      col.comment = col.comment.replace(regex, '');
-    }
-  }
-  return tableDesc;
-}
-
-
-function parseTablesInCppFile(filePath) {
-  const hdr = fs.readFileSync(filePath, 'UTF8');
-  const regex = /^\s*PERFETTO_TP_TABLE\((\w+)\)/mg;
-  let match = regex.exec(hdr);
-  const tables = [];
-  while (match != null) {
-    const tableDefName = match[1];
-    match = regex.exec(hdr);
-
-    // Now let's extract the table definition, that looks like this:
-    // // Some
-    // // Multiline
-    // // Comment
-    // #define PERFETTO_TP_STACK_PROFILE_FRAME_DEF(NAME, PARENT, C) \
-    // NAME(StackProfileFrameTable, "stack_profile_frame")        \
-    // PERFETTO_TP_ROOT_TABLE(PARENT, C)                          \
-    // C(StringPool::Id, name)                                    \
-    // C(StackProfileMappingTable::Id, mapping)                   \
-    // C(int64_t, rel_pc)                                         \
-    // C(std::optional<uint32_t>, symbol_set_id)
-    //
-    // Where PERFETTO_TP_STACK_PROFILE_FRAME_DEF is |tableDefName|.
-    let pattern = `(^[ ]*//.*\n)*`;
-    pattern += `^\s*#define\\s+${tableDefName}\\s*\\(`;
-    pattern += `(.*\\\\\\s*\n)+`;
-    pattern += `.+`;
-    const r = new RegExp(pattern, 'mi');
-    const tabMatch = r.exec(hdr);
-    if (!tabMatch) {
-      console.error(`could not find table ${tableDefName}`);
-      continue;
-    }
-    tables.push(parseTableDef(tableDefName, tabMatch[0]));
-  }
-  return tables;
-}
-
 function parseTablesInJson(filePath) {
   return JSON.parse(fs.readFileSync(filePath, 'UTF8'));
 }
 
-function overrideCppTablesWithJsonTables(cpp, json) {
-  const out = [];
-  const jsonAdded = new Set();
-  for (const table of json) {
-    out.push(table);
-    jsonAdded.add(table.name);
-  }
-  for (const table of cpp) {
-    if (!jsonAdded.has(table.name)) {
-      out.push(table);
-    }
-  }
-  return out;
-}
-
 function genLink(table) {
   return `[${table.name}](#${table.name})`;
 }
@@ -239,31 +69,24 @@
 }
 
 function main() {
-  const inFile = argv['i'];
   const outFile = argv['o'];
   const jsonFile = argv['j'];
-  if (!inFile) {
-    console.error('Usage: -i hdr1.h -i hdr2.h -j tbls.json -[-o out.md]');
+  if (!jsonFile) {
+    console.error('Usage: -j tbls.json -[-o out.md]');
     process.exit(1);
   }
 
-  // Can be either a string (-i single) or an array (-i one -i two).
-  const inFiles = (inFile instanceof Array) ? inFile : [inFile];
-  const cppTables =
-      Array.prototype.concat(...inFiles.map(parseTablesInCppFile));
-
   // Can be either a string (-j single) or an array (-j one -j two).
   const jsonFiles = (jsonFile instanceof Array) ? jsonFile : [jsonFile];
   const jsonTables =
       Array.prototype.concat(...jsonFiles.map(parseTablesInJson));
-  const tables = overrideCppTablesWithJsonTables(cppTables, jsonTables)
 
   // Resolve parents.
   const tablesIndex = {};    // 'TP_SCHED_SLICE_TABLE_DEF' -> table
   const tablesByGroup = {};  // 'profilers' => [table1, table2]
   const tablesCppName = {};  // 'StackProfileMappingTable' => table
   const tablesByName = {};   // 'profile_mapping' => table
-  for (const table of tables) {
+  for (const table of jsonTables) {
     tablesIndex[table.defMacro] = table;
     if (tablesByGroup[table.tablegroup] === undefined) {
       tablesByGroup[table.tablegroup] = [];
@@ -279,7 +102,7 @@
     return a.localeCompare(b);
   });
 
-  for (const table of tables) {
+  for (const table of jsonTables) {
     if (table.parentDefName) {
       table.parent = tablesIndex[table.parentDefName];
     }
@@ -325,7 +148,7 @@
     graph += '\n```\n';
   }
 
-  let title = '# PerfettoSQL Tables\n'
+  let title = '# PerfettoSQL Prelude\n'
   let md = title + graph;
   for (const tableGroup of tableGroups) {
     md += `## ${tableGroup}\n`
diff --git a/infra/perfetto.dev/src/gen_stdlib_docs_md.py b/infra/perfetto.dev/src/gen_stdlib_docs_md.py
index 7959053..c82f641 100644
--- a/infra/perfetto.dev/src/gen_stdlib_docs_md.py
+++ b/infra/perfetto.dev/src/gen_stdlib_docs_md.py
@@ -29,9 +29,9 @@
   def __init__(self, module_name: str, module_files: List[Dict[str,
                                                                Any]]) -> None:
     self.module_name = module_name
-    self.files_md = [
+    self.files_md = sorted([
         FileMd(module_name, file_dict) for file_dict in module_files
-    ]
+    ], key=lambda x: x.import_key)
     self.summary_objs = '\n'.join(
         file.summary_objs for file in self.files_md if file.summary_objs)
     self.summary_funs = '\n'.join(
@@ -41,10 +41,16 @@
                                        if file.summary_view_funs)
 
   def print_description(self):
+    if not self.files_md:
+      return ''
+
     long_s = []
     long_s.append(f'## Module: {self.module_name}')
 
     for file in self.files_md:
+      if not file.objs and not file.funs and not file.view_funs:
+        continue
+
       long_s.append(f'### {file.import_key}')
       if file.objs:
         long_s.append('#### Views/Tables')