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