1#!/usr/bin/python 2 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""" 26import os 27import re 28import sys 29 30PROP_AIDL_FILE_PATH = ("hardware/interfaces/automotive/vehicle/aidl_property/android/hardware/" + 31 "automotive/vehicle/VehicleProperty.aidl") 32CHANGE_MODE_CPP_FILE_PATH = ("hardware/interfaces/automotive/vehicle/aidl/generated_lib/cpp/" + 33 "ChangeModeForVehicleProperty.h") 34ACCESS_CPP_FILE_PATH = ("hardware/interfaces/automotive/vehicle/aidl/generated_lib/cpp/" + 35 "AccessForVehicleProperty.h") 36CHANGE_MODE_JAVA_FILE_PATH = ("hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/" + 37 "ChangeModeForVehicleProperty.java") 38ACCESS_JAVA_FILE_PATH = ("hardware/interfaces/automotive/vehicle/aidl/generated_lib/java/" + 39 "AccessForVehicleProperty.java") 40 41TAB = " " 42RE_ENUM_START = re.compile("\s*enum VehicleProperty \{") 43RE_ENUM_END = re.compile("\s*\}\;") 44RE_COMMENT_BEGIN = re.compile("\s*\/\*\*?") 45RE_COMMENT_END = re.compile("\s*\*\/") 46RE_CHANGE_MODE = re.compile("\s*\* @change_mode (\S+)\s*") 47RE_ACCESS = re.compile("\s*\* @access (\S+)\s*") 48RE_VALUE = re.compile("\s*(\w+)\s*=(.*)") 49 50LICENSE = """/* 51 * Copyright (C) 2022 The Android Open Source Project 52 * 53 * Licensed under the Apache License, Version 2.0 (the "License"); 54 * you may not use this file except in compliance with the License. 55 * You may obtain a copy of the License at 56 * 57 * http://www.apache.org/licenses/LICENSE-2.0 58 * 59 * Unless required by applicable law or agreed to in writing, software 60 * distributed under the License is distributed on an "AS IS" BASIS, 61 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 62 * See the License for the specific language governing permissions and 63 * limitations under the License. 64 */ 65 66/** 67 * DO NOT EDIT MANUALLY!!! 68 * 69 * Generated by tools/generate_annotation_enums.py. 70 */ 71 72// clang-format off 73 74""" 75 76CHANGE_MODE_CPP_HEADER = """#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_ 77#define android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_ 78 79#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h> 80#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyChangeMode.h> 81 82#include <unordered_map> 83 84namespace aidl { 85namespace android { 86namespace hardware { 87namespace automotive { 88namespace vehicle { 89 90std::unordered_map<VehicleProperty, VehiclePropertyChangeMode> ChangeModeForVehicleProperty = { 91""" 92 93CHANGE_MODE_CPP_FOOTER = """ 94}; 95 96} // namespace vehicle 97} // namespace automotive 98} // namespace hardware 99} // namespace android 100} // aidl 101 102#endif // android_hardware_automotive_vehicle_aidl_generated_lib_ChangeModeForVehicleProperty_H_ 103""" 104 105ACCESS_CPP_HEADER = """#ifndef android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_ 106#define android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_ 107 108#include <aidl/android/hardware/automotive/vehicle/VehicleProperty.h> 109#include <aidl/android/hardware/automotive/vehicle/VehiclePropertyAccess.h> 110 111#include <unordered_map> 112 113namespace aidl { 114namespace android { 115namespace hardware { 116namespace automotive { 117namespace vehicle { 118 119std::unordered_map<VehicleProperty, VehiclePropertyAccess> AccessForVehicleProperty = { 120""" 121 122ACCESS_CPP_FOOTER = """ 123}; 124 125} // namespace vehicle 126} // namespace automotive 127} // namespace hardware 128} // namespace android 129} // aidl 130 131#endif // android_hardware_automotive_vehicle_aidl_generated_lib_AccessForVehicleProperty_H_ 132""" 133 134CHANGE_MODE_JAVA_HEADER = """package android.hardware.automotive.vehicle; 135 136import java.util.Map; 137 138public final class ChangeModeForVehicleProperty { 139 140 public static final Map<Integer, Integer> values = Map.ofEntries( 141""" 142 143CHANGE_MODE_JAVA_FOOTER = """ 144 ); 145 146} 147""" 148 149ACCESS_JAVA_HEADER = """package android.hardware.automotive.vehicle; 150 151import java.util.Map; 152 153public final class AccessForVehicleProperty { 154 155 public static final Map<Integer, Integer> values = Map.ofEntries( 156""" 157 158ACCESS_JAVA_FOOTER = """ 159 ); 160 161} 162""" 163 164 165class Converter: 166 167 def __init__(self, name, annotation_re): 168 self.name = name 169 self.annotation_re = annotation_re 170 171 def convert(self, input, output, header, footer, cpp): 172 processing = False 173 in_comment = False 174 content = LICENSE + header 175 annotation = None 176 id = 0 177 with open(input, 'r') as f: 178 for line in f.readlines(): 179 if RE_ENUM_START.match(line): 180 processing = True 181 annotation = None 182 elif RE_ENUM_END.match(line): 183 processing = False 184 if not processing: 185 continue 186 if RE_COMMENT_BEGIN.match(line): 187 in_comment = True 188 if RE_COMMENT_END.match(line): 189 in_comment = False 190 if in_comment: 191 match = self.annotation_re.match(line) 192 if match: 193 annotation = match.group(1) 194 else: 195 match = RE_VALUE.match(line) 196 if match: 197 prop_name = match.group(1) 198 if prop_name == "INVALID": 199 continue 200 if not annotation: 201 print("No @" + self.name + " annotation for property: " + prop_name) 202 sys.exit(1) 203 if id != 0: 204 content += "\n" 205 if cpp: 206 annotation = annotation.replace(".", "::") 207 content += (TAB + TAB + "{VehicleProperty::" + prop_name + ", " + 208 annotation + "},") 209 else: 210 content += (TAB + TAB + "Map.entry(VehicleProperty." + prop_name + ", " + 211 annotation + "),") 212 id += 1 213 214 # Remove the additional "," at the end for the Java file. 215 if not cpp: 216 content = content[:-1] 217 218 content += footer 219 220 with open(output, 'w') as f: 221 f.write(content) 222 223 224def main(): 225 android_top = os.environ['ANDROID_BUILD_TOP'] 226 if not android_top: 227 print("ANDROID_BUILD_TOP is not in envorinmental variable, please run source and lunch " + 228 "at the android root") 229 230 aidl_file = os.path.join(android_top, PROP_AIDL_FILE_PATH) 231 change_mode_cpp_output = os.path.join(android_top, CHANGE_MODE_CPP_FILE_PATH); 232 access_cpp_output = os.path.join(android_top, ACCESS_CPP_FILE_PATH); 233 change_mode_java_output = os.path.join(android_top, CHANGE_MODE_JAVA_FILE_PATH); 234 access_java_output = os.path.join(android_top, ACCESS_JAVA_FILE_PATH); 235 236 c = Converter("change_mode", RE_CHANGE_MODE); 237 c.convert(aidl_file, change_mode_cpp_output, CHANGE_MODE_CPP_HEADER, CHANGE_MODE_CPP_FOOTER, True) 238 c.convert(aidl_file, change_mode_java_output, CHANGE_MODE_JAVA_HEADER, CHANGE_MODE_JAVA_FOOTER, False) 239 c = Converter("access", RE_ACCESS) 240 c.convert(aidl_file, access_cpp_output, ACCESS_CPP_HEADER, ACCESS_CPP_FOOTER, True) 241 c.convert(aidl_file, access_java_output, ACCESS_JAVA_HEADER, ACCESS_JAVA_FOOTER, False) 242 243 244if __name__ == "__main__": 245 main()