Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 _ATTRIBUTES = ('events', 'functions', 'parameters', 'properties', 'types') | |
|
not at google - send to devlin
2013/09/06 23:29:38
I'm thinking this shouldn't care about what the co
epeterson
2013/09/12 00:32:01
Done.
| |
| 6 | |
| 7 | |
| 8 def _NameForNode(node, node_type): | |
| 9 '''Creates a unique id for an object in an API schema, depending on | |
| 10 what type of attribute the object is a member of. | |
| 11 ''' | |
| 12 if node_type == 'properties': return node | |
| 13 if node_type == 'types': return node['id'] | |
| 14 if node_type is None: return node['namespace'] | |
| 15 if 'name' in node: | |
| 16 return node['name'] | |
| 17 # The API Schema probably had an error here. Fall back to the 'type' field to | |
| 18 # avoid raising an error. | |
| 19 return node['type'] | |
| 20 | |
| 21 | |
| 22 def _CreateGraph(api_schema, node_type=None): | |
| 23 '''Recursively move through an API schema, replacing lists of objects | |
| 24 for each attribute listed in |attributes| with a dict containing a | |
| 25 key for each object in the list. | |
| 26 ''' | |
| 27 availability_graph = {} | |
| 28 for node in api_schema: | |
|
not at google - send to devlin
2013/09/06 23:29:38
confusing dicts and lists here is.. odd. And I can
epeterson
2013/09/12 00:32:01
Done.
| |
| 29 name = _NameForNode(node, node_type) | |
|
not at google - send to devlin
2013/09/06 23:29:38
how about asserting "name not in graph" here.
epeterson
2013/09/12 00:32:01
Done.
| |
| 30 availability_graph[name] = { 'availability': None } | |
| 31 if node_type == 'properties': | |
| 32 # The 'properties' attribute is a key -> value mapping. Grab the value. | |
| 33 node = api_schema[node] | |
| 34 for attribute in _ATTRIBUTES: | |
| 35 if attribute in node: | |
| 36 availability_graph[name][attribute] = _CreateGraph(node[attribute], | |
| 37 node_type=attribute) | |
| 38 return availability_graph | |
| 39 | |
| 40 | |
| 41 class AvailabilityGraph(object): | |
| 42 '''Represents an API schema as a nested dict structure, where lists of | |
| 43 schema nodes (falling under one of |_ATTRIBUTES|) are converted to | |
| 44 dicts with a key representing each node. Availability information for | |
| 45 schema nodes is tracked as the graph is created and processed. | |
| 46 ''' | |
| 47 | |
| 48 def __init__(self, api_schema, channel_info): | |
| 49 self.graph = _CreateGraph(api_schema) | |
| 50 self.channel_info = channel_info | |
|
not at google - send to devlin
2013/09/06 23:29:38
these need to be private.
epeterson
2013/09/12 00:32:01
Done.
| |
| 51 self._paths = [] | |
| 52 | |
| 53 def SetPaths(self, other): | |
| 54 '''Sets a list of '/'-delimited dictionary-keys, or 'paths', that | |
| 55 exist in this object's |graph| but not in |other|'s graph. Update | |
| 56 'availability' for keys based on which graphs they are initially | |
| 57 found in. | |
| 58 ''' | |
| 59 def get_missing_paths(this_graph, other_graph, path=''): | |
| 60 paths = [] | |
| 61 for key in this_graph: | |
| 62 if key == 'availability': | |
| 63 continue | |
| 64 current_path = '%s/%s' % (path, key) if path else key | |
| 65 paths.extend(get_missing_paths(this_graph[key], | |
| 66 other_graph.get(key, {}), | |
| 67 current_path)) | |
| 68 if key not in _ATTRIBUTES: | |
| 69 # Add the path if the value was not available upon the API's release. | |
| 70 if key not in other_graph: | |
| 71 this_graph[key]['availability'] = self.channel_info | |
| 72 paths.append(current_path) | |
| 73 else: | |
| 74 this_graph[key]['availability'] = other.channel_info | |
| 75 return paths | |
| 76 | |
| 77 self._paths = get_missing_paths(self.graph, other.graph) | |
| 78 | |
| 79 def UpdatePaths(self, other): | |
| 80 '''Check each path in |_paths|, removing a path if it has become | |
| 81 available and updating that path's availability in the |graph|. | |
| 82 ''' | |
| 83 for path in self._paths[:]: | |
| 84 path_pieces = path.split('/') | |
| 85 if other.Lookup(*path_pieces) is not None: | |
| 86 node = self.graph | |
| 87 for path_piece in path_pieces: | |
| 88 node = node[path_piece] | |
| 89 node['availability'] = other.channel_info | |
| 90 self._paths.remove(path) | |
| 91 return bool(self._paths) | |
|
not at google - send to devlin
2013/09/06 23:29:38
Would a better set of methods on this class be som
epeterson
2013/09/12 00:32:01
Done.
| |
| 92 | |
| 93 def Lookup(self, *path): | |
| 94 '''Given a list of path components, |path|, checks if |graph| | |
| 95 contains |path| and returns its availability if found. | |
| 96 ''' | |
| 97 node = self.graph | |
| 98 for path_piece in path: | |
| 99 node = node.get(path_piece) | |
| 100 if node is None: | |
| 101 return None | |
| 102 return node.get('availability') | |
| OLD | NEW |