16f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski#!/usr/bin/env python
26f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
36f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiimport sys
46f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiimport xml.etree.ElementTree as ET
56f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
66f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskidef findSdkLevelForAttribute(id):
76f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    intId = int(id, 16)
86f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    packageId = 0x000000ff & (intId >> 24)
96f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    typeId = 0x000000ff & (intId >> 16)
106f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    entryId = 0x0000ffff & intId
116f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
126f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if packageId != 0x01 or typeId != 0x01:
136f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        return 0
146f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
156f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    levels = [(1, 0x021c), (2, 0x021d), (3, 0x0269), (4, 0x028d),
166f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski              (5, 0x02ad), (6, 0x02b3), (7, 0x02b5), (8, 0x02bd),
176f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski              (9, 0x02cb), (11, 0x0361), (12, 0x0366), (13, 0x03a6),
186f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski              (16, 0x03ae), (17, 0x03cc), (18, 0x03da), (19, 0x03f1),
196f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski              (20, 0x03f6), (21, 0x04ce)]
206f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    for level, attrEntryId in levels:
216f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if entryId <= attrEntryId:
226f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            return level
236f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    return 22
246f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
256f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
266f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskitree = None
276f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiwith open(sys.argv[1], 'rt') as f:
286f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    tree = ET.parse(f)
296f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
306f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiattrs = []
316f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskifor node in tree.iter('public'):
326f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski    if node.get('type') == 'attr':
336f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        sdkLevel = findSdkLevelForAttribute(node.get('id', '0'))
346f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski        if sdkLevel > 1 and sdkLevel < 22:
356f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski            attrs.append("{{ u\"{}\", {} }}".format(node.get('name'), sdkLevel))
366f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinski
376f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint "#include <string>"
386f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint "#include <unordered_map>"
396f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint
406f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint "namespace aapt {"
416f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint
426f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint "static std::unordered_map<std::u16string, size_t> sAttrMap = {"
436f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint ",\n    ".join(attrs)
446f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint "};"
456f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint
466f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint "size_t findAttributeSdkLevel(const std::u16string& name) {"
476f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint "    auto iter = sAttrMap.find(name);"
486f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint "    if (iter != sAttrMap.end()) {"
496f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint "        return iter->second;"
506f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint "    }"
516f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint "    return 0;"
526f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint "}"
536f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint
546f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint "} // namespace aapt"
556f6ceb7e1456698b1f33e04536bfb3227f9fcfcbAdam Lesinskiprint
56