OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import os.path | 5 import os.path |
6 import re | 6 import re |
7 import copy | 7 import copy |
8 | 8 |
9 class Model(object): | 9 class Model(object): |
10 """Model of all namespaces that comprise an API. | 10 """Model of all namespaces that comprise an API. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 function = Function(function_json) | 53 function = Function(function_json) |
54 self.functions[function.name] = function | 54 self.functions[function.name] = function |
55 | 55 |
56 class Type(object): | 56 class Type(object): |
57 """A Type defined in the json. | 57 """A Type defined in the json. |
58 | 58 |
59 Properties: | 59 Properties: |
60 - |name| the type name | 60 - |name| the type name |
61 - |description| the description of the type (if provided) | 61 - |description| the description of the type (if provided) |
62 - |properties| a map of property names to their model.Property | 62 - |properties| a map of property names to their model.Property |
| 63 - |from_client| indicates that instances of the Type can originate from the |
| 64 users of generated code, such as top-level types and function results |
| 65 - |from_json| indicates that instances of the Type can originate from the |
| 66 JSON (as described by the schema), such as top-level types and function |
| 67 parameters |
63 """ | 68 """ |
64 def __init__(self, json): | 69 def __init__(self, json): |
65 self.name = json['id'] | 70 self.name = json['id'] |
66 self.description = json.get('description') | 71 self.description = json.get('description') |
| 72 self.from_json = True |
| 73 self.from_client = True |
67 self.properties = {} | 74 self.properties = {} |
68 for prop_name, prop_json in json['properties'].items(): | 75 for prop_name, prop_json in json['properties'].items(): |
69 self.properties[prop_name] = Property(prop_name, prop_json) | 76 self.properties[prop_name] = Property(prop_name, prop_json, |
| 77 from_json=True, |
| 78 from_client=True) |
70 | 79 |
71 class Callback(object): | 80 class Callback(object): |
72 """A callback parameter to a Function. | 81 """A callback parameter to a Function. |
73 | 82 |
74 Properties: | 83 Properties: |
75 - |params| the parameters to this callback. | 84 - |params| the parameters to this callback. |
76 """ | 85 """ |
77 def __init__(self, json): | 86 def __init__(self, json): |
78 params = json['parameters'] | 87 params = json['parameters'] |
79 self.params = [] | 88 self.params = [] |
80 if len(params) == 0: | 89 if len(params) == 0: |
81 return | 90 return |
82 elif len(params) == 1: | 91 elif len(params) == 1: |
83 param = params[0] | 92 param = params[0] |
84 self.params.append(Property(param['name'], param)) | 93 self.params.append(Property(param['name'], param, |
| 94 from_client=True)) |
85 else: | 95 else: |
86 raise AssertionError("Callbacks can have at most a single parameter") | 96 raise AssertionError("Callbacks can have at most a single parameter") |
87 | 97 |
88 class Function(object): | 98 class Function(object): |
89 """A Function defined in the API. | 99 """A Function defined in the API. |
90 | 100 |
91 Properties: | 101 Properties: |
92 - |name| the function name | 102 - |name| the function name |
93 - |params| a list of parameters to the function (order matters). A separate | 103 - |params| a list of parameters to the function (order matters). A separate |
94 parameter is used for each choice of a 'choices' parameter. | 104 parameter is used for each choice of a 'choices' parameter. |
95 - |description| a description of the function (if provided) | 105 - |description| a description of the function (if provided) |
96 - |callback| the callback parameter to the function. There should be exactly | 106 - |callback| the callback parameter to the function. There should be exactly |
97 one | 107 one |
98 """ | 108 """ |
99 def __init__(self, json): | 109 def __init__(self, json): |
100 self.name = json['name'] | 110 self.name = json['name'] |
101 self.params = [] | 111 self.params = [] |
102 self.description = json['description'] | 112 self.description = json['description'] |
103 self.callback = None | 113 self.callback = None |
104 for param in json['parameters']: | 114 for param in json['parameters']: |
105 if param.get('type') == 'function': | 115 if param.get('type') == 'function': |
106 assert (not self.callback), self.name + " has more than one callback" | 116 assert (not self.callback), self.name + " has more than one callback" |
107 self.callback = Callback(param) | 117 self.callback = Callback(param) |
108 else: | 118 else: |
109 self.params.append(Property(param['name'], param)) | 119 self.params.append(Property(param['name'], param, |
110 assert (self.callback), self.name + " does not support callback" | 120 from_json=True)) |
111 | 121 |
112 class Property(object): | 122 class Property(object): |
113 """A property of a type OR a parameter to a function. | 123 """A property of a type OR a parameter to a function. |
114 | 124 |
115 Properties: | 125 Properties: |
116 - |name| name of the property as in the json. This shouldn't change since | 126 - |name| name of the property as in the json. This shouldn't change since |
117 it is the key used to access DictionaryValues | 127 it is the key used to access DictionaryValues |
118 - |unix_name| the unix_style_name of the property. Used as variable name | 128 - |unix_name| the unix_style_name of the property. Used as variable name |
119 - |optional| a boolean representing whether the property is optional | 129 - |optional| a boolean representing whether the property is optional |
120 - |description| a description of the property (if provided) | 130 - |description| a description of the property (if provided) |
121 - |type_| the model.PropertyType of this property | 131 - |type_| the model.PropertyType of this property |
122 - |ref_type| the type that the REF property is referencing. Can be used to | 132 - |ref_type| the type that the REF property is referencing. Can be used to |
123 map to its model.Type | 133 map to its model.Type |
124 - |item_type| a model.Property representing the type of each element in an | 134 - |item_type| a model.Property representing the type of each element in an |
125 ARRAY | 135 ARRAY |
126 - |properties| the properties of an OBJECT parameter | 136 - |properties| the properties of an OBJECT parameter |
127 """ | 137 """ |
128 def __init__(self, name, json): | 138 def __init__(self, name, json, |
129 if not re.match('^[a-z][a-zA-Z0-9]*$', name): | 139 from_json=False, |
130 raise AssertionError('Name %s must be lowerCamelCase' % name) | 140 from_client=False): |
| 141 """ |
| 142 Parameters: |
| 143 - |from_json| indicates that instances of the Type can originate from the |
| 144 JSON (as described by the schema), such as top-level types and function |
| 145 parameters |
| 146 - |from_client| indicates that instances of the Type can originate from the |
| 147 users of generated code, such as top-level types and function results |
| 148 """ |
131 self.name = name | 149 self.name = name |
132 self._unix_name = _UnixName(self.name) | 150 self._unix_name = _UnixName(self.name) |
133 self._unix_name_used = False | 151 self._unix_name_used = False |
134 self.optional = json.get('optional', False) | 152 self.optional = json.get('optional', False) |
135 self.description = json.get('description') | 153 self.description = json.get('description') |
136 if '$ref' in json: | 154 if '$ref' in json: |
137 self.ref_type = json['$ref'] | 155 self.ref_type = json['$ref'] |
138 self.type_ = PropertyType.REF | 156 self.type_ = PropertyType.REF |
139 elif 'enum' in json: | 157 elif 'enum' in json: |
140 self.enum_values = [] | 158 self.enum_values = [] |
141 for value in json['enum']: | 159 for value in json['enum']: |
142 self.enum_values.append(value) | 160 self.enum_values.append(value) |
143 self.type_ = PropertyType.ENUM | 161 self.type_ = PropertyType.ENUM |
144 elif 'type' in json: | 162 elif 'type' in json: |
145 json_type = json['type'] | 163 json_type = json['type'] |
146 if json_type == 'string': | 164 if json_type == 'string': |
147 self.type_ = PropertyType.STRING | 165 self.type_ = PropertyType.STRING |
148 elif json_type == 'any': | 166 elif json_type == 'any': |
149 self.type_ = PropertyType.ANY | 167 self.type_ = PropertyType.ANY |
150 elif json_type == 'boolean': | 168 elif json_type == 'boolean': |
151 self.type_ = PropertyType.BOOLEAN | 169 self.type_ = PropertyType.BOOLEAN |
152 elif json_type == 'integer': | 170 elif json_type == 'integer': |
153 self.type_ = PropertyType.INTEGER | 171 self.type_ = PropertyType.INTEGER |
154 elif json_type == 'number': | 172 elif json_type == 'number': |
155 self.type_ = PropertyType.DOUBLE | 173 self.type_ = PropertyType.DOUBLE |
156 elif json_type == 'array': | 174 elif json_type == 'array': |
157 self.item_type = Property(name + "Element", json['items']) | 175 self.item_type = Property(name + "Element", json['items'], |
| 176 from_json, |
| 177 from_client) |
158 self.type_ = PropertyType.ARRAY | 178 self.type_ = PropertyType.ARRAY |
159 elif json_type == 'object': | 179 elif json_type == 'object': |
| 180 self.type_ = PropertyType.OBJECT |
| 181 # These members are read when this OBJECT Property is used as a Type |
160 self.properties = {} | 182 self.properties = {} |
161 self.type_ = PropertyType.OBJECT | 183 self.from_json = from_json |
162 for key, val in json['properties'].items(): | 184 self.from_client = from_client |
163 self.properties[key] = Property(key, val) | 185 for key, val in json.get('properties', {}).items(): |
| 186 self.properties[key] = Property(key, val, |
| 187 from_json, |
| 188 from_client) |
164 else: | 189 else: |
165 raise NotImplementedError(json_type) | 190 raise NotImplementedError(json_type) |
166 elif 'choices' in json: | 191 elif 'choices' in json: |
167 assert len(json['choices']), 'Choices has no choices\n%s' % json | 192 assert len(json['choices']), 'Choices has no choices\n%s' % json |
168 self.choices = {} | 193 self.choices = {} |
169 self.type_ = PropertyType.CHOICES | 194 self.type_ = PropertyType.CHOICES |
170 for choice_json in json['choices']: | 195 for choice_json in json['choices']: |
171 choice = Property(self.name, choice_json) | 196 choice = Property(self.name, choice_json, |
| 197 from_json, |
| 198 from_client) |
172 # A choice gets its unix_name set in | 199 # A choice gets its unix_name set in |
173 # cpp_type_generator.GetExpandedChoicesInParams | 200 # cpp_type_generator.GetExpandedChoicesInParams |
174 choice._unix_name = None | 201 choice._unix_name = None |
175 # The existence of any single choice is optional | 202 # The existence of any single choice is optional |
176 choice.optional = True | 203 choice.optional = True |
177 self.choices[choice.type_] = choice | 204 self.choices[choice.type_] = choice |
178 else: | 205 else: |
179 raise NotImplementedError(json) | 206 raise NotImplementedError(json) |
180 | 207 |
181 def GetUnixName(self): | 208 def GetUnixName(self): |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 CHOICES = _Info(False, "CHOICES") | 257 CHOICES = _Info(False, "CHOICES") |
231 OBJECT = _Info(False, "OBJECT") | 258 OBJECT = _Info(False, "OBJECT") |
232 ANY = _Info(False, "ANY") | 259 ANY = _Info(False, "ANY") |
233 | 260 |
234 def _UnixName(name): | 261 def _UnixName(name): |
235 """Returns the unix_style name for a given lowerCamelCase string. | 262 """Returns the unix_style name for a given lowerCamelCase string. |
236 """ | 263 """ |
237 return '_'.join([x.lower() | 264 return '_'.join([x.lower() |
238 for x in re.findall('[A-Z][a-z_]*', name[0].upper() + name[1:])]) | 265 for x in re.findall('[A-Z][a-z_]*', name[0].upper() + name[1:])]) |
239 | 266 |
OLD | NEW |