File: code_generator_ts.py

package info (click to toggle)
chromium 139.0.7258.127-2
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 6,122,156 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (128 lines) | stat: -rw-r--r-- 4,982 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# Copyright 2024 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from codegen_util import FileInfo, Util
from code_generator import (EventTemplateBase, ProjectInfoBase, EventInfoBase,
                            MetricInfoBase)


class ProjectInfoTs(ProjectInfoBase):
  """Codegen-related info about a project in Typescript."""

  def __init__(self, project):
    super().__init__(project, "webui")


class EventInfoTs(EventInfoBase):
  """Codegen-related info about an event in Typescript."""

  def __init__(self, event, project_info):
    super().__init__(event, project_info)

    if self.is_event_sequence == 'true':
      self.systemUptime = (
          '{microseconds: BigInt(Math.floor(Date.now() * 1000))}')
    else:
      self.systemUptime = 'null'


class MetricInfoTs(MetricInfoBase):
  """Codegen-related info about a metric in Typescript."""

  def __init__(self, metric, project_info, event_info):
    super().__init__(metric)

    self.project_name = project_info.name
    self.event_name = event_info.name

    if metric.type == 'hmac-string':
      self.ts_type = 'number'
      self.type_enum = 'hmacValue'
    elif metric.type == 'int':
      self.ts_type = 'bigint'
      self.type_enum = 'longValue'
    elif metric.type == 'raw-string':
      self.ts_type = 'string'
      self.type_enum = 'rawStrValue'
    elif metric.type == 'double':
      self.ts_type = 'number'
      self.type_enum = 'doubleValue'
    elif metric.type == 'int-array':
      # todo(b/341807121): support int array in Typescript.
      self.type_enum = ''
    else:
      if self.is_enum:
        self.ts_type = project_info.name + "_" + metric.type
        self.type_enum = 'intValue'
      else:
        raise ValueError('Invalid metric type.')


class TemplateTypescript(EventTemplateBase):
  """Template for producing Typescript code from structured.xml, to
  be used in WebUI pages."""

  def __init__(self, model, dirname, basename, file_template, project_template,
               enum_template, event_template, metric_template,
               metric_field_template, metric_build_code_template):
    super().__init__(model, dirname, basename, file_template, project_template,
                     enum_template, event_template, metric_template)
    self.metric_field_template = metric_field_template
    self.metric_build_code_template = metric_build_code_template

  def write_file(self):
    file_info = FileInfo(self.dirname, self.basename)
    with open(file_info.filepath, 'w') as f:
      f.write(self._stamp_file())

  def _stamp_file(self):
    project_code = "".join(
        self._stamp_project(project) for project in self.model.projects)
    return self.file_template.format(project_code=project_code)

  def _stamp_project(self, project):
    project_info = ProjectInfoTs(project)
    if project_info.should_codegen:
      event_code = ''.join(
          self._stamp_event(project_info, event) for event in project.events)
      enum_code = '\n\n'.join(
          self._stamp_enum(project_info, enum) for enum in project.enums)
      return self.project_template.format(project=project,
                                          enum_code=enum_code,
                                          event_code=event_code)
    return ""

  def _stamp_event(self, project_info, event):
    event_info = EventInfoTs(event, project_info)
    metric_code = ''.join(
        self._stamp_metric(project_info, event_info, metric)
        for metric in event.metrics)
    metric_fields = ''.join(
        self._stamp_metric_fields(project_info, event_info, metric)
        for metric in event.metrics)
    metric_build_code = ''.join(
        self._stamp_metric_build_code(project_info, event_info, metric)
        for metric in event.metrics)
    return self.event_template.format(event=event_info,
                                      metric_fields=metric_fields,
                                      metric_code=metric_code,
                                      metric_build_code=metric_build_code)

  def _stamp_metric(self, project_info, event_info, metric):
    metric_info = MetricInfoTs(metric, project_info, event_info)
    return self.metric_template.format(metric=metric_info)

  def _stamp_metric_fields(self, project_info, event_info, metric):
    metric_info = MetricInfoTs(metric, project_info, event_info)
    return self.metric_field_template.format(metric=metric_info)

  def _stamp_metric_build_code(self, project_info, event_info, metric):
    metric_info = MetricInfoTs(metric, project_info, event_info)
    return self.metric_build_code_template.format(metric=metric_info)

  def _stamp_enum(self, project_info, enum):
    variants = ',\n'.join(
        ['{v.name} = {v.value}'.format(v=v) for v in enum.variants])
    return self.enum_template.format(project_info=project_info,
                                     enum=enum,
                                     variants=variants)