• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (C) 2022 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15from typing import List
16from typing import Optional
17
18from python.generators.trace_processor_table.public import Alias
19from python.generators.trace_processor_table.public import ColumnFlag
20from python.generators.trace_processor_table.util import ParsedTable
21from python.generators.trace_processor_table.util import ParsedColumn
22from python.generators.trace_processor_table.util import data_layer_type
23from python.generators.trace_processor_table.util import parse_type
24from python.generators.trace_processor_table.util import typed_column_type
25
26
27class ColumnSerializer:
28  """Functions for serializing a single Column in a table into C++."""
29
30  def __init__(self, table: ParsedTable, column: ParsedColumn, col_index: int):
31    self.col_index = col_index
32    self.parsed_col = column
33    self.col = self.parsed_col.column
34    self.name = self.col.name
35    self.flags = self.col.flags
36
37    parsed_type = parse_type(table.table, self.col.type)
38
39    self.typed_column_type = typed_column_type(table.table, self.parsed_col)
40    self.cpp_type = parsed_type.cpp_type_with_optionality()
41    self.data_layer_type = data_layer_type(table.table, self.parsed_col)
42
43    self.is_implicit_id = self.parsed_col.is_implicit_id
44    self.is_implicit_type = self.parsed_col.is_implicit_type
45    self.is_ancestor = self.parsed_col.is_ancestor
46    self.is_string = parsed_type.cpp_type == 'StringPool::Id'
47    self.is_optional = parsed_type.is_optional
48
49  def colindex(self) -> str:
50    return f'    static constexpr uint32_t {self.name} = {self.col_index};'
51
52  def coltype_enum(self) -> str:
53    return f'    using {self.name} = {self.typed_column_type};'
54
55  def row_field(self) -> Optional[str]:
56    if self.is_implicit_id or self.is_implicit_type:
57      return None
58    if self.is_ancestor:
59      return None
60    return f'    {self.cpp_type} {self.name};'
61
62  def row_param(self) -> Optional[str]:
63    if self.is_implicit_id or self.is_implicit_type:
64      return None
65    return f'{self.cpp_type} in_{self.name} = {{}}'
66
67  def parent_row_initializer(self) -> Optional[str]:
68    if self.is_implicit_id or self.is_implicit_type:
69      return None
70    if not self.is_ancestor:
71      return None
72    return f'in_{self.name}'
73
74  def row_initializer(self) -> Optional[str]:
75    if self.is_implicit_id or self.is_implicit_type:
76      return None
77    if self.is_ancestor:
78      return None
79    return f'{self.name}(in_{self.name})'
80
81  def const_row_ref_getter(self) -> Optional[str]:
82    return f'''ColumnType::{self.name}::type {self.name}() const {{
83      return table_->{self.name}()[row_number_];
84    }}'''
85
86  def row_ref_getter(self) -> Optional[str]:
87    if self.is_implicit_id or self.is_implicit_type:
88      return None
89    return f'''void set_{self.name}(
90        ColumnType::{self.name}::non_optional_type v) {{
91      return mutable_table()->mutable_{self.name}()->Set(row_number_, v);
92    }}'''
93
94  def flag(self) -> Optional[str]:
95    if self.is_implicit_id or self.is_implicit_type:
96      return None
97    if self.is_ancestor:
98      return None
99    default = f'ColumnType::{self.name}::default_flags()'
100    if self.flags == ColumnFlag.NONE:
101      flags = default
102    else:
103      flags = f'static_cast<uint32_t>({to_cpp_flags(self.flags)}) | {default}'
104    return f'''
105    static constexpr uint32_t {self.name} = {flags};
106    '''
107
108  def storage_init(self) -> Optional[str]:
109    if self.is_implicit_id or self.is_implicit_type:
110      return None
111    if self.is_ancestor:
112      return None
113
114    storage = f'ColumnStorage<ColumnType::{self.name}::stored_type>'
115    dense = str(ColumnFlag.DENSE in self.flags).lower()
116    return f'''{self.name}_({storage}::Create<{dense}>())'''
117
118  def column_init(self) -> Optional[str]:
119    if self.is_implicit_id or self.is_implicit_type:
120      return None
121    if self.is_ancestor:
122      return None
123    return f'''
124    AddColumnToVector(columns, "{self.name}", &self->{self.name}_, ColumnFlag::{self.name},
125                      static_cast<uint32_t>(columns.size()), olay_idx);
126    '''
127
128  def shrink_to_fit(self) -> Optional[str]:
129    if self.is_implicit_id:
130      return None
131    if self.is_ancestor:
132      return None
133    return f'    {self.name}_.ShrinkToFit();'
134
135  def append(self) -> Optional[str]:
136    if self.is_implicit_id or self.is_implicit_type:
137      return None
138    if self.is_ancestor:
139      return None
140    return f'    mutable_{self.name}()->Append(row.{self.name});'
141
142  def accessor(self) -> Optional[str]:
143    inner = f'columns()[ColumnIndex::{self.name}]'
144    return f'''
145  const {self.typed_column_type}& {self.name}() const {{
146    return static_cast<const ColumnType::{self.name}&>({inner});
147  }}
148  '''
149
150  def mutable_accessor(self) -> Optional[str]:
151    if self.is_implicit_id or self.is_implicit_type:
152      return None
153    return f'''
154  {self.typed_column_type}* mutable_{self.name}() {{
155    return static_cast<ColumnType::{self.name}*>(
156        GetColumn(ColumnIndex::{self.name}));
157  }}
158  '''
159
160  def storage(self) -> Optional[str]:
161    if self.is_implicit_id or self.is_implicit_type:
162      return None
163    if self.is_ancestor:
164      return None
165    name = self.name
166    return f'  ColumnStorage<ColumnType::{name}::stored_type> {name}_;'
167
168  def iterator_getter(self) -> Optional[str]:
169    name = self.name
170    return f'''
171    ColumnType::{self.name}::type {name}() const {{
172      const auto& col = table_->{name}();
173      return col.GetAtIdx(
174        iterator_.StorageIndexForColumn(col.index_in_table()));
175    }}
176    '''
177
178  def iterator_setter(self) -> Optional[str]:
179    if self.is_implicit_id or self.is_implicit_type:
180      return None
181    return f'''
182      void set_{self.name}(ColumnType::{self.name}::non_optional_type v) {{
183        auto* col = mutable_table_->mutable_{self.name}();
184        col->SetAtIdx(
185          iterator_.StorageIndexForColumn(col->index_in_table()), v);
186      }}
187    '''
188
189  def static_schema(self) -> Optional[str]:
190    if self.is_implicit_id or self.is_implicit_type:
191      return None
192    return f'''
193    schema.columns.emplace_back(Table::Schema::Column{{
194        "{self.name}", ColumnType::{self.name}::SqlValueType(), false,
195        {str(ColumnFlag.SORTED in self.flags).lower()},
196        {str(ColumnFlag.HIDDEN in self.flags).lower()},
197        {str(ColumnFlag.SET_ID in self.flags).lower()}}});
198    '''
199
200  def row_eq(self) -> Optional[str]:
201    if self.is_implicit_id or self.is_implicit_type:
202      return None
203    return f'ColumnType::{self.name}::Equals({self.name}, other.{self.name})'
204
205  def extend_parent_param(self) -> Optional[str]:
206    if self.is_implicit_id or self.is_implicit_type:
207      return None
208    if self.is_ancestor:
209      return None
210    return f'ColumnStorage<ColumnType::{self.name}::stored_type> {self.name}'
211
212  def extend_parent_param_arg(self) -> Optional[str]:
213    if self.is_implicit_id or self.is_implicit_type:
214      return None
215    if self.is_ancestor:
216      return None
217    return f'std::move({self.name})'
218
219  def static_assert_flags(self) -> Optional[str]:
220    if self.is_implicit_id or self.is_implicit_type:
221      return None
222    if self.is_ancestor:
223      return None
224    return f'''
225      static_assert(
226        ColumnLegacy::IsFlagsAndTypeValid<ColumnType::{self.name}::stored_type>(
227          ColumnFlag::{self.name}),
228        "Column type and flag combination is not valid");
229    '''
230
231  def extend_nullable_vector(self) -> Optional[str]:
232    if self.is_implicit_id or self.is_implicit_type:
233      return None
234    if self.is_ancestor:
235      return None
236    return f'''
237    PERFETTO_DCHECK({self.name}.size() == parent_overlay.size());
238    {self.name}_ = std::move({self.name});
239    '''
240
241  def storage_layer(self) -> Optional[str]:
242    if self.is_ancestor:
243      return None
244    return f'''
245  RefPtr<column::DataLayer> {self.name}_storage_layer_;
246  '''
247
248  def null_layer(self) -> Optional[str]:
249    if self.is_ancestor:
250      return None
251    if not self.is_optional or self.is_string:
252      return f''
253    return f'''
254  RefPtr<column::DataLayer> {self.name}_null_layer_;
255  '''
256
257  def storage_layer_create(self) -> str:
258    if self.is_ancestor:
259      return f'''const_parent_->storage_layers()[ColumnIndex::{self.name}]'''
260    return f'''{self.name}_storage_layer_'''
261
262  def null_layer_create(self) -> str:
263    if not self.is_optional or self.is_string:
264      return f'{{}}'
265    if self.is_ancestor:
266      return f'''const_parent_->null_layers()[ColumnIndex::{self.name}]'''
267    return f'''{self.name}_null_layer_'''
268
269  def storage_layer_init(self) -> str:
270    if self.is_ancestor:
271      return f''
272    if self.is_implicit_id:
273      return f'{self.name}_storage_layer_(new column::IdStorage())'
274    if self.is_string:
275      return f'''{self.name}_storage_layer_(
276          new column::StringStorage(string_pool(), &{self.name}_.vector()))'''
277    if ColumnFlag.SET_ID in self.flags:
278      return f'''{self.name}_storage_layer_(
279          new column::SetIdStorage(&{self.name}_.vector()))'''
280    if self.is_optional:
281      return f'''{self.name}_storage_layer_(
282          new column::NumericStorage<ColumnType::{self.name}::non_optional_stored_type>(
283            &{self.name}_.non_null_vector(),
284            ColumnTypeHelper<ColumnType::{self.name}::stored_type>::ToColumnType(),
285            {str(ColumnFlag.SORTED in self.flags).lower()}))'''
286    return f'''{self.name}_storage_layer_(
287        new column::NumericStorage<ColumnType::{self.name}::non_optional_stored_type>(
288          &{self.name}_.vector(),
289          ColumnTypeHelper<ColumnType::{self.name}::stored_type>::ToColumnType(),
290          {str(ColumnFlag.SORTED in self.flags).lower()}))'''
291
292  def null_layer_init(self) -> str:
293    if self.is_ancestor:
294      return f''
295    if not self.is_optional or self.is_string:
296      return f''
297    if ColumnFlag.DENSE in self.flags:
298      return f'''{self.name}_null_layer_(new column::DenseNullOverlay({self.name}_.bv()))'''
299    return f'''{self.name}_null_layer_(new column::NullOverlay({self.name}_.bv()))'''
300
301
302class TableSerializer(object):
303  """Functions for seralizing a single Table into C++."""
304
305  def __init__(self, parsed: ParsedTable):
306    self.table = parsed.table
307    self.table_name = parsed.table.class_name
308    self.column_serializers = []
309
310    if parsed.table.parent:
311      self.parent_class_name = parsed.table.parent.class_name
312    else:
313      self.parent_class_name = 'macros_internal::RootParentTable'
314
315    self.column_serializers = []
316    for c in parsed.columns:
317      # Aliases should be ignored as they are handled in SQL currently.
318      if isinstance(c.column.type, Alias):
319        continue
320      self.column_serializers.append(
321          ColumnSerializer(parsed, c, len(self.column_serializers)))
322
323  def foreach_col(self, serialize_fn, delimiter='\n') -> str:
324    lines = []
325    for c in self.column_serializers:
326      serialized = serialize_fn(c)
327      if serialized:
328        lines.append(serialized.lstrip('\n').rstrip())
329    return delimiter.join(lines).strip()
330
331  def id_defn(self) -> str:
332    if self.table.parent:
333      return f'''
334  using Id = {self.table.parent.class_name}::Id;
335    '''
336    return '''
337  struct Id : public BaseId {
338    Id() = default;
339    explicit constexpr Id(uint32_t v) : BaseId(v) {}
340  };
341  static_assert(std::is_trivially_destructible_v<Id>,
342                "Inheritance used without trivial destruction");
343    '''
344
345  def row_struct(self) -> str:
346    param = self.foreach_col(
347        ColumnSerializer.row_param, delimiter=',\n        ')
348    parent_row_init = self.foreach_col(
349        ColumnSerializer.parent_row_initializer, delimiter=', ')
350    row_init = self.foreach_col(
351        ColumnSerializer.row_initializer, delimiter=',\n          ')
352    parent_separator = ',' if row_init else ''
353    row_eq = self.foreach_col(ColumnSerializer.row_eq, delimiter=' &&\n       ')
354    return f'''
355  struct Row : public {self.parent_class_name}::Row {{
356    Row({param},
357        std::nullptr_t = nullptr)
358        : {self.parent_class_name}::Row({parent_row_init}){parent_separator}
359          {row_init} {{
360      type_ = "{self.table.sql_name}";
361    }}
362    {self.foreach_col(ColumnSerializer.row_field)}
363
364    bool operator==(const {self.table_name}::Row& other) const {{
365      return type() == other.type() && {row_eq};
366    }}
367  }};
368    '''
369
370  def const_row_reference_struct(self) -> str:
371    row_ref_getters = self.foreach_col(
372        ColumnSerializer.const_row_ref_getter, delimiter='\n    ')
373    return f'''
374  class ConstRowReference : public macros_internal::AbstractConstRowReference<
375    {self.table_name}, RowNumber> {{
376   public:
377    ConstRowReference(const {self.table_name}* table, uint32_t row_number)
378        : AbstractConstRowReference(table, row_number) {{}}
379
380    {row_ref_getters}
381  }};
382  static_assert(std::is_trivially_destructible_v<ConstRowReference>,
383                "Inheritance used without trivial destruction");
384    '''
385
386  def row_reference_struct(self) -> str:
387    row_ref_getters = self.foreach_col(
388        ColumnSerializer.row_ref_getter, delimiter='\n    ')
389    return f'''
390  class RowReference : public ConstRowReference {{
391   public:
392    RowReference(const {self.table_name}* table, uint32_t row_number)
393        : ConstRowReference(table, row_number) {{}}
394
395    {row_ref_getters}
396
397   private:
398    {self.table_name}* mutable_table() const {{
399      return const_cast<{self.table_name}*>(table_);
400    }}
401  }};
402  static_assert(std::is_trivially_destructible_v<RowReference>,
403                "Inheritance used without trivial destruction");
404    '''
405
406  def constructor(self) -> str:
407    storage_init = self.foreach_col(
408        ColumnSerializer.storage_init, delimiter=',\n        ')
409    storage_layer_init = self.foreach_col(
410        ColumnSerializer.storage_layer_init, delimiter=',\n        ')
411    storage_layer_sep = '\n,' if storage_layer_init else ''
412    null_layer_init = self.foreach_col(
413        ColumnSerializer.null_layer_init, delimiter=',\n        ')
414    null_layer_sep = '\n,' if null_layer_init else ''
415    if self.table.parent:
416      parent_param = f', {self.parent_class_name}* parent'
417      parent_arg = 'parent'
418      parent_init = 'parent_(parent), const_parent_(parent)' + (
419          ', ' if storage_init else '')
420    else:
421      parent_param = ''
422      parent_arg = 'nullptr'
423      parent_init = ''
424    col_init = self.foreach_col(ColumnSerializer.column_init)
425    if col_init:
426      olay = 'uint32_t olay_idx = OverlayCount(parent);'
427    else:
428      olay = ''
429    storage_layer_create = self.foreach_col(
430        ColumnSerializer.storage_layer_create, delimiter=',')
431    null_layer_create = self.foreach_col(
432        ColumnSerializer.null_layer_create, delimiter=',')
433    return f'''
434  static std::vector<ColumnLegacy> GetColumns(
435      {self.table_name}* self,
436      const macros_internal::MacroTable* parent) {{
437    std::vector<ColumnLegacy> columns =
438        CopyColumnsFromParentOrAddRootColumns(self, parent);
439    {olay}
440    {col_init}
441    return columns;
442  }}
443
444  PERFETTO_NO_INLINE explicit {self.table_name}(StringPool* pool{parent_param})
445      : macros_internal::MacroTable(
446          pool,
447          GetColumns(this, {parent_arg}),
448          {parent_arg}),
449        {parent_init}{storage_init}{storage_layer_sep}
450        {storage_layer_init}{null_layer_sep}
451        {null_layer_init} {{
452    {self.foreach_col(ColumnSerializer.static_assert_flags)}
453    OnConstructionCompletedRegularConstructor(
454      {{{storage_layer_create}}},
455      {{{null_layer_create}}});
456  }}
457    '''
458
459  def parent_field(self) -> str:
460    if self.table.parent:
461      return f'''
462  {self.parent_class_name}* parent_ = nullptr;
463  const {self.parent_class_name}* const_parent_ = nullptr;
464      '''
465    return ''
466
467  def insert_common(self) -> str:
468    if self.table.parent:
469      return '''
470    Id id = Id{parent_->Insert(row).id};
471    UpdateOverlaysAfterParentInsert();
472      '''
473    return '''
474    Id id = Id{row_number};
475    type_.Append(string_pool()->InternString(row.type()));
476      '''
477
478  def const_iterator(self) -> str:
479    iterator_getters = self.foreach_col(
480        ColumnSerializer.iterator_getter, delimiter='\n')
481    return f'''
482  class ConstIterator;
483  class ConstIterator : public macros_internal::AbstractConstIterator<
484    ConstIterator, {self.table_name}, RowNumber, ConstRowReference> {{
485   public:
486    {iterator_getters}
487
488   protected:
489    explicit ConstIterator(const {self.table_name}* table,
490                           Table::Iterator iterator)
491        : AbstractConstIterator(table, std::move(iterator)) {{}}
492
493    uint32_t CurrentRowNumber() const {{
494      return iterator_.StorageIndexForLastOverlay();
495    }}
496
497   private:
498    friend class {self.table_name};
499    friend class macros_internal::AbstractConstIterator<
500      ConstIterator, {self.table_name}, RowNumber, ConstRowReference>;
501  }};
502      '''
503
504  def iterator(self) -> str:
505    iterator_setters = self.foreach_col(
506        ColumnSerializer.iterator_setter, delimiter='\n')
507    return f'''
508  class Iterator : public ConstIterator {{
509    public:
510     {iterator_setters}
511
512     RowReference row_reference() const {{
513       return RowReference(mutable_table_, CurrentRowNumber());
514     }}
515
516    private:
517     friend class {self.table_name};
518
519     explicit Iterator({self.table_name}* table, Table::Iterator iterator)
520        : ConstIterator(table, std::move(iterator)),
521          mutable_table_(table) {{}}
522
523     {self.table_name}* mutable_table_ = nullptr;
524  }};
525      '''
526
527  def extend(self) -> str:
528    if not self.table.parent:
529      return ''
530    params = self.foreach_col(
531        ColumnSerializer.extend_parent_param, delimiter='\n, ')
532    args = self.foreach_col(
533        ColumnSerializer.extend_parent_param_arg, delimiter=', ')
534    delim = ',' if params else ''
535    return f'''
536  static std::unique_ptr<Table> ExtendParent(
537      const {self.parent_class_name}& parent{delim}
538      {params}) {{
539    return std::unique_ptr<Table>(new {self.table_name}(
540        parent.string_pool(), parent, RowMap(0, parent.row_count()){delim}
541        {args}));
542  }}
543
544  static std::unique_ptr<Table> SelectAndExtendParent(
545      const {self.parent_class_name}& parent,
546      std::vector<{self.parent_class_name}::RowNumber> parent_overlay{delim}
547      {params}) {{
548    std::vector<uint32_t> prs_untyped(parent_overlay.size());
549    for (uint32_t i = 0; i < parent_overlay.size(); ++i) {{
550      prs_untyped[i] = parent_overlay[i].row_number();
551    }}
552    return std::unique_ptr<Table>(new {self.table_name}(
553        parent.string_pool(), parent, RowMap(std::move(prs_untyped)){delim}
554        {args}));
555  }}
556    '''
557
558  def extend_constructor(self) -> str:
559    if not self.table.parent:
560      return ''
561    storage_layer_init = self.foreach_col(
562        ColumnSerializer.storage_layer_init, delimiter=',\n        ')
563    storage_layer_sep = '\n,' if storage_layer_init else ''
564    null_layer_init = self.foreach_col(
565        ColumnSerializer.null_layer_init, delimiter=',\n        ')
566    null_layer_sep = '\n,' if null_layer_init else ''
567    params = self.foreach_col(
568        ColumnSerializer.extend_parent_param, delimiter='\n, ')
569    storage_layer_create = self.foreach_col(
570        ColumnSerializer.storage_layer_create, delimiter=',')
571    null_layer_create = self.foreach_col(
572        ColumnSerializer.null_layer_create, delimiter=',')
573    return f'''
574  {self.table_name}(StringPool* pool,
575            const {self.parent_class_name}& parent,
576            const RowMap& parent_overlay{',' if params else ''}
577            {params})
578      : macros_internal::MacroTable(
579          pool,
580          GetColumns(this, &parent),
581          parent,
582          parent_overlay),
583          const_parent_(&parent){storage_layer_sep}
584        {storage_layer_init}{null_layer_sep}
585        {null_layer_init} {{
586    {self.foreach_col(ColumnSerializer.static_assert_flags)}
587    {self.foreach_col(ColumnSerializer.extend_nullable_vector)}
588
589    std::vector<RefPtr<column::DataLayer>> overlay_layers(OverlayCount(&parent) + 1);
590    for (uint32_t i = 0; i < overlay_layers.size(); ++i) {{
591      if (overlays()[i].row_map().IsIndexVector()) {{
592        overlay_layers[i].reset(new column::ArrangementOverlay(
593            overlays()[i].row_map().GetIfIndexVector(),
594            column::DataLayerChain::Indices::State::kNonmonotonic));
595      }} else if (overlays()[i].row_map().IsBitVector()) {{
596        overlay_layers[i].reset(new column::SelectorOverlay(
597            overlays()[i].row_map().GetIfBitVector()));
598      }} else if (overlays()[i].row_map().IsRange()) {{
599        overlay_layers[i].reset(new column::RangeOverlay(
600            overlays()[i].row_map().GetIfIRange()));
601      }}
602    }}
603
604    OnConstructionCompleted(
605      {{{storage_layer_create}}}, {{{null_layer_create}}}, std::move(overlay_layers));
606  }}
607    '''
608
609  def column_count(self) -> str:
610    return str(len(self.column_serializers))
611
612  def serialize(self) -> str:
613    return f'''
614class {self.table_name} : public macros_internal::MacroTable {{
615 public:
616  static constexpr uint32_t kColumnCount = {self.column_count().strip()};
617
618  {self.id_defn().lstrip()}
619  struct ColumnIndex {{
620    {self.foreach_col(ColumnSerializer.colindex)}
621  }};
622  struct ColumnType {{
623    {self.foreach_col(ColumnSerializer.coltype_enum)}
624  }};
625  {self.row_struct().strip()}
626  struct ColumnFlag {{
627    {self.foreach_col(ColumnSerializer.flag)}
628  }};
629
630  class RowNumber;
631  class ConstRowReference;
632  class RowReference;
633
634  class RowNumber : public macros_internal::AbstractRowNumber<
635      {self.table_name}, ConstRowReference, RowReference> {{
636   public:
637    explicit RowNumber(uint32_t row_number)
638        : AbstractRowNumber(row_number) {{}}
639  }};
640  static_assert(std::is_trivially_destructible_v<RowNumber>,
641                "Inheritance used without trivial destruction");
642
643  {self.const_row_reference_struct().strip()}
644  {self.row_reference_struct().strip()}
645
646  {self.const_iterator().strip()}
647  {self.iterator().strip()}
648
649  struct IdAndRow {{
650    Id id;
651    uint32_t row;
652    RowReference row_reference;
653    RowNumber row_number;
654  }};
655
656  {self.constructor().strip()}
657  ~{self.table_name}() override;
658
659  static const char* Name() {{ return "{self.table.sql_name}"; }}
660
661  static Table::Schema ComputeStaticSchema() {{
662    Table::Schema schema;
663    schema.columns.emplace_back(Table::Schema::Column{{
664        "id", SqlValue::Type::kLong, true, true, false, false}});
665    schema.columns.emplace_back(Table::Schema::Column{{
666        "type", SqlValue::Type::kString, false, false, false, false}});
667    {self.foreach_col(ColumnSerializer.static_schema)}
668    return schema;
669  }}
670
671  ConstIterator IterateRows() const {{
672    return ConstIterator(this, Table::IterateRows());
673  }}
674
675  Iterator IterateRows() {{ return Iterator(this, Table::IterateRows()); }}
676
677  ConstIterator FilterToIterator(const Query& q) const {{
678    return ConstIterator(
679      this, ApplyAndIterateRows(QueryToRowMap(q)));
680  }}
681
682  Iterator FilterToIterator(const Query& q) {{
683    return Iterator(this, ApplyAndIterateRows(QueryToRowMap(q)));
684  }}
685
686  void ShrinkToFit() {{
687    {self.foreach_col(ColumnSerializer.shrink_to_fit)}
688  }}
689
690  std::optional<ConstRowReference> FindById(Id find_id) const {{
691    std::optional<uint32_t> row = id().IndexOf(find_id);
692    return row ? std::make_optional(ConstRowReference(this, *row))
693               : std::nullopt;
694  }}
695
696  std::optional<RowReference> FindById(Id find_id) {{
697    std::optional<uint32_t> row = id().IndexOf(find_id);
698    return row ? std::make_optional(RowReference(this, *row)) : std::nullopt;
699  }}
700
701  IdAndRow Insert(const Row& row) {{
702    uint32_t row_number = row_count();
703    {self.insert_common().strip()}
704    {self.foreach_col(ColumnSerializer.append)}
705    UpdateSelfOverlayAfterInsert();
706    return IdAndRow{{id, row_number, RowReference(this, row_number),
707                     RowNumber(row_number)}};
708  }}
709
710  {self.extend().strip()}
711
712  {self.foreach_col(ColumnSerializer.accessor)}
713
714  {self.foreach_col(ColumnSerializer.mutable_accessor)}
715
716 private:
717  {self.extend_constructor().strip()}
718  {self.parent_field().strip()}
719  {self.foreach_col(ColumnSerializer.storage)}
720
721  {self.foreach_col(ColumnSerializer.storage_layer)}
722
723  {self.foreach_col(ColumnSerializer.null_layer)}
724}};
725  '''.strip('\n')
726
727
728def serialize_header(ifdef_guard: str, tables: List[ParsedTable],
729                     include_paths: List[str]) -> str:
730  """Serializes a table header file containing the given set of tables."""
731  # Replace the backslash with forward slash when building on Windows.
732  # Caused b/327985369 without the replace.
733  include_paths_str = '\n'.join([f'#include "{i}"' for i in include_paths
734                                ]).replace("\\", "/")
735  tables_str = '\n\n'.join([TableSerializer(t).serialize() for t in tables])
736  return f'''
737#ifndef {ifdef_guard}
738#define {ifdef_guard}
739
740#include <array>
741#include <cstddef>
742#include <cstdint>
743#include <memory>
744#include <optional>
745#include <type_traits>
746#include <utility>
747#include <vector>
748
749#include "perfetto/base/logging.h"
750#include "perfetto/trace_processor/basic_types.h"
751#include "perfetto/trace_processor/ref_counted.h"
752#include "src/trace_processor/containers/bit_vector.h"
753#include "src/trace_processor/containers/row_map.h"
754#include "src/trace_processor/containers/string_pool.h"
755#include "src/trace_processor/db/column/arrangement_overlay.h"
756#include "src/trace_processor/db/column/data_layer.h"
757#include "src/trace_processor/db/column/dense_null_overlay.h"
758#include "src/trace_processor/db/column/numeric_storage.h"
759#include "src/trace_processor/db/column/id_storage.h"
760#include "src/trace_processor/db/column/null_overlay.h"
761#include "src/trace_processor/db/column/range_overlay.h"
762#include "src/trace_processor/db/column/selector_overlay.h"
763#include "src/trace_processor/db/column/set_id_storage.h"
764#include "src/trace_processor/db/column/string_storage.h"
765#include "src/trace_processor/db/column/types.h"
766#include "src/trace_processor/db/column_storage.h"
767#include "src/trace_processor/db/column.h"
768#include "src/trace_processor/db/table.h"
769#include "src/trace_processor/db/typed_column.h"
770#include "src/trace_processor/db/typed_column_internal.h"
771#include "src/trace_processor/tables/macros_internal.h"
772
773{include_paths_str}
774
775namespace perfetto::trace_processor::tables {{
776
777{tables_str.strip()}
778
779}}  // namespace perfetto
780
781#endif  // {ifdef_guard}
782  '''.strip()
783
784
785def to_cpp_flags(raw_flag: ColumnFlag) -> str:
786  """Converts a ColumnFlag to the C++ flags which it represents
787
788  It is not valid to call this function with ColumnFlag.NONE as in this case
789  defaults for that column should be implicitly used."""
790
791  assert raw_flag != ColumnFlag.NONE
792  flags = []
793  if ColumnFlag.SORTED in raw_flag:
794    flags.append('ColumnLegacy::Flag::kSorted')
795  if ColumnFlag.HIDDEN in raw_flag:
796    flags.append('ColumnLegacy::Flag::kHidden')
797  if ColumnFlag.DENSE in raw_flag:
798    flags.append('ColumnLegacy::Flag::kDense')
799  if ColumnFlag.SET_ID in raw_flag:
800    flags.append('ColumnLegacy::Flag::kSetId')
801  return ' | '.join(flags)
802