177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin#!/usr/bin/python 277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# 477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# Copyright (C) 2012 The Android Open Source Project 577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# 677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# Licensed under the Apache License, Version 2.0 (the "License"); 777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# you may not use this file except in compliance with the License. 877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# You may obtain a copy of the License at 977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# 1077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# http://www.apache.org/licenses/LICENSE-2.0 1177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# 1277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# Unless required by applicable law or agreed to in writing, software 1377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# distributed under the License is distributed on an "AS IS" BASIS, 1477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# See the License for the specific language governing permissions and 1677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# limitations under the License. 1777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# 1877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 1977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin""" 2077b63ca0447545a4dac3ac062f218d878ce01ba0Igor MurashkinA set of classes (models) each closely representing an XML node in the 2177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkinmetadata_properties.xml file. 2277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 2377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Node: Base class for most nodes. 2477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Entry: A node corresponding to <entry> elements. 2577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Clone: A node corresponding to <clone> elements. 26aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin MergedEntry: A node corresponding to either <entry> or <clone> elements. 2777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Kind: A node corresponding to <dynamic>, <static>, <controls> elements. 2877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin InnerNamespace: A node corresponding to a <namespace> nested under a <kind>. 2977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin OuterNamespace: A node corresponding to a <namespace> with <kind> children. 3077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Section: A node corresponding to a <section> element. 3177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Enum: A class corresponding an <enum> element within an <entry> 32aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin EnumValue: A class corresponding to a <value> element within an Enum 3377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Metadata: Root node that also provides tree construction functionality. 3477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Tag: A node corresponding to a top level <tag> element. 35b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin Typedef: A node corresponding to a <typedef> element under <types>. 3677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin""" 3777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 3877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkinimport sys 395804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkinimport itertools 40586c861e6dab3fdf48fc8440c719ad0b59d49d72Igor Murashkinfrom collections import OrderedDict 4177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 4277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkinclass Node(object): 4377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 4477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Base class for most nodes that are part of the Metadata graph. 4577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 4677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Attributes (Read-Only): 4777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin parent: An edge to a parent Node. 4877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin name: A string describing the name, usually but not always the 'name' 4977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin attribute of the corresponding XML node. 5077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 5177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 5277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def __init__(self): 5377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._parent = None 5477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._name = None 5577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 5677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 5777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def parent(self): 5877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._parent 5977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 6077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 6177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def name(self): 6277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._name 6377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 6477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def find_all(self, pred): 6577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 6677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Find all descendants that match the predicate. 6777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 6877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Args: 6977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin pred: a predicate function that acts as a filter for a Node 7077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 7177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Yields: 7277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin A sequence of all descendants for which pred(node) is true, 7377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin in a pre-order visit order. 7477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 7577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if pred(self): 7677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin yield self 7777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 7877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if self._get_children() is None: 7977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return 8077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 8177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for i in self._get_children(): 8277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for j in i.find_all(pred): 8377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin yield j 8477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 8577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def find_first(self, pred): 8677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 8777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Find the first descendant that matches the predicate. 8877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 8977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Args: 9077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin pred: a predicate function that acts as a filter for a Node 9177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 9277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Returns: 9377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin The first Node from find_all(pred), or None if there were no results. 9477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 9577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for i in self.find_all(pred): 9677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return i 9777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 9877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return None 9977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 10077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def find_parent_first(self, pred): 10177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 10277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Find the first ancestor that matches the predicate. 10377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 10477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Args: 10577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin pred: A predicate function that acts as a filter for a Node 10677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 10777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Returns: 10877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin The first ancestor closest to the node for which pred(node) is true. 10977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 11077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for i in self.find_parents(pred): 11177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return i 11277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 11377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return None 11477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 11577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def find_parents(self, pred): 11677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 11777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Find all ancestors that match the predicate. 11877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 11977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Args: 12077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin pred: A predicate function that acts as a filter for a Node 12177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 12277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Yields: 12377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin A sequence of all ancestors (closest to furthest) from the node, 12477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin where pred(node) is true. 12577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 12677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin parent = self.parent 12777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 12877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin while parent is not None: 12977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if pred(parent): 13077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin yield parent 13177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin parent = parent.parent 13277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 13377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def sort_children(self): 13477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 13577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Sorts the immediate children in-place. 13677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 13777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._sort_by_name(self._children) 13877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 13977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _sort_by_name(self, what): 14077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin what.sort(key=lambda x: x.name) 14177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 14277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _get_name(self): 14377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return lambda x: x.name 14477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 14577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # Iterate over all children nodes. None when node doesn't support children. 14677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _get_children(self): 14777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return (i for i in self._children) 14877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 14977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _children_name_map_matching(self, match=lambda x: True): 15077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin d = {} 151aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin for i in self._get_children(): 15277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if match(i): 15377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin d[i.name] = i 15477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return d 15577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 15677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @staticmethod 15777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _dictionary_by_name(values): 158586c861e6dab3fdf48fc8440c719ad0b59d49d72Igor Murashkin d = OrderedDict() 15977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for i in values: 16077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin d[i.name] = i 16177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 16277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return d 16377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 16477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def validate_tree(self): 16577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 16677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Sanity check the tree recursively, ensuring for a node n, all children's 16777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin parents are also n. 16877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 16977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Returns: 17077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin True if validation succeeds, False otherwise. 17177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 17277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin succ = True 17377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin children = self._get_children() 17477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if children is None: 17577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return True 17677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 17777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for child in self._get_children(): 17877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if child.parent != self: 17977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin print >> sys.stderr, ("ERROR: Node '%s' doesn't match the parent" + \ 18077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin "(expected: %s, actual %s)") \ 18177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin %(child, self, child.parent) 18277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin succ = False 18377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 18477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin succ = child.validate_tree() and succ 18577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 18677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return succ 18777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 18877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def __str__(self): 18977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return "<%s name='%s'>" %(self.__class__, self.name) 19077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 19177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkinclass Metadata(Node): 19277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 19377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin A node corresponding to a <metadata> entry. 19477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 19577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Attributes (Read-Only): 19677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin parent: An edge to the parent Node. This is always None for Metadata. 19777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin outer_namespaces: A sequence of immediate OuterNamespace children. 19877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin tags: A sequence of all Tag instances available in the graph. 199b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin types: An iterable of all Typedef instances available in the graph. 20077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 20177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 20277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def __init__(self): 20377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 20477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Initialize with no children. Use insert_* functions and then 20577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin construct_graph() to build up the Metadata from some source. 20677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 20777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# Private 20877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._entries = [] 20977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # kind => { name => entry } 21077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._entry_map = { 'static': {}, 'dynamic': {}, 'controls': {} } 211586c861e6dab3fdf48fc8440c719ad0b59d49d72Igor Murashkin self._entries_ordered = [] # list of ordered Entry/Clone instances 21277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._clones = [] 21377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 21477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin# Public (Read Only) 21563c0fb27d923a32d9a398471ad318bfe84befbebEino-Ville Talvala self._name = None 21677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._parent = None 21777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._outer_namespaces = None 21877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._tags = [] 219b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin self._types = [] 22077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 22177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 22277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def outer_namespaces(self): 22377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if self._outer_namespaces is None: 22477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return None 22577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin else: 22677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return (i for i in self._outer_namespaces) 22777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 22877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 22977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def tags(self): 23077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return (i for i in self._tags) 23177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 232b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin @property 233b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin def types(self): 234b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin return (i for i in self._types) 235b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 23677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _get_properties(self): 23777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 23877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for i in self._entries: 23977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin yield i 24077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 24177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for i in self._clones: 24277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin yield i 24377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 24477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def insert_tag(self, tag, description=""): 24577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 24677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Insert a tag into the metadata. 24777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 24877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Args: 24977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin tag: A string identifier for a tag. 25077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin description: A string description for a tag. 25177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 25277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Example: 25377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin metadata.insert_tag("BC", "Backwards Compatibility for old API") 25477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 25577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Remarks: 25677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Subsequent calls to insert_tag with the same tag are safe (they will 25777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin be ignored). 25877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 25977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin tag_ids = [tg.name for tg in self.tags if tg.name == tag] 26077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if not tag_ids: 2616ad61d460aabf8db9b52e946bb38b8f20717b2a8Igor Murashkin self._tags.append(Tag(tag, self, description)) 26277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 263b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin def insert_type(self, type_name, type_selector="typedef", **kwargs): 264b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin """ 265b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin Insert a type into the metadata. 266b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 267b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin Args: 268b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin type_name: A type's name 269b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin type_selector: The selector for the type, e.g. 'typedef' 270b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 271b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin Args (if type_selector == 'typedef'): 272b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin languages: A map of 'language name' -> 'fully qualified class path' 273b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 274b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin Example: 275b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin metadata.insert_type('rectangle', 'typedef', 276b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin { 'java': 'android.graphics.Rect' }) 277b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 278b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin Remarks: 279b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin Subsequent calls to insert_type with the same type name are safe (they 280b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin will be ignored) 281b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin """ 282b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 283b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin if type_selector != 'typedef': 284b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin raise ValueError("Unsupported type_selector given " + type_selector) 285b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 286b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin type_names = [tp.name for tp in self.types if tp.name == tp] 287b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin if not type_names: 288b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin self._types.append(Typedef(type_name, self, kwargs.get('languages'))) 289b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 29077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def insert_entry(self, entry): 29177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 29277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Insert an entry into the metadata. 29377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 29477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Args: 29577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry: A key-value dictionary describing an entry. Refer to 29677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Entry#__init__ for the keys required/optional. 29777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 29877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Remarks: 29977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Subsequent calls to insert_entry with the same entry+kind name are safe 30077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin (they will be ignored). 30177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 30277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin e = Entry(**entry) 30377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._entries.append(e) 30477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._entry_map[e.kind][e.name] = e 305586c861e6dab3fdf48fc8440c719ad0b59d49d72Igor Murashkin self._entries_ordered.append(e) 30677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 30777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def insert_clone(self, clone): 30877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 30977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Insert a clone into the metadata. 31077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 31177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Args: 31277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin clone: A key-value dictionary describing a clone. Refer to 31377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Clone#__init__ for the keys required/optional. 31477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 31577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Remarks: 31677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Subsequent calls to insert_clone with the same clone+kind name are safe 31777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin (they will be ignored). Also the target entry need not be inserted 31877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ahead of the clone entry. 31977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 32077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # figure out corresponding entry later. allow clone insert, entry insert 32177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry = None 32277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin c = Clone(entry, **clone) 32377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._entry_map[c.kind][c.name] = c 32477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._clones.append(c) 325586c861e6dab3fdf48fc8440c719ad0b59d49d72Igor Murashkin self._entries_ordered.append(c) 32677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 32777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def prune_clones(self): 32877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 32977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Remove all clones that don't point to an existing entry. 33077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 33177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Remarks: 33277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin This should be called after all insert_entry/insert_clone calls have 33377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin finished. 33477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 33577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin remove_list = [] 33677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for p in self._clones: 33777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if p.entry is None: 33877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin remove_list.append(p) 33977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 34077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for p in remove_list: 34177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 34277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # remove from parent's entries list 34377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if p.parent is not None: 34477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin p.parent._entries.remove(p) 34577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # remove from parents' _leafs list 346aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin for ancestor in p.find_parents(lambda x: not isinstance(x, Metadata)): 34777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ancestor._leafs.remove(p) 34877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 34977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # remove from global list 35077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._clones.remove(p) 35177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._entry_map[p.kind].pop(p.name) 352586c861e6dab3fdf48fc8440c719ad0b59d49d72Igor Murashkin self._entries_ordered.remove(p) 35377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 35477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 35577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # After all entries/clones are inserted, 35677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # invoke this to generate the parent/child node graph all these objects 35777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def construct_graph(self): 35877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 35977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Generate the graph recursively, after which all Entry nodes will be 36077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin accessible recursively by crawling through the outer_namespaces sequence. 36177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 36277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Remarks: 36377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin This is safe to be called multiple times at any time. It should be done at 36477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin least once or there will be no graph. 36577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 36677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self.validate_tree() 36777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._construct_tags() 36877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self.validate_tree() 369b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin self._construct_types() 370b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin self.validate_tree() 37177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._construct_clones() 37277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self.validate_tree() 37377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._construct_outer_namespaces() 37477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self.validate_tree() 37577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 37677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _construct_tags(self): 37777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin tag_dict = self._dictionary_by_name(self.tags) 37877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for p in self._get_properties(): 37977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin p._tags = [] 38077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for tag_id in p._tag_ids: 38177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin tag = tag_dict.get(tag_id) 38277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 38377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if tag not in p._tags: 38477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin p._tags.append(tag) 38577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 386617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin if p not in tag.entries: 387617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin tag._entries.append(p) 388617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin 389b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin def _construct_types(self): 390b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin type_dict = self._dictionary_by_name(self.types) 391b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin for p in self._get_properties(): 392b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin if p._type_name: 393b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin type_node = type_dict.get(p._type_name) 394b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin p._typedef = type_node 395b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 396b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin if p not in type_node.entries: 397b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin type_node._entries.append(p) 398b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 39977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _construct_clones(self): 40077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for p in self._clones: 40177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin target_kind = p.target_kind 40277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin target_entry = self._entry_map[target_kind].get(p.name) 40377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin p._entry = target_entry 40477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 40577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # should not throw if we pass validation 40677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # but can happen when importing obsolete CSV entries 40777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if target_entry is None: 40877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin print >> sys.stderr, ("WARNING: Clone entry '%s' target kind '%s'" + \ 40977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin " has no corresponding entry") \ 41077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin %(p.name, p.target_kind) 41177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 41277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _construct_outer_namespaces(self): 41377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 41477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if self._outer_namespaces is None: #the first time this runs 41577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._outer_namespaces = [] 41677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 41777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin root = self._dictionary_by_name(self._outer_namespaces) 41877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for ons_name, ons in root.iteritems(): 41977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ons._leafs = [] 42077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 421586c861e6dab3fdf48fc8440c719ad0b59d49d72Igor Murashkin for p in self._entries_ordered: 42277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ons_name = p.get_outer_namespace() 42377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ons = root.get(ons_name, OuterNamespace(ons_name, self)) 42477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin root[ons_name] = ons 42577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 42677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if p not in ons._leafs: 42777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ons._leafs.append(p) 42877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 42977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for ons_name, ons in root.iteritems(): 43077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 43177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ons.validate_tree() 43277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 43377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._construct_sections(ons) 43477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 43577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if ons not in self._outer_namespaces: 43677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._outer_namespaces.append(ons) 43777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 43877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ons.validate_tree() 43977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 44077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _construct_sections(self, outer_namespace): 44177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 44277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin sections_dict = self._dictionary_by_name(outer_namespace.sections) 44377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for sec_name, sec in sections_dict.iteritems(): 44477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin sec._leafs = [] 44577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin sec.validate_tree() 44677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 44777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for p in outer_namespace._leafs: 44877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin does_exist = sections_dict.get(p.get_section()) 44977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 45077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin sec = sections_dict.get(p.get_section(), \ 45177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Section(p.get_section(), outer_namespace)) 45277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin sections_dict[p.get_section()] = sec 45377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 45477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin sec.validate_tree() 45577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 45677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if p not in sec._leafs: 45777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin sec._leafs.append(p) 45877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 45977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for sec_name, sec in sections_dict.iteritems(): 46077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 46177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if not sec.validate_tree(): 46277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin print >> sys.stderr, ("ERROR: Failed to validate tree in " + \ 46377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin "construct_sections (start), with section = '%s'")\ 46477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin %(sec) 46577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 46677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._construct_kinds(sec) 46777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 46877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if sec not in outer_namespace.sections: 46977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin outer_namespace._sections.append(sec) 47077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 47177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if not sec.validate_tree(): 47277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin print >> sys.stderr, ("ERROR: Failed to validate tree in " + \ 47377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin "construct_sections (end), with section = '%s'") \ 47477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin %(sec) 47577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 47677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # 'controls', 'static' 'dynamic'. etc 47777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _construct_kinds(self, section): 4785804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin for kind in section.kinds: 47977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin kind._leafs = [] 48077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin section.validate_tree() 48177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 4825804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin group_entry_by_kind = itertools.groupby(section._leafs, lambda x: x.kind) 4835804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin leaf_it = ((k, g) for k, g in group_entry_by_kind) 48477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 4855804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin # allow multiple kinds with the same name. merge if adjacent 4865804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin # e.g. dynamic,dynamic,static,static,dynamic -> dynamic,static,dynamic 4875804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin # this helps maintain ABI compatibility when adding an entry in a new kind 4885804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin for idx, (kind_name, entry_it) in enumerate(leaf_it): 4895804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin if idx >= len(section._kinds): 4905804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin kind = Kind(kind_name, section) 4915804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin section._kinds.append(kind) 4925804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin section.validate_tree() 49377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 4945804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin kind = section._kinds[idx] 49577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 4965804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin for p in entry_it: 4975804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin if p not in kind._leafs: 4985804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin kind._leafs.append(p) 49977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 5005804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin for kind in section._kinds: 50177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin kind.validate_tree() 50277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._construct_inner_namespaces(kind) 50377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin kind.validate_tree() 50477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._construct_entries(kind) 50577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin kind.validate_tree() 50677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 50777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if not section.validate_tree(): 50877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin print >> sys.stderr, ("ERROR: Failed to validate tree in " + \ 50977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin "construct_kinds, with kind = '%s'") %(kind) 51077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 51177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if not kind.validate_tree(): 51277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin print >> sys.stderr, ("ERROR: Failed to validate tree in " + \ 51377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin "construct_kinds, with kind = '%s'") %(kind) 51477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 51577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _construct_inner_namespaces(self, parent, depth=0): 51677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin #parent is InnerNamespace or Kind 51777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ins_dict = self._dictionary_by_name(parent.namespaces) 51877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for name, ins in ins_dict.iteritems(): 51977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ins._leafs = [] 52077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 52177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for p in parent._leafs: 52277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ins_list = p.get_inner_namespace_list() 52377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 52477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if len(ins_list) > depth: 52577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ins_str = ins_list[depth] 52677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ins = ins_dict.get(ins_str, InnerNamespace(ins_str, parent)) 52777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ins_dict[ins_str] = ins 52877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 52977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if p not in ins._leafs: 53077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ins._leafs.append(p) 53177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 53277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for name, ins in ins_dict.iteritems(): 53377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ins.validate_tree() 53477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # construct children INS 53577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._construct_inner_namespaces(ins, depth + 1) 53677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ins.validate_tree() 53777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # construct children entries 53877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._construct_entries(ins, depth + 1) 53977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 54077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if ins not in parent.namespaces: 54177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin parent._namespaces.append(ins) 54277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 54377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if not ins.validate_tree(): 54477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin print >> sys.stderr, ("ERROR: Failed to validate tree in " + \ 54577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin "construct_inner_namespaces, with ins = '%s'") \ 54677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin %(ins) 54777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 54877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # doesnt construct the entries, so much as links them 54977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _construct_entries(self, parent, depth=0): 55077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin #parent is InnerNamespace or Kind 55177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry_dict = self._dictionary_by_name(parent.entries) 55277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for p in parent._leafs: 55377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ins_list = p.get_inner_namespace_list() 55477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 55577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if len(ins_list) == depth: 55677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry = entry_dict.get(p.name, p) 55777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry_dict[p.name] = entry 55877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 55977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for name, entry in entry_dict.iteritems(): 56077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 56177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin old_parent = entry.parent 56277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry._parent = parent 56377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 56477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if entry not in parent.entries: 56577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin parent._entries.append(entry) 56677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 56777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if old_parent is not None and old_parent != parent: 56877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin print >> sys.stderr, ("ERROR: Parent changed from '%s' to '%s' for " + \ 56977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin "entry '%s'") \ 57077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin %(old_parent.name, parent.name, entry.name) 57177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 57277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _get_children(self): 57377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if self.outer_namespaces is not None: 57477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for i in self.outer_namespaces: 57577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin yield i 57677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 57777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if self.tags is not None: 57877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for i in self.tags: 57977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin yield i 58077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 58177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkinclass Tag(Node): 58277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 58377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin A tag Node corresponding to a top-level <tag> element. 58477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 58577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Attributes (Read-Only): 58677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin name: alias for id 58777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin id: The name of the tag, e.g. for <tag id="BC"/> id = 'BC' 58877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin description: The description of the tag, the contents of the <tag> element. 58977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin parent: An edge to the parent, which is always the Metadata root node. 59077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entries: A sequence of edges to entries/clones that are using this Tag. 59177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 59277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def __init__(self, name, parent, description=""): 59377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._name = name # 'id' attribute in XML 59477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._id = name 59577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._description = description 59677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._parent = parent 59777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 59877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # all entries that have this tag, including clones 599617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin self._entries = [] # filled in by Metadata#construct_tags 60077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 60177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 60277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def id(self): 60377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._id 60477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 60577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 60677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def description(self): 60777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._description 60877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 60977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 61077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def entries(self): 61177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return (i for i in self._entries) 61277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 61377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _get_children(self): 61477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return None 61577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 616b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkinclass Typedef(Node): 617b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin """ 618b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin A typedef Node corresponding to a <typedef> element under a top-level <types>. 619b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 620b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin Attributes (Read-Only): 621b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin name: The name of this typedef as a string. 622b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin languages: A dictionary of 'language name' -> 'fully qualified class'. 623b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin parent: An edge to the parent, which is always the Metadata root node. 624b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin entries: An iterable over all entries which reference this typedef. 625b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin """ 626b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin def __init__(self, name, parent, languages=None): 627b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin self._name = name 628b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin self._parent = parent 629b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 630b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin # all entries that have this typedef 631b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin self._entries = [] # filled in by Metadata#construct_types 632b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 633b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin self._languages = languages or {} 634b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 635b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin @property 636b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin def languages(self): 637b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin return self._languages 638b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 639b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin @property 640b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin def entries(self): 641b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin return (i for i in self._entries) 642b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 643b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin def _get_children(self): 644b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin return None 645b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 64677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkinclass OuterNamespace(Node): 64777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 64877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin A node corresponding to a <namespace> element under <metadata> 64977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 65077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Attributes (Read-Only): 65177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin name: The name attribute of the <namespace name="foo"> element. 65277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin parent: An edge to the parent, which is always the Metadata root node. 65377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin sections: A sequence of Section children. 65477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 65577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def __init__(self, name, parent, sections=[]): 65677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._name = name 65777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._parent = parent # MetadataSet 65877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._sections = sections[:] 65977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._leafs = [] 66077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 66177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._children = self._sections 66277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 66377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 66477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def sections(self): 66577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return (i for i in self._sections) 66677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 66777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkinclass Section(Node): 66877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 66977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin A node corresponding to a <section> element under <namespace> 67077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 67177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Attributes (Read-Only): 67277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin name: The name attribute of the <section name="foo"> element. 67377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin parent: An edge to the parent, which is always an OuterNamespace instance. 67477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin description: A string description of the section, or None. 67577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin kinds: A sequence of Kind children. 6765804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin merged_kinds: A sequence of virtual Kind children, 6775804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin with each Kind's children merged by the kind.name 67877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 67977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def __init__(self, name, parent, description=None, kinds=[]): 68077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._name = name 68177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._parent = parent 68277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._description = description 68377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._kinds = kinds[:] 68477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 68577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._leafs = [] 68677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 68777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 68877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 68977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def description(self): 69077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._description 69177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 69277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 69377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def kinds(self): 69477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return (i for i in self._kinds) 69577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 69677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def sort_children(self): 69777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self.validate_tree() 69877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # order is always controls,static,dynamic 69977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin find_child = lambda x: [i for i in self._get_children() if i.name == x] 70077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin new_lst = find_child('controls') \ 70177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin + find_child('static') \ 70277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin + find_child('dynamic') 70377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._kinds = new_lst 70477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self.validate_tree() 70577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 70677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _get_children(self): 70777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return (i for i in self.kinds) 70877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 7095804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin @property 7105804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin def merged_kinds(self): 7115804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin 7125804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin def aggregate_by_name(acc, el): 7135804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin existing = [i for i in acc if i.name == el.name] 7145804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin if existing: 7155804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin k = existing[0] 7165804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin else: 7175804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin k = Kind(el.name, el.parent) 7185804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin acc.append(k) 7195804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin 7205804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin k._namespaces.extend(el._namespaces) 7215804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin k._entries.extend(el._entries) 7225804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin 7235804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin return acc 7245804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin 7255804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin new_kinds_lst = reduce(aggregate_by_name, self.kinds, []) 7265804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin 7275804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin for k in new_kinds_lst: 7285804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin yield k 7295804a48bb15d245fb06f72cf6d64369f151fcc28Igor Murashkin 730aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin def combine_kinds_into_single_node(self): 731aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin r""" 732aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin Combines the section's Kinds into a single node. 733aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 734aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin Combines all the children (kinds) of this section into a single 735aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin virtual Kind node. 736aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 737aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin Returns: 738aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin A new Kind node that collapses all Kind siblings into one, combining 739aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin all their children together. 740aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 741aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin For example, given self.kinds == [ x, y ] 742aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 743aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin x y z 744aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin / | | \ --> / | | \ 745aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin a b c d a b c d 746aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 747aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin a new instance z is returned in this example. 748aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 749aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin Remarks: 750aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin The children of the kinds are the same references as before, that is 751aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin their parents will point to the old parents and not to the new parent. 752aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin """ 753aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin combined = Kind(name="combined", parent=self) 754aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 755aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin for k in self._get_children(): 756aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin combined._namespaces.extend(k.namespaces) 757aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin combined._entries.extend(k.entries) 758aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 759aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin return combined 760aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 76177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkinclass Kind(Node): 76277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 76377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin A node corresponding to one of: <static>,<dynamic>,<controls> under a 76477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin <section> element. 76577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 76677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Attributes (Read-Only): 76777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin name: A string which is one of 'static', 'dynamic, or 'controls'. 76877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin parent: An edge to the parent, which is always a Section instance. 76977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin namespaces: A sequence of InnerNamespace children. 77077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entries: A sequence of Entry/Clone children. 771617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin merged_entries: A sequence of MergedEntry virtual nodes from entries 77277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 77377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def __init__(self, name, parent): 77477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._name = name 77577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._parent = parent 77677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._namespaces = [] 77777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._entries = [] 77877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 77977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._leafs = [] 78077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 78177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 78277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def namespaces(self): 78377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._namespaces 78477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 78577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 78677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def entries(self): 78777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._entries 78877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 789617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin @property 790617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin def merged_entries(self): 791617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin for i in self.entries: 792617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin yield i.merge() 793617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin 79477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def sort_children(self): 79577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._namespaces.sort(key=self._get_name()) 79677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._entries.sort(key=self._get_name()) 79777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 79877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _get_children(self): 79977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for i in self.namespaces: 80077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin yield i 80177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for i in self.entries: 80277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin yield i 80377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 804aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin def combine_children_by_name(self): 805aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin r""" 806aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin Combine multiple children with the same name into a single node. 807aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 808aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin Returns: 809aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin A new Kind where all of the children with the same name were combined. 810aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 811aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin For example: 812aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 813aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin Given a Kind k: 814aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 815aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin k 816aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin / | \ 817aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin a b c 818aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin | | | 819aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin d e f 820aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 821aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin a.name == "foo" 822aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin b.name == "foo" 823aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin c.name == "bar" 824aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 825aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin The returned Kind will look like this: 826aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 827aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin k' 828aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin / \ 829aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin a' c' 830aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin / | | 831aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin d e f 832aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 833aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin Remarks: 834aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin This operation is not recursive. To combine the grandchildren and other 835aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin ancestors, call this method on the ancestor nodes. 836aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin """ 837aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin return Kind._combine_children_by_name(self, new_type=type(self)) 838aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 839aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin # new_type is either Kind or InnerNamespace 840aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin @staticmethod 841aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin def _combine_children_by_name(self, new_type): 842aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin new_ins_dict = OrderedDict() 843aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin new_ent_dict = OrderedDict() 844aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 845aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin for ins in self.namespaces: 846aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin new_ins = new_ins_dict.setdefault(ins.name, 847aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin InnerNamespace(ins.name, parent=self)) 848aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin new_ins._namespaces.extend(ins.namespaces) 849aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin new_ins._entries.extend(ins.entries) 850aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 851aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin for ent in self.entries: 852aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin new_ent = new_ent_dict.setdefault(ent.name, 853aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin ent.merge()) 854aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 855aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin kind = new_type(self.name, self.parent) 856aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin kind._namespaces = new_ins_dict.values() 857aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin kind._entries = new_ent_dict.values() 858aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 859aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin return kind 860aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 86177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkinclass InnerNamespace(Node): 86277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 86377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin A node corresponding to a <namespace> which is an ancestor of a Kind. 86477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin These namespaces may have other namespaces recursively, or entries as leafs. 86577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 86677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Attributes (Read-Only): 86777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin name: Name attribute from the element, e.g. <namespace name="foo"> -> 'foo' 86877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin parent: An edge to the parent, which is an InnerNamespace or a Kind. 86977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin namespaces: A sequence of InnerNamespace children. 87077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entries: A sequence of Entry/Clone children. 871617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin merged_entries: A sequence of MergedEntry virtual nodes from entries 87277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 87377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def __init__(self, name, parent): 87477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._name = name 87577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._parent = parent 87677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._namespaces = [] 87777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._entries = [] 87877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._leafs = [] 87977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 88077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 88177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def namespaces(self): 88277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._namespaces 88377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 88477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 88577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def entries(self): 88677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._entries 88777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 888617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin @property 889617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin def merged_entries(self): 890617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin for i in self.entries: 891617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin yield i.merge() 892617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin 89377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def sort_children(self): 89477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._namespaces.sort(key=self._get_name()) 89577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._entries.sort(key=self._get_name()) 89677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 89777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _get_children(self): 89877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for i in self.namespaces: 89977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin yield i 90077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for i in self.entries: 90177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin yield i 90277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 903aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin def combine_children_by_name(self): 904aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin r""" 905aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin Combine multiple children with the same name into a single node. 906aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 907aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin Returns: 908aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin A new InnerNamespace where all of the children with the same name were 909aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin combined. 910aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 911aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin For example: 912aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 913aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin Given an InnerNamespace i: 914aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 915aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin i 916aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin / | \ 917aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin a b c 918aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin | | | 919aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin d e f 920aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 921aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin a.name == "foo" 922aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin b.name == "foo" 923aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin c.name == "bar" 924aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 925aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin The returned InnerNamespace will look like this: 926aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 927aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin i' 928aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin / \ 929aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin a' c' 930aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin / | | 931aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin d e f 932aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 933aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin Remarks: 934aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin This operation is not recursive. To combine the grandchildren and other 935aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin ancestors, call this method on the ancestor nodes. 936aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin """ 937aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin return Kind._combine_children_by_name(self, new_type=type(self)) 938aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 939375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkinclass EnumValue(Node): 94077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 94177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin A class corresponding to a <value> element within an <enum> within an <entry>. 94277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 94377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Attributes (Read-Only): 94477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin name: A string, e.g. 'ON' or 'OFF' 94577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin id: An optional numeric string, e.g. '0' or '0xFF' 94677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin optional: A boolean 947b432916043290beb246054a77f8978b3136f4315Eino-Ville Talvala hidden: A boolean, True if the enum should be hidden. 94877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin notes: A string describing the notes, or None. 949375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin parent: An edge to the parent, always an Enum instance. 95077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 951b432916043290beb246054a77f8978b3136f4315Eino-Ville Talvala def __init__(self, name, parent, id=None, optional=False, hidden=False, notes=None): 95277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._name = name # str, e.g. 'ON' or 'OFF' 95377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._id = id # int, e.g. '0' 95477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._optional = optional # bool 955b432916043290beb246054a77f8978b3136f4315Eino-Ville Talvala self._hidden = hidden # bool 95677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._notes = notes # None or str 957375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin self._parent = parent 95877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 95977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 96077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def id(self): 96177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._id 96277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 96377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 96477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def optional(self): 96577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._optional 96677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 96777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 968b432916043290beb246054a77f8978b3136f4315Eino-Ville Talvala def hidden(self): 969b432916043290beb246054a77f8978b3136f4315Eino-Ville Talvala return self._hidden 970b432916043290beb246054a77f8978b3136f4315Eino-Ville Talvala 971b432916043290beb246054a77f8978b3136f4315Eino-Ville Talvala @property 97277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def notes(self): 97377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._notes 97477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 975375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin def _get_children(self): 976375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin return None 977375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin 978375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkinclass Enum(Node): 97977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 98077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin A class corresponding to an <enum> element within an <entry>. 98177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 98277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Attributes (Read-Only): 98377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin parent: An edge to the parent, always an Entry instance. 98477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin values: A sequence of EnumValue children. 985aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin has_values_with_id: A boolean representing if any of the children have a 986aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin non-empty id property. 98777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 988b432916043290beb246054a77f8978b3136f4315Eino-Ville Talvala def __init__(self, parent, values, ids={}, optionals=[], hiddens=[], notes={}): 98977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._values = \ 990b432916043290beb246054a77f8978b3136f4315Eino-Ville Talvala [ EnumValue(val, self, ids.get(val), val in optionals, val in hiddens, \ 991b432916043290beb246054a77f8978b3136f4315Eino-Ville Talvala notes.get(val)) \ 99277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for val in values ] 99377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 99477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._parent = parent 995375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin self._name = None 99677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 99777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 99877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def values(self): 99977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return (i for i in self._values) 100077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 1001aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin @property 1002aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin def has_values_with_id(self): 1003aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin return bool(any(i for i in self.values if i.id)) 1004aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin 1005375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin def _get_children(self): 1006375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin return (i for i in self._values) 1007375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin 100877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkinclass Entry(Node): 100977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 101077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin A node corresponding to an <entry> element. 101177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 101277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Attributes (Read-Only): 101377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin parent: An edge to the parent node, which is an InnerNamespace or Kind. 101477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin name: The fully qualified name string, e.g. 'android.shading.mode' 101577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin name_short: The name attribute from <entry name="mode">, e.g. mode 101677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin type: The type attribute from <entry type="bar"> 101777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin kind: A string ('static', 'dynamic', 'controls') corresponding to the 101877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin ancestor Kind#name 101977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin container: The container attribute from <entry container="array">, or None. 102077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin container_sizes: A sequence of size strings or None if container is None. 1021b556bc47068d816cb319a5d0e2f6841b007b38f2Igor Murashkin enum: An Enum instance if the enum attribute is true, None otherwise. 1022f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala visibility: The visibility of this entry ('system', 'hidden', 'public') 1023f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala across the system. System entries are only visible in native code 1024f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala headers. Hidden entries are marked @hide in managed code, while 1025f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala public entries are visible in the Android SDK. 1026f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala applied_visibility: As visibility, but always valid, defaulting to 'system' 1027f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala if no visibility is given for an entry. 10286c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin synthetic: The C-level visibility of this entry ('false', 'true'). 10296c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin Synthetic entries will not be generated into the native metadata 10306c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin list of entries (in C code). In general a synthetic entry is 10316c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin glued together at the Java layer from multiple visibiltity=hidden 10326c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin entries. 1033ca25627fc63255d147286ef9a9624059825eb548Igor Murashkin hwlevel: The lowest hardware level at which the entry is guaranteed 1034ca25627fc63255d147286ef9a9624059825eb548Igor Murashkin to be supported by the camera device. All devices with higher 1035ca25627fc63255d147286ef9a9624059825eb548Igor Murashkin hwlevels will also include this entry. None means that the 1036ca25627fc63255d147286ef9a9624059825eb548Igor Murashkin entry is optional on any hardware level. 10376c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin deprecated: Marks an entry as @Deprecated in the Java layer; if within an 10386c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin unreleased version this needs to be removed altogether. If applied 10396c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin to an entry from an older release, then this means the entry 10406c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin should be ignored by newer code. 1041ef40ad6249555a0a45c57907f4b9509b59e3e9f5Alex Ray optional: a bool representing the optional attribute, which denotes the entry 1042ef40ad6249555a0a45c57907f4b9509b59e3e9f5Alex Ray is required for hardware level full devices, but optional for other 1043ef40ad6249555a0a45c57907f4b9509b59e3e9f5Alex Ray hardware levels. None if not present. 1044ef40ad6249555a0a45c57907f4b9509b59e3e9f5Alex Ray applied_optional: As optional but always valid, defaulting to False if no 1045ef40ad6249555a0a45c57907f4b9509b59e3e9f5Alex Ray optional attribute is present. 104677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin tuple_values: A sequence of strings describing the tuple values, 104777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin None if container is not 'tuple'. 104877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin description: A string description, or None. 104977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin range: A string range, or None. 105077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin units: A string units, or None. 105177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin tags: A sequence of Tag nodes associated with this Entry. 105277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin type_notes: A string describing notes for the type, or None. 1053b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin typedef: A Typedef associated with this Entry, or None. 105477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 105577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Remarks: 105677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Subclass Clone can be used interchangeable with an Entry, 105777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for when we don't care about the underlying type. 105877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 105977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin parent and tags edges are invalid until after Metadata#construct_graph 106077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin has been invoked. 106177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 106277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def __init__(self, **kwargs): 106377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 106477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Instantiate a new Entry node. 106577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 106677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Args: 106777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin name: A string with the fully qualified name, e.g. 'android.shading.mode' 106877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin type: A string describing the type, e.g. 'int32' 106977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin kind: A string describing the kind, e.g. 'static' 107077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 107177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Args (if container): 107277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin container: A string describing the container, e.g. 'array' or 'tuple' 107377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin container_sizes: A list of string sizes if a container, or None otherwise 107477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 107577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Args (if container is 'tuple'): 107677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin tuple_values: A list of tuple values, e.g. ['width', 'height'] 107777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 1078b556bc47068d816cb319a5d0e2f6841b007b38f2Igor Murashkin Args (if the 'enum' attribute is true): 1079b556bc47068d816cb319a5d0e2f6841b007b38f2Igor Murashkin enum: A boolean, True if this is an enum, False otherwise 108077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin enum_values: A list of value strings, e.g. ['ON', 'OFF'] 108177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin enum_optionals: A list of optional enum values, e.g. ['OFF'] 108277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin enum_notes: A dictionary of value->notes strings. 108377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin enum_ids: A dictionary of value->id strings. 108477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 108577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Args (optional): 108677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin description: A string with a description of the entry. 108777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin range: A string with the range of the values of the entry, e.g. '>= 0' 108877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin units: A string with the units of the values, e.g. 'inches' 1089a5b73c27ddbf032d1b3b4f628ac8fc0846c0ed2cEino-Ville Talvala details: A string with the detailed documentation for the entry 1090a5b73c27ddbf032d1b3b4f628ac8fc0846c0ed2cEino-Ville Talvala hal_details: A string with the HAL implementation details for the entry 109177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin tag_ids: A list of tag ID strings, e.g. ['BC', 'V1'] 109277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin type_notes: A string with the notes for the type 1093f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala visibility: A string describing the visibility, eg 'system', 'hidden', 1094f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala 'public' 10956c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin synthetic: A bool to mark whether this entry is visible only at the Java 10966c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin layer (True), or at both layers (False = default). 1097ca25627fc63255d147286ef9a9624059825eb548Igor Murashkin hwlevel: A string of the HW level (one of 'legacy', 'limited', 'full') 10986c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin deprecated: A bool to mark whether this is @Deprecated at the Java layer 10996c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin (default = False). 1100ef40ad6249555a0a45c57907f4b9509b59e3e9f5Alex Ray optional: A bool to mark whether optional for non-full hardware devices 1101b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin typedef: A string corresponding to a typedef's name attribute. 110277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 110377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 110477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if kwargs.get('type') is None: 110577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin print >> sys.stderr, "ERROR: Missing type for entry '%s' kind '%s'" \ 110677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin %(kwargs.get('name'), kwargs.get('kind')) 110777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 110877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # Attributes are Read-Only, but edges may be mutated by 110977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # Metadata, particularly during construct_graph 111077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 111177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._name = kwargs['name'] 111277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._type = kwargs['type'] 111377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._kind = kwargs['kind'] # static, dynamic, or controls 111477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 111577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._init_common(**kwargs) 111677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 111777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 111877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def type(self): 111977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._type 112077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 112177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 112277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def kind(self): 112377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._kind 112477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 112577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 1126f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala def visibility(self): 1127f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala return self._visibility 1128f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala 1129f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala @property 1130f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala def applied_visibility(self): 1131f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala return self._visibility or 'system' 1132f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala 1133f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala @property 11346c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin def synthetic(self): 11356c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin return self._synthetic 11366c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin 11376c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin @property 1138ca25627fc63255d147286ef9a9624059825eb548Igor Murashkin def hwlevel(self): 1139ca25627fc63255d147286ef9a9624059825eb548Igor Murashkin return self._hwlevel 1140ca25627fc63255d147286ef9a9624059825eb548Igor Murashkin 1141ca25627fc63255d147286ef9a9624059825eb548Igor Murashkin @property 11426c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin def deprecated(self): 11436c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin return self._deprecated 11446c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin 1145ca25627fc63255d147286ef9a9624059825eb548Igor Murashkin # TODO: optional should just return hwlevel is None 11466c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin @property 1147ef40ad6249555a0a45c57907f4b9509b59e3e9f5Alex Ray def optional(self): 1148ef40ad6249555a0a45c57907f4b9509b59e3e9f5Alex Ray return self._optional 1149ef40ad6249555a0a45c57907f4b9509b59e3e9f5Alex Ray 1150ef40ad6249555a0a45c57907f4b9509b59e3e9f5Alex Ray @property 1151ef40ad6249555a0a45c57907f4b9509b59e3e9f5Alex Ray def applied_optional(self): 1152ef40ad6249555a0a45c57907f4b9509b59e3e9f5Alex Ray return self._optional or False 1153ef40ad6249555a0a45c57907f4b9509b59e3e9f5Alex Ray 1154ef40ad6249555a0a45c57907f4b9509b59e3e9f5Alex Ray @property 115577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def name_short(self): 115677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self.get_name_minimal() 115777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 115877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 115977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def container(self): 116077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._container 116177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 116277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 116377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def container_sizes(self): 116477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if self._container_sizes is None: 116577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return None 116677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin else: 116777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return (i for i in self._container_sizes) 116877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 116977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 117077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def tuple_values(self): 117177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if self._tuple_values is None: 117277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return None 117377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin else: 117477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return (i for i in self._tuple_values) 117577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 117677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 117777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def description(self): 117877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._description 117977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 118077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 118177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def range(self): 118277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._range 118377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 118477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 118577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def units(self): 118677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._units 118777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 118877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 1189a5b73c27ddbf032d1b3b4f628ac8fc0846c0ed2cEino-Ville Talvala def details(self): 1190a5b73c27ddbf032d1b3b4f628ac8fc0846c0ed2cEino-Ville Talvala return self._details 1191a5b73c27ddbf032d1b3b4f628ac8fc0846c0ed2cEino-Ville Talvala 1192a5b73c27ddbf032d1b3b4f628ac8fc0846c0ed2cEino-Ville Talvala @property 1193a5b73c27ddbf032d1b3b4f628ac8fc0846c0ed2cEino-Ville Talvala def hal_details(self): 1194a5b73c27ddbf032d1b3b4f628ac8fc0846c0ed2cEino-Ville Talvala return self._hal_details 119577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 119677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 119777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def tags(self): 119877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin if self._tags is None: 119977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return None 120077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin else: 120177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return (i for i in self._tags) 120277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 120377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 120477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def type_notes(self): 120577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._type_notes 120677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 120777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 1208b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin def typedef(self): 1209b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin return self._typedef 1210b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 1211b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin @property 121277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def enum(self): 121377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._enum 121477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 121577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _get_children(self): 1216375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin if self.enum: 1217375cfd3889aa72160273af802370c8f47f5c64d1Igor Murashkin yield self.enum 121877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 121977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def sort_children(self): 122077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return None 122177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 122277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def is_clone(self): 122377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 122477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Whether or not this is a Clone instance. 122577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 122677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Returns: 122777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin False 122877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 122977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return False 123077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 123177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def _init_common(self, **kwargs): 123277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 1233b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin self._parent = None # filled in by Metadata::_construct_entries 123477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 123577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._container = kwargs.get('container') 123677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._container_sizes = kwargs.get('container_sizes') 123777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 123877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # access these via the 'enum' prop 123977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin enum_values = kwargs.get('enum_values') 124077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin enum_optionals = kwargs.get('enum_optionals') 1241b432916043290beb246054a77f8978b3136f4315Eino-Ville Talvala enum_hiddens = kwargs.get('enum_hiddens') 1242aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin enum_notes = kwargs.get('enum_notes') # { value => notes } 1243aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin enum_ids = kwargs.get('enum_ids') # { value => notes } 124477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._tuple_values = kwargs.get('tuple_values') 124577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 124677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._description = kwargs.get('description') 124777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._range = kwargs.get('range') 124877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._units = kwargs.get('units') 1249a5b73c27ddbf032d1b3b4f628ac8fc0846c0ed2cEino-Ville Talvala self._details = kwargs.get('details') 1250a5b73c27ddbf032d1b3b4f628ac8fc0846c0ed2cEino-Ville Talvala self._hal_details = kwargs.get('hal_details') 125177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 125277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._tag_ids = kwargs.get('tag_ids', []) 1253b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin self._tags = None # Filled in by Metadata::_construct_tags 125477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 125577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._type_notes = kwargs.get('type_notes') 1256b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin self._type_name = kwargs.get('type_name') 1257b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin self._typedef = None # Filled in by Metadata::_construct_types 125877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 1259b556bc47068d816cb319a5d0e2f6841b007b38f2Igor Murashkin if kwargs.get('enum', False): 1260b432916043290beb246054a77f8978b3136f4315Eino-Ville Talvala self._enum = Enum(self, enum_values, enum_ids, enum_optionals, 1261b432916043290beb246054a77f8978b3136f4315Eino-Ville Talvala enum_hiddens, enum_notes) 1262617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin else: 1263617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin self._enum = None 126477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 1265f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala self._visibility = kwargs.get('visibility') 12666c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin self._synthetic = kwargs.get('synthetic', False) 1267ca25627fc63255d147286ef9a9624059825eb548Igor Murashkin self._hwlevel = kwargs.get('hwlevel') 12686c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin self._deprecated = kwargs.get('deprecated', False) 1269ef40ad6249555a0a45c57907f4b9509b59e3e9f5Alex Ray self._optional = kwargs.get('optional') 1270f384f0a06cf156c51c4ca584a4323e132c15f64fEino-Ville Talvala 127177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._property_keys = kwargs 127277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 1273617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin def merge(self): 1274617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin """ 1275617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin Copy the attributes into a new entry, merging it with the target entry 1276617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin if it's a clone. 1277617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin """ 1278617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin return MergedEntry(self) 1279617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin 128077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # Helpers for accessing less than the fully qualified name 128177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 128277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def get_name_as_list(self): 128377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 128477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Returns the name as a list split by a period. 128577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 128677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin For example: 128777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry.name is 'android.lens.info.shading' 128877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry.get_name_as_list() == ['android', 'lens', 'info', 'shading'] 128977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 129077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self.name.split(".") 129177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 129277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def get_inner_namespace_list(self): 129377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 129477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Returns the inner namespace part of the name as a list 129577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 129677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin For example: 129777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry.name is 'android.lens.info.shading' 129877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry.get_inner_namespace_list() == ['info'] 129977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 130077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self.get_name_as_list()[2:-1] 130177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 130277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def get_outer_namespace(self): 130377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 130477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Returns the outer namespace as a string. 130577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 130677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin For example: 130777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry.name is 'android.lens.info.shading' 130877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry.get_outer_namespace() == 'android' 130977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 131077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Remarks: 131177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Since outer namespaces are non-recursive, 131277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin and each entry has one, this does not need to be a list. 131377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 131477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self.get_name_as_list()[0] 131577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 131677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def get_section(self): 131777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 131877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Returns the section as a string. 131977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 132077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin For example: 132177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry.name is 'android.lens.info.shading' 132277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry.get_section() == '' 132377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 132477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Remarks: 132577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Since outer namespaces are non-recursive, 132677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin and each entry has one, this does not need to be a list. 132777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 132877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self.get_name_as_list()[1] 132977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 133077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def get_name_minimal(self): 133177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 133277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Returns only the last component of the fully qualified name as a string. 133377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 133477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin For example: 133577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry.name is 'android.lens.info.shading' 133677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry.get_name_minimal() == 'shading' 133777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 133877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Remarks: 133977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry.name_short it an alias for this 134077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 134177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self.get_name_as_list()[-1] 134277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 13437b9a2dccf20bac314258708e55d8c75b2ecf892aIgor Murashkin def get_path_without_name(self): 13447b9a2dccf20bac314258708e55d8c75b2ecf892aIgor Murashkin """ 13457b9a2dccf20bac314258708e55d8c75b2ecf892aIgor Murashkin Returns a string path to the entry, with the name component excluded. 13467b9a2dccf20bac314258708e55d8c75b2ecf892aIgor Murashkin 13477b9a2dccf20bac314258708e55d8c75b2ecf892aIgor Murashkin For example: 13487b9a2dccf20bac314258708e55d8c75b2ecf892aIgor Murashkin entry.name is 'android.lens.info.shading' 13497b9a2dccf20bac314258708e55d8c75b2ecf892aIgor Murashkin entry.get_path_without_name() == 'android.lens.info' 13507b9a2dccf20bac314258708e55d8c75b2ecf892aIgor Murashkin """ 13517b9a2dccf20bac314258708e55d8c75b2ecf892aIgor Murashkin return ".".join(self.get_name_as_list()[0:-1]) 13527b9a2dccf20bac314258708e55d8c75b2ecf892aIgor Murashkin 13537b9a2dccf20bac314258708e55d8c75b2ecf892aIgor Murashkin 135477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkinclass Clone(Entry): 135577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 135677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin A Node corresponding to a <clone> element. It has all the attributes of an 135777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin <entry> element (Entry) plus the additions specified below. 135877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 135977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Attributes (Read-Only): 136077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry: an edge to an Entry object that this targets 136177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin target_kind: A string describing the kind of the target entry. 136277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin name: a string of the name, same as entry.name 136377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin kind: a string of the Kind ancestor, one of 'static', 'controls', 'dynamic' 136477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin for the <clone> element. 136577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin type: always None, since a clone cannot override the type. 136677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 136777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def __init__(self, entry=None, **kwargs): 136877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 136977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Instantiate a new Clone node. 137077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 137177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Args: 137277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin name: A string with the fully qualified name, e.g. 'android.shading.mode' 137377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin type: A string describing the type, e.g. 'int32' 137477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin kind: A string describing the kind, e.g. 'static' 137577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin target_kind: A string for the kind of the target entry, e.g. 'dynamic' 137677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 137777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Args (if container): 137877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin container: A string describing the container, e.g. 'array' or 'tuple' 137977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin container_sizes: A list of string sizes if a container, or None otherwise 138077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 138177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Args (if container is 'tuple'): 138277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin tuple_values: A list of tuple values, e.g. ['width', 'height'] 138377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 1384b556bc47068d816cb319a5d0e2f6841b007b38f2Igor Murashkin Args (if the 'enum' attribute is true): 1385b556bc47068d816cb319a5d0e2f6841b007b38f2Igor Murashkin enum: A boolean, True if this is an enum, False otherwise 138677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin enum_values: A list of value strings, e.g. ['ON', 'OFF'] 138777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin enum_optionals: A list of optional enum values, e.g. ['OFF'] 138877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin enum_notes: A dictionary of value->notes strings. 138977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin enum_ids: A dictionary of value->id strings. 139077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 139177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Args (optional): 139277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry: An edge to the corresponding target Entry. 139377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin description: A string with a description of the entry. 139477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin range: A string with the range of the values of the entry, e.g. '>= 0' 139577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin units: A string with the units of the values, e.g. 'inches' 1396a5b73c27ddbf032d1b3b4f628ac8fc0846c0ed2cEino-Ville Talvala details: A string with the detailed documentation for the entry 1397a5b73c27ddbf032d1b3b4f628ac8fc0846c0ed2cEino-Ville Talvala hal_details: A string with the HAL implementation details for the entry 139877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin tag_ids: A list of tag ID strings, e.g. ['BC', 'V1'] 139977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin type_notes: A string with the notes for the type 140077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 140177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Remarks: 140277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Note that type is not specified since it has to be the same as the 140377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin entry.type. 140477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 1405aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin self._entry = entry # Entry object 140677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._target_kind = kwargs['target_kind'] 1407aa133d352a42aebf93320eded40c75b4d7cff6e7Igor Murashkin self._name = kwargs['name'] # same as entry.name 140877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._kind = kwargs['kind'] 140977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 141077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # illegal to override the type, it should be the same as the entry 141177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._type = None 141277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # the rest of the kwargs are optional 141377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin # can be used to override the regular entry data 141477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin self._init_common(**kwargs) 141577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 141677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 141777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def entry(self): 141877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._entry 141977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 142077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin @property 142177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def target_kind(self): 142277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return self._target_kind 142377b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 142477b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin def is_clone(self): 142577b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 142677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Whether or not this is a Clone instance. 142777b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 142877b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin Returns: 142977b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin True 143077b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin """ 143177b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin return True 143277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 1433617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkinclass MergedEntry(Entry): 1434617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin """ 1435617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin A MergedEntry has all the attributes of a Clone and its target Entry merged 1436617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin together. 1437617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin 1438617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin Remarks: 1439617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin Useful when we want to 'unfold' a clone into a real entry by copying out 1440617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin the target entry data. In this case we don't care about distinguishing 1441617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin a clone vs an entry. 1442617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin """ 1443617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin def __init__(self, entry): 1444617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin """ 1445617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin Create a new instance of MergedEntry. 144677b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 1447617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin Args: 1448617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin entry: An Entry or Clone instance 1449617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin """ 1450a5b73c27ddbf032d1b3b4f628ac8fc0846c0ed2cEino-Ville Talvala props_distinct = ['description', 'units', 'range', 'details', 1451a5b73c27ddbf032d1b3b4f628ac8fc0846c0ed2cEino-Ville Talvala 'hal_details', 'tags', 'kind'] 145277b63ca0447545a4dac3ac062f218d878ce01ba0Igor Murashkin 1453617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin for p in props_distinct: 1454baacf9a9f032ca392b37b4982eafa43b0a8d4b52Igor Murashkin p = '_' + p 1455617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin if entry.is_clone(): 1456baacf9a9f032ca392b37b4982eafa43b0a8d4b52Igor Murashkin setattr(self, p, getattr(entry, p) or getattr(entry.entry, p)) 1457617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin else: 1458baacf9a9f032ca392b37b4982eafa43b0a8d4b52Igor Murashkin setattr(self, p, getattr(entry, p)) 1459617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin 1460baacf9a9f032ca392b37b4982eafa43b0a8d4b52Igor Murashkin props_common = ['parent', 'name', 'container', 1461617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin 'container_sizes', 'enum', 1462617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin 'tuple_values', 1463617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin 'type', 1464617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin 'type_notes', 1465b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 'visibility', 14666c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin 'synthetic', 1467ca25627fc63255d147286ef9a9624059825eb548Igor Murashkin 'hwlevel', 14686c936c18e02b122baaa3d5056b0555b6cff256f8Igor Murashkin 'deprecated', 1469ef40ad6249555a0a45c57907f4b9509b59e3e9f5Alex Ray 'optional', 1470b8dc88148bca2e5a267c2ff39aff94b98b00ad6dIgor Murashkin 'typedef' 1471617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin ] 1472617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin 1473617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin for p in props_common: 1474baacf9a9f032ca392b37b4982eafa43b0a8d4b52Igor Murashkin p = '_' + p 1475617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin if entry.is_clone(): 1476baacf9a9f032ca392b37b4982eafa43b0a8d4b52Igor Murashkin setattr(self, p, getattr(entry.entry, p)) 1477617da1675f9ea7b6ea33d9e6f47e0a07379f14b1Igor Murashkin else: 1478baacf9a9f032ca392b37b4982eafa43b0a8d4b52Igor Murashkin setattr(self, p, getattr(entry, p)) 1479