xref: /aosp_15_r20/external/perfetto/python/generators/trace_processor_table/serialize.py (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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 static_schema(self) -> Optional[str]:
179    if self.is_implicit_id or self.is_implicit_type:
180      return None
181    return f'''
182    schema.columns.emplace_back(Table::Schema::Column{{
183        "{self.name}", ColumnType::{self.name}::SqlValueType(), false,
184        {str(ColumnFlag.SORTED in self.flags).lower()},
185        {str(ColumnFlag.HIDDEN in self.flags).lower()},
186        {str(ColumnFlag.SET_ID in self.flags).lower()}}});
187    '''
188
189  def row_eq(self) -> Optional[str]:
190    if self.is_implicit_id or self.is_implicit_type:
191      return None
192    return f'ColumnType::{self.name}::Equals({self.name}, other.{self.name})'
193
194  def extend_parent_param(self) -> Optional[str]:
195    if self.is_implicit_id or self.is_implicit_type:
196      return None
197    if self.is_ancestor:
198      return None
199    return f'ColumnStorage<ColumnType::{self.name}::stored_type> {self.name}'
200
201  def extend_parent_param_arg(self) -> Optional[str]:
202    if self.is_implicit_id or self.is_implicit_type:
203      return None
204    if self.is_ancestor:
205      return None
206    return f'std::move({self.name})'
207
208  def static_assert_flags(self) -> Optional[str]:
209    if self.is_implicit_id or self.is_implicit_type:
210      return None
211    if self.is_ancestor:
212      return None
213    return f'''
214      static_assert(
215        ColumnLegacy::IsFlagsAndTypeValid<ColumnType::{self.name}::stored_type>(
216          ColumnFlag::{self.name}),
217        "Column type and flag combination is not valid");
218    '''
219
220  def extend_nullable_vector(self) -> Optional[str]:
221    if self.is_implicit_id or self.is_implicit_type:
222      return None
223    if self.is_ancestor:
224      return None
225    return f'''
226    PERFETTO_DCHECK({self.name}.size() == parent_overlay.size());
227    {self.name}_ = std::move({self.name});
228    '''
229
230  def storage_layer(self) -> Optional[str]:
231    if self.is_ancestor:
232      return None
233    return f'''
234  RefPtr<column::StorageLayer> {self.name}_storage_layer_;
235  '''
236
237  def null_layer(self) -> Optional[str]:
238    if self.is_ancestor:
239      return None
240    if not self.is_optional or self.is_string:
241      return f''
242    return f'''
243  RefPtr<column::OverlayLayer> {self.name}_null_layer_;
244  '''
245
246  def storage_layer_create(self) -> str:
247    if self.is_ancestor:
248      return f'''const_parent_->storage_layers()[ColumnIndex::{self.name}]'''
249    return f'''{self.name}_storage_layer_'''
250
251  def null_layer_create(self) -> str:
252    if not self.is_optional or self.is_string:
253      return f'{{}}'
254    if self.is_ancestor:
255      return f'''const_parent_->null_layers()[ColumnIndex::{self.name}]'''
256    return f'''{self.name}_null_layer_'''
257
258  def storage_layer_init(self) -> str:
259    if self.is_ancestor:
260      return f''
261    if self.is_implicit_id:
262      return f'{self.name}_storage_layer_(new column::IdStorage())'
263    if self.is_string:
264      return f'''{self.name}_storage_layer_(
265          new column::StringStorage(string_pool(), &{self.name}_.vector()))'''
266    if ColumnFlag.SET_ID in self.flags:
267      return f'''{self.name}_storage_layer_(
268          new column::SetIdStorage(&{self.name}_.vector()))'''
269    if self.is_optional:
270      return f'''{self.name}_storage_layer_(
271          new column::NumericStorage<ColumnType::{self.name}::non_optional_stored_type>(
272            &{self.name}_.non_null_vector(),
273            ColumnTypeHelper<ColumnType::{self.name}::stored_type>::ToColumnType(),
274            {str(ColumnFlag.SORTED in self.flags).lower()}))'''
275    return f'''{self.name}_storage_layer_(
276        new column::NumericStorage<ColumnType::{self.name}::non_optional_stored_type>(
277          &{self.name}_.vector(),
278          ColumnTypeHelper<ColumnType::{self.name}::stored_type>::ToColumnType(),
279          {str(ColumnFlag.SORTED in self.flags).lower()}))'''
280
281  def null_layer_init(self) -> str:
282    if self.is_ancestor:
283      return f''
284    if not self.is_optional or self.is_string:
285      return f''
286    if ColumnFlag.DENSE in self.flags:
287      return f'''{self.name}_null_layer_(new column::DenseNullOverlay({self.name}_.bv()))'''
288    return f'''{self.name}_null_layer_(new column::NullOverlay({self.name}_.bv()))'''
289
290
291class TableSerializer(object):
292  """Functions for seralizing a single Table into C++."""
293
294  def __init__(self, parsed: ParsedTable):
295    self.table = parsed.table
296    self.table_name = parsed.table.class_name
297    self.column_serializers = []
298
299    if parsed.table.parent:
300      self.parent_class_name = parsed.table.parent.class_name
301    else:
302      self.parent_class_name = 'macros_internal::RootParentTable'
303
304    self.column_serializers = []
305    for c in parsed.columns:
306      # Aliases should be ignored as they are handled in SQL currently.
307      if isinstance(c.column.type, Alias):
308        continue
309      self.column_serializers.append(
310          ColumnSerializer(parsed, c, len(self.column_serializers)))
311
312  def foreach_col(self, serialize_fn, delimiter='\n') -> str:
313    lines = []
314    for c in self.column_serializers:
315      serialized = serialize_fn(c)
316      if serialized:
317        lines.append(serialized.lstrip('\n').rstrip())
318    return delimiter.join(lines).strip()
319
320  def id_defn(self) -> str:
321    if self.table.parent:
322      return f'''
323  using Id = {self.table.parent.class_name}::Id;
324    '''
325    return '''
326  struct Id : public BaseId {
327    Id() = default;
328    explicit constexpr Id(uint32_t v) : BaseId(v) {}
329  };
330  static_assert(std::is_trivially_destructible_v<Id>,
331                "Inheritance used without trivial destruction");
332    '''
333
334  def row_struct(self) -> str:
335    param = self.foreach_col(
336        ColumnSerializer.row_param, delimiter=',\n        ')
337    parent_row_init = self.foreach_col(
338        ColumnSerializer.parent_row_initializer, delimiter=', ')
339    row_init = self.foreach_col(
340        ColumnSerializer.row_initializer, delimiter=',\n          ')
341    parent_separator = ',' if row_init else ''
342    row_eq = self.foreach_col(ColumnSerializer.row_eq, delimiter=' &&\n       ')
343    return f'''
344  struct Row : public {self.parent_class_name}::Row {{
345    Row({param},
346        std::nullptr_t = nullptr)
347        : {self.parent_class_name}::Row({parent_row_init}){parent_separator}
348          {row_init} {{
349      type_ = "{self.table.sql_name}";
350    }}
351    {self.foreach_col(ColumnSerializer.row_field)}
352
353    bool operator==(const {self.table_name}::Row& other) const {{
354      return type() == other.type() && {row_eq};
355    }}
356  }};
357    '''
358
359  def const_row_reference_struct(self) -> str:
360    row_ref_getters = self.foreach_col(
361        ColumnSerializer.const_row_ref_getter, delimiter='\n    ')
362    return f'''
363  class ConstRowReference : public macros_internal::AbstractConstRowReference<
364    {self.table_name}, RowNumber> {{
365   public:
366    ConstRowReference(const {self.table_name}* table, uint32_t row_number)
367        : AbstractConstRowReference(table, row_number) {{}}
368
369    {row_ref_getters}
370  }};
371  static_assert(std::is_trivially_destructible_v<ConstRowReference>,
372                "Inheritance used without trivial destruction");
373    '''
374
375  def row_reference_struct(self) -> str:
376    row_ref_getters = self.foreach_col(
377        ColumnSerializer.row_ref_getter, delimiter='\n    ')
378    return f'''
379  class RowReference : public ConstRowReference {{
380   public:
381    RowReference(const {self.table_name}* table, uint32_t row_number)
382        : ConstRowReference(table, row_number) {{}}
383
384    {row_ref_getters}
385
386   private:
387    {self.table_name}* mutable_table() const {{
388      return const_cast<{self.table_name}*>(table());
389    }}
390  }};
391  static_assert(std::is_trivially_destructible_v<RowReference>,
392                "Inheritance used without trivial destruction");
393    '''
394
395  def constructor(self) -> str:
396    storage_init = self.foreach_col(
397        ColumnSerializer.storage_init, delimiter=',\n        ')
398    storage_layer_init = self.foreach_col(
399        ColumnSerializer.storage_layer_init, delimiter=',\n        ')
400    storage_layer_sep = '\n,' if storage_layer_init else ''
401    null_layer_init = self.foreach_col(
402        ColumnSerializer.null_layer_init, delimiter=',\n        ')
403    null_layer_sep = '\n,' if null_layer_init else ''
404    if self.table.parent:
405      parent_param = f', {self.parent_class_name}* parent'
406      parent_arg = 'parent'
407      parent_init = 'parent_(parent), const_parent_(parent)' + (
408          ', ' if storage_init else '')
409    else:
410      parent_param = ''
411      parent_arg = 'nullptr'
412      parent_init = ''
413    col_init = self.foreach_col(ColumnSerializer.column_init)
414    if col_init:
415      olay = 'uint32_t olay_idx = OverlayCount(parent);'
416    else:
417      olay = ''
418    storage_layer_create = self.foreach_col(
419        ColumnSerializer.storage_layer_create, delimiter=',')
420    null_layer_create = self.foreach_col(
421        ColumnSerializer.null_layer_create, delimiter=',')
422    return f'''
423  static std::vector<ColumnLegacy> GetColumns(
424      {self.table_name}* self,
425      const macros_internal::MacroTable* parent) {{
426    std::vector<ColumnLegacy> columns =
427        CopyColumnsFromParentOrAddRootColumns(self, parent);
428    {olay}
429    {col_init}
430    return columns;
431  }}
432
433  PERFETTO_NO_INLINE explicit {self.table_name}(StringPool* pool{parent_param})
434      : macros_internal::MacroTable(
435          pool,
436          GetColumns(this, {parent_arg}),
437          {parent_arg}),
438        {parent_init}{storage_init}{storage_layer_sep}
439        {storage_layer_init}{null_layer_sep}
440        {null_layer_init} {{
441    {self.foreach_col(ColumnSerializer.static_assert_flags)}
442    OnConstructionCompletedRegularConstructor(
443      {{{storage_layer_create}}},
444      {{{null_layer_create}}});
445  }}
446    '''
447
448  def parent_field(self) -> str:
449    if self.table.parent:
450      return f'''
451  {self.parent_class_name}* parent_ = nullptr;
452  const {self.parent_class_name}* const_parent_ = nullptr;
453      '''
454    return ''
455
456  def insert_common(self) -> str:
457    if self.table.parent:
458      return '''
459    Id id = Id{parent_->Insert(row).id};
460    UpdateOverlaysAfterParentInsert();
461      '''
462    return '''
463    Id id = Id{row_number};
464    type_.Append(string_pool()->InternString(row.type()));
465      '''
466
467  def const_iterator(self) -> str:
468    iterator_getters = self.foreach_col(
469        ColumnSerializer.iterator_getter, delimiter='\n')
470    return f'''
471  class ConstIterator;
472  class ConstIterator : public macros_internal::AbstractConstIterator<
473    ConstIterator, {self.table_name}, RowNumber, ConstRowReference> {{
474   public:
475    {iterator_getters}
476
477   protected:
478    explicit ConstIterator(const {self.table_name}* table,
479                           Table::Iterator iterator)
480        : AbstractConstIterator(table, std::move(iterator)) {{}}
481
482    uint32_t CurrentRowNumber() const {{
483      return iterator_.StorageIndexForLastOverlay();
484    }}
485
486   private:
487    friend class {self.table_name};
488    friend class macros_internal::AbstractConstIterator<
489      ConstIterator, {self.table_name}, RowNumber, ConstRowReference>;
490  }};
491      '''
492
493  def iterator(self) -> str:
494    return f'''
495  class Iterator : public ConstIterator {{
496    public:
497     RowReference row_reference() const {{
498       return {{const_cast<{self.table_name}*>(table()), CurrentRowNumber()}};
499     }}
500
501    private:
502     friend class {self.table_name};
503
504     explicit Iterator({self.table_name}* table, Table::Iterator iterator)
505        : ConstIterator(table, std::move(iterator)) {{}}
506  }};
507      '''
508
509  def extend(self) -> str:
510    if not self.table.parent:
511      return ''
512    params = self.foreach_col(
513        ColumnSerializer.extend_parent_param, delimiter='\n, ')
514    args = self.foreach_col(
515        ColumnSerializer.extend_parent_param_arg, delimiter=', ')
516    delim = ',' if params else ''
517    return f'''
518  static std::unique_ptr<{self.table_name}> ExtendParent(
519      const {self.parent_class_name}& parent{delim}
520      {params}) {{
521    return std::unique_ptr<{self.table_name}>(new {self.table_name}(
522        parent.string_pool(), parent, RowMap(0, parent.row_count()){delim}
523        {args}));
524  }}
525
526  static std::unique_ptr<{self.table_name}> SelectAndExtendParent(
527      const {self.parent_class_name}& parent,
528      std::vector<{self.parent_class_name}::RowNumber> parent_overlay{delim}
529      {params}) {{
530    std::vector<uint32_t> prs_untyped(parent_overlay.size());
531    for (uint32_t i = 0; i < parent_overlay.size(); ++i) {{
532      prs_untyped[i] = parent_overlay[i].row_number();
533    }}
534    return std::unique_ptr<{self.table_name}>(new {self.table_name}(
535        parent.string_pool(), parent, RowMap(std::move(prs_untyped)){delim}
536        {args}));
537  }}
538    '''
539
540  def extend_constructor(self) -> str:
541    if not self.table.parent:
542      return ''
543    storage_layer_init = self.foreach_col(
544        ColumnSerializer.storage_layer_init, delimiter=',\n        ')
545    storage_layer_sep = '\n,' if storage_layer_init else ''
546    null_layer_init = self.foreach_col(
547        ColumnSerializer.null_layer_init, delimiter=',\n        ')
548    null_layer_sep = '\n,' if null_layer_init else ''
549    params = self.foreach_col(
550        ColumnSerializer.extend_parent_param, delimiter='\n, ')
551    storage_layer_create = self.foreach_col(
552        ColumnSerializer.storage_layer_create, delimiter=',')
553    null_layer_create = self.foreach_col(
554        ColumnSerializer.null_layer_create, delimiter=',')
555    return f'''
556  {self.table_name}(StringPool* pool,
557            const {self.parent_class_name}& parent,
558            const RowMap& parent_overlay{',' if params else ''}
559            {params})
560      : macros_internal::MacroTable(
561          pool,
562          GetColumns(this, &parent),
563          parent,
564          parent_overlay),
565          const_parent_(&parent){storage_layer_sep}
566        {storage_layer_init}{null_layer_sep}
567        {null_layer_init} {{
568    {self.foreach_col(ColumnSerializer.static_assert_flags)}
569    {self.foreach_col(ColumnSerializer.extend_nullable_vector)}
570
571    std::vector<RefPtr<column::OverlayLayer>> overlay_layers(OverlayCount(&parent) + 1);
572    for (uint32_t i = 0; i < overlay_layers.size(); ++i) {{
573      if (overlays()[i].row_map().IsIndexVector()) {{
574        overlay_layers[i].reset(new column::ArrangementOverlay(
575            overlays()[i].row_map().GetIfIndexVector(),
576            column::DataLayerChain::Indices::State::kNonmonotonic));
577      }} else if (overlays()[i].row_map().IsBitVector()) {{
578        overlay_layers[i].reset(new column::SelectorOverlay(
579            overlays()[i].row_map().GetIfBitVector()));
580      }} else if (overlays()[i].row_map().IsRange()) {{
581        overlay_layers[i].reset(new column::RangeOverlay(
582            overlays()[i].row_map().GetIfIRange()));
583      }}
584    }}
585
586    OnConstructionCompleted(
587      {{{storage_layer_create}}}, {{{null_layer_create}}}, std::move(overlay_layers));
588  }}
589    '''
590
591  def column_count(self) -> str:
592    return str(len(self.column_serializers))
593
594  def serialize(self) -> str:
595    return f'''
596class {self.table_name} : public macros_internal::MacroTable {{
597 public:
598  static constexpr uint32_t kColumnCount = {self.column_count().strip()};
599
600  {self.id_defn().lstrip()}
601  struct ColumnIndex {{
602    {self.foreach_col(ColumnSerializer.colindex)}
603  }};
604  struct ColumnType {{
605    {self.foreach_col(ColumnSerializer.coltype_enum)}
606  }};
607  {self.row_struct().strip()}
608  struct ColumnFlag {{
609    {self.foreach_col(ColumnSerializer.flag)}
610  }};
611
612  class RowNumber;
613  class ConstRowReference;
614  class RowReference;
615
616  class RowNumber : public macros_internal::AbstractRowNumber<
617      {self.table_name}, ConstRowReference, RowReference> {{
618   public:
619    explicit RowNumber(uint32_t row_number)
620        : AbstractRowNumber(row_number) {{}}
621  }};
622  static_assert(std::is_trivially_destructible_v<RowNumber>,
623                "Inheritance used without trivial destruction");
624
625  {self.const_row_reference_struct().strip()}
626  {self.row_reference_struct().strip()}
627
628  {self.const_iterator().strip()}
629  {self.iterator().strip()}
630
631  struct IdAndRow {{
632    Id id;
633    uint32_t row;
634    RowReference row_reference;
635    RowNumber row_number;
636  }};
637
638  {self.constructor().strip()}
639  ~{self.table_name}() override;
640
641  static const char* Name() {{ return "{self.table.sql_name}"; }}
642
643  static Table::Schema ComputeStaticSchema() {{
644    Table::Schema schema;
645    schema.columns.emplace_back(Table::Schema::Column{{
646        "id", SqlValue::Type::kLong, true, true, false, false}});
647    schema.columns.emplace_back(Table::Schema::Column{{
648        "type", SqlValue::Type::kString, false, false, false, false}});
649    {self.foreach_col(ColumnSerializer.static_schema)}
650    return schema;
651  }}
652
653  ConstIterator IterateRows() const {{
654    return ConstIterator(this, Table::IterateRows());
655  }}
656
657  Iterator IterateRows() {{ return Iterator(this, Table::IterateRows()); }}
658
659  ConstIterator FilterToIterator(const Query& q) const {{
660    return ConstIterator(this, QueryToIterator(q));
661  }}
662
663  Iterator FilterToIterator(const Query& q) {{
664    return Iterator(this, QueryToIterator(q));
665  }}
666
667  void ShrinkToFit() {{
668    {self.foreach_col(ColumnSerializer.shrink_to_fit)}
669  }}
670
671  ConstRowReference operator[](uint32_t r) const {{
672    return ConstRowReference(this, r);
673  }}
674  RowReference operator[](uint32_t r) {{ return RowReference(this, r); }}
675  ConstRowReference operator[](RowNumber r) const {{
676    return ConstRowReference(this, r.row_number());
677  }}
678  RowReference operator[](RowNumber r) {{
679    return RowReference(this, r.row_number());
680  }}
681
682  std::optional<ConstRowReference> FindById(Id find_id) const {{
683    std::optional<uint32_t> row = id().IndexOf(find_id);
684    return row ? std::make_optional(ConstRowReference(this, *row))
685               : std::nullopt;
686  }}
687
688  std::optional<RowReference> FindById(Id find_id) {{
689    std::optional<uint32_t> row = id().IndexOf(find_id);
690    return row ? std::make_optional(RowReference(this, *row)) : std::nullopt;
691  }}
692
693  IdAndRow Insert(const Row& row) {{
694    uint32_t row_number = row_count();
695    {self.insert_common().strip()}
696    {self.foreach_col(ColumnSerializer.append)}
697    UpdateSelfOverlayAfterInsert();
698    return IdAndRow{{id, row_number, RowReference(this, row_number),
699                     RowNumber(row_number)}};
700  }}
701
702  {self.extend().strip()}
703
704  {self.foreach_col(ColumnSerializer.accessor)}
705
706  {self.foreach_col(ColumnSerializer.mutable_accessor)}
707
708 private:
709  {self.extend_constructor().strip()}
710  {self.parent_field().strip()}
711  {self.foreach_col(ColumnSerializer.storage)}
712
713  {self.foreach_col(ColumnSerializer.storage_layer)}
714
715  {self.foreach_col(ColumnSerializer.null_layer)}
716}};
717  '''.strip('\n')
718
719
720def serialize_header(ifdef_guard: str, tables: List[ParsedTable],
721                     include_paths: List[str]) -> str:
722  """Serializes a table header file containing the given set of tables."""
723  # Replace the backslash with forward slash when building on Windows.
724  # Caused b/327985369 without the replace.
725  include_paths_str = '\n'.join([f'#include "{i}"' for i in include_paths
726                                ]).replace("\\", "/")
727  tables_str = '\n\n'.join([TableSerializer(t).serialize() for t in tables])
728  return f'''
729#ifndef {ifdef_guard}
730#define {ifdef_guard}
731
732#include <array>
733#include <cstddef>
734#include <cstdint>
735#include <memory>
736#include <optional>
737#include <type_traits>
738#include <utility>
739#include <vector>
740
741#include "perfetto/base/logging.h"
742#include "perfetto/trace_processor/basic_types.h"
743#include "perfetto/trace_processor/ref_counted.h"
744#include "src/trace_processor/containers/bit_vector.h"
745#include "src/trace_processor/containers/row_map.h"
746#include "src/trace_processor/containers/string_pool.h"
747#include "src/trace_processor/db/column/arrangement_overlay.h"
748#include "src/trace_processor/db/column/data_layer.h"
749#include "src/trace_processor/db/column/dense_null_overlay.h"
750#include "src/trace_processor/db/column/numeric_storage.h"
751#include "src/trace_processor/db/column/id_storage.h"
752#include "src/trace_processor/db/column/null_overlay.h"
753#include "src/trace_processor/db/column/range_overlay.h"
754#include "src/trace_processor/db/column/selector_overlay.h"
755#include "src/trace_processor/db/column/set_id_storage.h"
756#include "src/trace_processor/db/column/string_storage.h"
757#include "src/trace_processor/db/column/types.h"
758#include "src/trace_processor/db/column_storage.h"
759#include "src/trace_processor/db/column.h"
760#include "src/trace_processor/db/table.h"
761#include "src/trace_processor/db/typed_column.h"
762#include "src/trace_processor/db/typed_column_internal.h"
763#include "src/trace_processor/tables/macros_internal.h"
764
765{include_paths_str}
766
767namespace perfetto::trace_processor::tables {{
768
769{tables_str.strip()}
770
771}}  // namespace perfetto
772
773#endif  // {ifdef_guard}
774  '''.strip()
775
776
777def to_cpp_flags(raw_flag: ColumnFlag) -> str:
778  """Converts a ColumnFlag to the C++ flags which it represents
779
780  It is not valid to call this function with ColumnFlag.NONE as in this case
781  defaults for that column should be implicitly used."""
782
783  assert raw_flag != ColumnFlag.NONE
784  flags = []
785  if ColumnFlag.SORTED in raw_flag:
786    flags.append('ColumnLegacy::Flag::kSorted')
787  if ColumnFlag.HIDDEN in raw_flag:
788    flags.append('ColumnLegacy::Flag::kHidden')
789  if ColumnFlag.DENSE in raw_flag:
790    flags.append('ColumnLegacy::Flag::kDense')
791  if ColumnFlag.SET_ID in raw_flag:
792    flags.append('ColumnLegacy::Flag::kSetId')
793  return ' | '.join(flags)
794