File: java_element_generator.py

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 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 (148 lines) | stat: -rw-r--r-- 5,257 bytes parent folder | download | duplicates (11)
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import json
import class_generator

_INDENT = '    '


def _GenerateString(content, indent='  '):
  """Generates an UTF-8 string to be included in a static structure initializer.
  If content is not specified, uses NULL.
  """
  if content is None:
    return indent + 'null,'
  else:
    # json.dumps quotes the string and escape characters as required.
    return indent + '%s,' % json.dumps(content)


def _GenerateArrayVariableName(element_name, field_name, field_name_count):
  """Generates a unique variable name for an array variable.
  """
  var = '%s_%s' % (element_name, field_name)
  if var not in field_name_count:
    field_name_count[var] = 0
    return var
  new_var = '%s_%d' % (var, field_name_count[var])
  field_name_count[var] += 1
  return new_var


def _GenerateArray(element_name, field_info, content, indent, field_name_count):
  """Generates an array created inline in a constructor call. If content is
  not specified, null is used.
  """
  if content is None:
    return indent + 'null,'

  lines = []

  array_field = class_generator.GenerateField(field_info['contents'])
  array_type = array_field[:array_field.find(' ')]
  lines.append(indent + 'new %s[]{' % array_type)
  for subcontent in content:
    lines.append(
        _GenerateFieldContent(element_name, field_info['contents'], subcontent,
                              indent + _INDENT, field_name_count))
  lines.append(indent + '},')
  return '\n'.join(lines)


def _GenerateClass(element_name, field_info, content, indent, field_name_count):
  """Generates a class to be used in a constructor call. If content is not
  specified, use null.
  """
  if content is None:
    return indent + 'null'

  lines = []

  fields = field_info['fields']
  class_name = field_info['type_name']
  lines.append(indent + 'new ' + class_name + '(')
  for field in fields:
    subcontent = content.get(field['field'])
    lines.append(
        _GenerateFieldContent(element_name, field, subcontent, indent + _INDENT,
                              field_name_count))

  # remove the trailing comma for the last parameter
  lines[-1] = lines[-1][:-1]
  lines.append(indent + '),')

  return '\n'.join(lines)


def _GenerateFieldContent(element_name, field_info, content, indent,
                          field_name_count):
  """Generate the content of a field to be included in the constructor call. If
  the field's content is not specified, uses the default value if one exists.
  """
  if content is None:
    content = field_info.get('java_default', None)

  java_type = field_info['type']
  if java_type in ('int', 'class'):
    return '%s%s,' % (indent, content)
  elif java_type == 'enum':
    # TODO(peilinwang) temporarily treat enums as strings. Maybe use a
    # different schema? Right now these scripts are only used for generating
    # fieldtrial testing configs.
    return '%s"%s",' % (indent, content)
  elif java_type == 'string':
    return _GenerateString(content, indent)
  elif java_type == 'string16':
    raise RuntimeError('Generating a UTF16 java String is not supported yet.')
  elif java_type == 'array':
    return _GenerateArray(element_name, field_info, content, indent,
                          field_name_count)
  elif java_type == 'struct':
    return _GenerateClass(element_name, field_info, content, indent,
                          field_name_count)
  else:
    raise RuntimeError('Unknown field type "%s"' % java_type)


def _GenerateElement(type_name, schema, element_name, element,
                     field_name_count):
  """Generate the constructor call for one element.
  """
  lines = []
  lines.append(_INDENT + 'public static final %s %s = ' %
               (type_name, element_name))
  lines.append(2 * _INDENT + 'new %s(' % (type_name))
  for field_info in schema:
    content = element.get(field_info['field'], None)
    if (content == None and not field_info.get('optional', False)):
      raise RuntimeError('Mandatory field "%s" omitted in element "%s".' %
                         (field_info['field'], element_name))
    lines.append(
        _GenerateFieldContent(element_name, field_info, content, 2 * _INDENT,
                              field_name_count))

  # remove the trailing comma for the last parameter
  lines[-1] = lines[-1][:-1]
  lines.append(2 * _INDENT + ');')
  return '\n'.join(lines)


def GenerateElements(type_name, schema, description, field_name_count={}):
  """Generate the static initializers for all the elements in the
  description['elements'] dictionary, as well as for any variables in
  description['int_variables']. All elements in description['elements']
  will be generated as a public static final int/class.
  """
  result = []
  for var_name, value in description.get('int_variables', {}).items():
    result.append('public static final int %s = %s;' % (var_name, value))
  result.append('')

  for element_name, element in description.get('elements', {}).items():
    result.append(
        _GenerateElement(type_name, schema, element_name, element,
                         field_name_count))
    result.append('')
  return '\n'.join(result)