Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e14bd55 authored by Victor Shutemov's avatar Victor Shutemov
Browse files

Fix AIDL VHAL metadata extraction script

Add capability to process values from imports.
Update json metadata file with new data.

Testing:
1. cd hardware/interfaces/automotive/vehicle/aidl/emu_metadata
2. ./generate_emulator_metadata.py ../../aidl_property/android/hardware/automotive/vehicle out.json

Bug: 317529575
Test: manual
Change-Id: I315f1f75c2372796bde3bdacd39246344579c002
parent 35bf32ff
Loading
Loading
Loading
Loading
+3063 −1920

File changed.

Preview size limit exceeded, changes collapsed.

+70 −31
Original line number Diff line number Diff line
@@ -19,23 +19,56 @@ import sys

from pathlib import Path

RE_PACKAGE = re.compile(r"\npackage\s([\.a-z0-9]*);")
RE_IMPORT = re.compile(r"\nimport\s([\.a-zA-Z0-9]*);")
RE_ENUM = re.compile(r"\s*enum\s+(\w*) {\n(.*)}", re.MULTILINE | re.DOTALL)
RE_COMMENT = re.compile(r"(?:(?:\/\*\*)((?:.|\n)*?)(?:\*\/))?(?:\n|^)\s*(\w*)(?:\s+=\s*)?((?:[a-zA-Z0-9]|\s|\+|)*),", re.DOTALL)
RE_COMMENT = re.compile(r"(?:(?:\/\*\*)((?:.|\n)*?)(?:\*\/))?(?:\n|^)\s*(\w*)(?:\s+=\s*)?((?:[\.\-a-zA-Z0-9]|\s|\+|)*),",
                        re.DOTALL)
RE_BLOCK_COMMENT_TITLE = re.compile("^(?:\s|\*)*((?:\w|\s|\.)*)\n(?:\s|\*)*(?:\n|$)")
RE_BLOCK_COMMENT_ANNOTATION = re.compile("^(?:\s|\*)*@(\w*)\s+((?:\w|:)*)", re.MULTILINE)
RE_HEX_NUMBER = re.compile("([0-9A-Fa-fxX]+)")
RE_BLOCK_COMMENT_ANNOTATION = re.compile("^(?:\s|\*)*@(\w*)\s+((?:[\w:\.])*)", re.MULTILINE)
RE_HEX_NUMBER = re.compile("([\.\-0-9A-Za-z]+)")


class JEnum:
    def __init__(self, name):
    def __init__(self, package, name):
        self.package = package
        self.name = name
        self.values = []

class Enum:
    def __init__(self, package, name, text, imports):
        self.text = text
        self.parsed = False
        self.imports = imports
        self.jenum = JEnum(package, name)

class Converter:
    # Only addition is supported for now, but that covers all existing properties except
    # OBD diagnostics, which use bitwise shifts
    def calculateValue(self, expression, default_value):
    def parse(self, enums):
        if self.parsed:
            return
        for dep in self.imports:
            enums[dep].parse(enums)
        print("Parsing " + self.jenum.name)
        matches = RE_COMMENT.findall(self.text)
        defaultValue = 0
        for match in matches:
            value = dict()
            value['name'] = match[1]
            value['value'] = self.calculateValue(match[2], defaultValue, enums)
            defaultValue = value['value'] + 1
            if self.jenum.name == "VehicleProperty":
                block_comment = match[0]
                self.parseBlockComment(value, block_comment)
            self.jenum.values.append(value)
        self.parsed = True
        self.text = None

    def get_value(self, value_name):
        for value in self.jenum.values:
            if value['name'] == value_name:
                return value['value']
        raise Exception("Cannot decode value: " + self.jenum.package + " : " + value_name)

    def calculateValue(self, expression, default_value, enums):
        numbers = RE_HEX_NUMBER.findall(expression)
        if len(numbers) == 0:
            return default_value
@@ -44,6 +77,12 @@ class Converter:
        if numbers[0].lower().startswith("0x"):
            base = 16
        for number in numbers:
            if '.' in number:
                package, val_name = number.split('.')
                for dep in self.imports:
                    if package in dep:
                        result += enums[dep].get_value(val_name)
            else:
                result += int(number, base)
        return result

@@ -54,30 +93,22 @@ class Converter:
            break
        annots_res = RE_BLOCK_COMMENT_ANNOTATION.findall(blockComment)
        for annot in annots_res:
            value[annot[0]] = annot[1]

    def parseEnumContents(self, enum: JEnum, enumValue):
        matches = RE_COMMENT.findall(enumValue)
        defaultValue = 0
        for match in matches:
            value = dict()
            value['name'] = match[1]
            value['value'] = self.calculateValue(match[2], defaultValue)
            defaultValue = value['value'] + 1
            if enum.name == "VehicleProperty":
                block_comment = match[0]
                self.parseBlockComment(value, block_comment)
            enum.values.append(value)
            value[annot[0]] = annot[1].replace(".", ":")

class Converter:
    # Only addition is supported for now, but that covers all existing properties except
    # OBD diagnostics, which use bitwise shifts
    def convert(self, input):
        text = Path(input).read_text()
        matches = RE_ENUM.findall(text)
        jenums = []
        package = RE_PACKAGE.findall(text)[0]
        imports = RE_IMPORT.findall(text)
        enums = []
        for match in matches:
            enum = JEnum(match[0])
            self.parseEnumContents(enum, match[1])
            jenums.append(enum)
        return jenums
            enum = Enum(package, match[0], match[1], imports)
            enums.append(enum)
        return enums


def main():
    if (len(sys.argv) != 3):
@@ -85,10 +116,18 @@ def main():
        sys.exit(1)
    aidl_path = sys.argv[1]
    out_path = sys.argv[2]
    result = []
    enums_dict = dict()
    for file in os.listdir(aidl_path):
        result.extend(Converter().convert(os.path.join(aidl_path, file)))
    json_result = json.dumps(result, default=vars, indent=2)
        enums = Converter().convert(os.path.join(aidl_path, file))
        for enum in enums:
            enums_dict[enum.jenum.package + "." + enum.jenum.name] = enum

    result = []
    for enum_name, enum in enums_dict.items():
        enum.parse(enums_dict)
        result.append(enum.jenum.__dict__)

    json_result = json.dumps(result, default=None, indent=2)
    with open(out_path, 'w') as f:
        f.write(json_result)