blob: 7276fe669b2113d14b8f6967b7a1b1e4425ffc76 [file] [log] [blame]
Keith Mok57baaaf2023-06-13 22:33:10 +00001#!/usr/bin/python3
Yu Shan63e24d72022-06-24 17:53:32 +00002
3# Copyright (C) 2022 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17"""A script to generate Java files and CPP header files based on annotations in VehicleProperty.aidl
18
19 Need ANDROID_BUILD_TOP environmental variable to be set. This script will update
20 ChangeModeForVehicleProperty.h and AccessForVehicleProperty.h under generated_lib/cpp and
21 ChangeModeForVehicleProperty.java and AccessForVehicleProperty.java under generated_lib/java.
22
23 Usage:
24 $ python generate_annotation_enums.py
25"""
Yu Shan41dd7f12023-06-07 13:25:43 -070026import argparse
27import filecmp
Yu Shan63e24d72022-06-24 17:53:32 +000028import os
29import re
30import sys
Yu Shan41dd7f12023-06-07 13:25:43 -070031import tempfile
Yu Shan63e24d72022-06-24 17:53:32 +000032
Yu Shan41dd7f12023-06-07 13:25:43 -070033PROP_AIDL_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl_property/android/hardware/' +
34 'automotive/vehicle/VehicleProperty.aidl')
35CHANGE_MODE_CPP_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/cpp/' +
36 'ChangeModeForVehicleProperty.h')
37ACCESS_CPP_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/cpp/' +
38 'AccessForVehicleProperty.h')
39CHANGE_MODE_JAVA_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/' +
40 'ChangeModeForVehicleProperty.java')
41ACCESS_JAVA_FILE_PATH = ('hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/' +
42 'AccessForVehicleProperty.java')
43SCRIPT_PATH = 'hardware/interfaces/automotive/vehicle/tools/generate_annotation_enums.py'
Yu Shan63e24d72022-06-24 17:53:32 +000044
Yu Shan41dd7f12023-06-07 13:25:43 -070045TAB = ' '
46RE_ENUM_START = re.compile('\s*enum VehicleProperty \{')
47RE_ENUM_END = re.compile('\s*\}\;')
48RE_COMMENT_BEGIN = re.compile('\s*\/\*\*?')
49RE_COMMENT_END = re.compile('\s*\*\/')
50RE_CHANGE_MODE = re.compile('\s*\* @change_mode (\S+)\s*')
51RE_ACCESS = re.compile('\s*\* @access (\S+)\s*')
52RE_VALUE = re.compile('\s*(\w+)\s*=(.*)')
Yu Shan63e24d72022-06-24 17:53:32 +000053
54LICENSE = """/*
55 * Copyright (C) 2022 The Android Open Source Project
56 *
57 * Licensed under the Apache License, Version 2.0 (the "License");
58 * you may not use this file except in compliance with the License.
59 * You may obtain a copy of the License at
60 *
61 * http://www.apache.org/licenses/LICENSE-2.0
62 *
63 * Unless required by applicable law or agreed to in writing, software
64 * distributed under the License is distributed on an "AS IS" BASIS,
65 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66 * See the License for the specific language governing permissions and
67 * limitations under the License.
68 */
69
70/**
71 * DO NOT EDIT MANUALLY!!!
72 *
73 * Generated by tools/generate_annotation_enums.py.
74 */
75
Aaqib Ismail2e8915d2023-01-30 13:04:05 -080076// clang-format off
77
Yu Shan63e24d72022-06-24 17:53:32 +000078"""
79
80CHANGE_MODE_CPP_HEADER = """#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
81#define android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
82
83#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
84#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.h>
85
86#include <unordered_map>
87
88namespace aidl {
89namespace android {
90namespace hardware {
91namespace automotive {
92namespace vehicle {
93
94std::unordered_map<VehicleProperty, VehiclePropertyChangeMode> ChangeModeForVehicleProperty = {
95"""
96
97CHANGE_MODE_CPP_FOOTER = """
98};
99
100} // namespace vehicle
101} // namespace automotive
102} // namespace hardware
103} // namespace android
104} // aidl
105
106#endif // android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_
107"""
108
109ACCESS_CPP_HEADER = """#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
110#define android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
111
112#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h>
113#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.h>
114
115#include <unordered_map>
116
117namespace aidl {
118namespace android {
119namespace hardware {
120namespace automotive {
121namespace vehicle {
122
123std::unordered_map<VehicleProperty, VehiclePropertyAccess> AccessForVehicleProperty = {
124"""
125
126ACCESS_CPP_FOOTER = """
127};
128
129} // namespace vehicle
130} // namespace automotive
131} // namespace hardware
132} // namespace android
133} // aidl
134
135#endif // android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_
136"""
137
138CHANGE_MODE_JAVA_HEADER = """package android.hardware.automotive.vehicle;
139
140import java.util.Map;
141
142public final class ChangeModeForVehicleProperty {
143
144 public static final Map<Integer, Integer> values = Map.ofEntries(
145"""
146
147CHANGE_MODE_JAVA_FOOTER = """
148 );
149
150}
151"""
152
153ACCESS_JAVA_HEADER = """package android.hardware.automotive.vehicle;
154
155import java.util.Map;
156
157public final class AccessForVehicleProperty {
158
159 public static final Map<Integer, Integer> values = Map.ofEntries(
160"""
161
162ACCESS_JAVA_FOOTER = """
163 );
164
165}
166"""
167
168
169class Converter:
170
171 def __init__(self, name, annotation_re):
172 self.name = name
173 self.annotation_re = annotation_re
174
175 def convert(self, input, output, header, footer, cpp):
176 processing = False
177 in_comment = False
178 content = LICENSE + header
179 annotation = None
180 id = 0
181 with open(input, 'r') as f:
182 for line in f.readlines():
183 if RE_ENUM_START.match(line):
184 processing = True
185 annotation = None
186 elif RE_ENUM_END.match(line):
187 processing = False
188 if not processing:
189 continue
190 if RE_COMMENT_BEGIN.match(line):
191 in_comment = True
Yu Shan595c1da2023-07-06 17:38:49 -0700192 annotation = None
Yu Shan63e24d72022-06-24 17:53:32 +0000193 if RE_COMMENT_END.match(line):
194 in_comment = False
195 if in_comment:
196 match = self.annotation_re.match(line)
Yu Shan595c1da2023-07-06 17:38:49 -0700197 if match and not annotation:
Yu Shan63e24d72022-06-24 17:53:32 +0000198 annotation = match.group(1)
199 else:
200 match = RE_VALUE.match(line)
201 if match:
202 prop_name = match.group(1)
Yu Shan41dd7f12023-06-07 13:25:43 -0700203 if prop_name == 'INVALID':
Yu Shan63e24d72022-06-24 17:53:32 +0000204 continue
205 if not annotation:
Yu Shan41dd7f12023-06-07 13:25:43 -0700206 raise Exception(
207 'No @' + self.name + ' annotation for property: ' + prop_name)
Yu Shan63e24d72022-06-24 17:53:32 +0000208 if id != 0:
Yu Shan41dd7f12023-06-07 13:25:43 -0700209 content += '\n'
Yu Shan63e24d72022-06-24 17:53:32 +0000210 if cpp:
Yu Shan41dd7f12023-06-07 13:25:43 -0700211 annotation = annotation.replace('.', '::')
212 content += (TAB + TAB + '{VehicleProperty::' + prop_name + ', ' +
213 annotation + '},')
Yu Shan63e24d72022-06-24 17:53:32 +0000214 else:
Yu Shan41dd7f12023-06-07 13:25:43 -0700215 content += (TAB + TAB + 'Map.entry(VehicleProperty.' + prop_name + ', ' +
216 annotation + '),')
Yu Shan63e24d72022-06-24 17:53:32 +0000217 id += 1
218
Yu Shan41dd7f12023-06-07 13:25:43 -0700219 # Remove the additional ',' at the end for the Java file.
Yu Shan63e24d72022-06-24 17:53:32 +0000220 if not cpp:
221 content = content[:-1]
222
223 content += footer
224
225 with open(output, 'w') as f:
226 f.write(content)
227
228
Yu Shan41dd7f12023-06-07 13:25:43 -0700229def createTempFile():
230 f = tempfile.NamedTemporaryFile(delete=False);
231 f.close();
232 return f.name
233
234
Yu Shan63e24d72022-06-24 17:53:32 +0000235def main():
Yu Shan41dd7f12023-06-07 13:25:43 -0700236 parser = argparse.ArgumentParser(
237 description='Generate Java and C++ enums based on annotations in VehicleProperty.aidl')
238 parser.add_argument('--android_build_top', required=False, help='Path to ANDROID_BUILD_TOP')
239 parser.add_argument('--preupload_files', nargs='+', required=False, help='modified files')
240 parser.add_argument('--check_only', required=False, action='store_true',
241 help='only check whether the generated files need update')
242 args = parser.parse_args();
243 android_top = None
244 output_folder = None
245 if args.android_build_top:
246 android_top = args.android_build_top
247 vehiclePropertyUpdated = False
248 for preuload_file in args.preupload_files:
249 if preuload_file.endswith('VehicleProperty.aidl'):
250 vehiclePropertyUpdated = True
251 break
252 if not vehiclePropertyUpdated:
253 return
254 else:
255 android_top = os.environ['ANDROID_BUILD_TOP']
Yu Shan63e24d72022-06-24 17:53:32 +0000256 if not android_top:
Yu Shan41dd7f12023-06-07 13:25:43 -0700257 print('ANDROID_BUILD_TOP is not in envorinmental variable, please run source and lunch ' +
258 'at the android root')
Yu Shan63e24d72022-06-24 17:53:32 +0000259
260 aidl_file = os.path.join(android_top, PROP_AIDL_FILE_PATH)
Yu Shan63e24d72022-06-24 17:53:32 +0000261
Yu Shan41dd7f12023-06-07 13:25:43 -0700262 change_mode_cpp_file = os.path.join(android_top, CHANGE_MODE_CPP_FILE_PATH);
263 access_cpp_file = os.path.join(android_top, ACCESS_CPP_FILE_PATH);
264 change_mode_java_file = os.path.join(android_top, CHANGE_MODE_JAVA_FILE_PATH);
265 access_java_file = os.path.join(android_top, ACCESS_JAVA_FILE_PATH);
266 temp_files = []
267
268 if not args.check_only:
269 change_mode_cpp_output = change_mode_cpp_file
270 access_cpp_output = access_cpp_file
271 change_mode_java_output = change_mode_java_file
272 access_java_output = access_java_file
273 else:
274 change_mode_cpp_output = createTempFile()
275 temp_files.append(change_mode_cpp_output)
276 access_cpp_output = createTempFile()
277 temp_files.append(access_cpp_output)
278 change_mode_java_output = createTempFile()
279 temp_files.append(change_mode_java_output)
280 access_java_output = createTempFile()
281 temp_files.append(access_java_output)
282
283 try:
284 c = Converter('change_mode', RE_CHANGE_MODE);
285 c.convert(aidl_file, change_mode_cpp_output, CHANGE_MODE_CPP_HEADER, CHANGE_MODE_CPP_FOOTER,
286 True)
287 c.convert(aidl_file, change_mode_java_output, CHANGE_MODE_JAVA_HEADER,
288 CHANGE_MODE_JAVA_FOOTER, False)
289 c = Converter('access', RE_ACCESS)
290 c.convert(aidl_file, access_cpp_output, ACCESS_CPP_HEADER, ACCESS_CPP_FOOTER, True)
291 c.convert(aidl_file, access_java_output, ACCESS_JAVA_HEADER, ACCESS_JAVA_FOOTER, False)
292
293 if not args.check_only:
294 return
295
296 if ((not filecmp.cmp(change_mode_cpp_output, change_mode_cpp_file)) or
297 (not filecmp.cmp(change_mode_java_output, change_mode_java_file)) or
298 (not filecmp.cmp(access_cpp_output, access_cpp_file)) or
299 (not filecmp.cmp(access_java_output, access_java_file))):
300 print('The generated enum files for VehicleProperty.aidl requires update, ')
301 print('Run \npython ' + android_top + '/' + SCRIPT_PATH)
302 sys.exit(1)
303 except Exception as e:
304 print('Error parsing VehicleProperty.aidl')
305 print(e)
306 sys.exit(1)
307 finally:
308 for file in temp_files:
309 os.remove(file)
Yu Shan63e24d72022-06-24 17:53:32 +0000310
311
Yu Shan41dd7f12023-06-07 13:25:43 -0700312if __name__ == '__main__':
Yu Shan63e24d72022-06-24 17:53:32 +0000313 main()