| # 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) |