Chromium Code Reviews| Index: components/policy/tools/generate_policy_source.py |
| diff --git a/components/policy/tools/generate_policy_source.py b/components/policy/tools/generate_policy_source.py |
| index 9ccf881d17137a2ecd5b98f6e3ea77f21a44cda8..62f558a74976f141c244ae048668f48e2a36c96d 100755 |
| --- a/components/policy/tools/generate_policy_source.py |
| +++ b/components/policy/tools/generate_policy_source.py |
| @@ -16,6 +16,7 @@ from optparse import OptionParser |
| import re |
| import sys |
| import textwrap |
| +import types |
| CHROME_POLICY_KEY = 'SOFTWARE\\\\Policies\\\\Google\\\\Chrome' |
| @@ -282,6 +283,7 @@ class SchemaNodesGenerator: |
| } |
| self.stringlist_type = None |
| self.ranges = {} |
| + self.id_map = {} |
| def GetString(self, s): |
| if s in self.shared_strings: |
| @@ -398,24 +400,28 @@ class SchemaNodesGenerator: |
| |schema|: a valid JSON schema in a dictionary. |
| |name|: the name of the current node, for the generated comments.""" |
| + if schema.has_key('$ref'): |
| + if schema.has_key('id'): |
| + raise RuntimeError("Schemas with a $ref can't have an id") |
| + return schema['$ref'] |
| if schema['type'] in self.simple_types: |
| if not self.SchemaHaveRestriction(schema): |
| # Simple types use shared nodes. |
| - return self.GetSimpleType(schema['type']) |
| + return self.CheckID(schema, self.GetSimpleType(schema['type'])) |
|
Joao da Silva
2014/04/08 15:02:10
I think adding CheckID() in the right places is ha
binjin
2014/04/09 11:00:36
Done.
|
| elif 'enum' in schema: |
| - return self.GetEnumType(schema, name) |
| + return self.CheckID(schema, self.GetEnumType(schema, name)) |
| elif 'pattern' in schema: |
| - return self.GetPatternType(schema, name) |
| + return self.CheckID(schema, self.GetPatternType(schema, name)) |
| else: |
| - return self.GetRangedType(schema, name) |
| + return self.CheckID(schema, self.GetRangedType(schema, name)) |
| if schema['type'] == 'array': |
| # Special case for lists of strings, which is a common policy type. |
| if schema['items']['type'] == 'string': |
| - return self.GetStringList() |
| - return self.AppendSchema( |
| + return self.CheckID(schema, self.GetStringList()) |
| + return self.CheckID(schema, self.AppendSchema( |
| 'TYPE_LIST', |
| - self.Generate(schema['items'], 'items of ' + name)) |
| + self.Generate(schema['items'], 'items of ' + name))) |
| elif schema['type'] == 'object': |
| # Reserve an index first, so that dictionaries come before their |
| # properties. This makes sure that the root node is the first in the |
| @@ -458,7 +464,7 @@ class SchemaNodesGenerator: |
| # Set the right data at |index| now. |
| self.schema_nodes[index] = ('TYPE_DICTIONARY', extra, name) |
| - return index |
| + return self.CheckID(schema, index) |
| else: |
| assert False |
| @@ -516,6 +522,48 @@ class SchemaNodesGenerator: |
| f.write(' kStringEnumerations,\n' if self.string_enums else ' NULL,\n') |
| f.write('};\n\n') |
| + def CheckID(self, schema, index): |
| + """Check and add 'id' attribute to id_map |
| + |
| + |schema|: target JSON schema that might come with 'id' attribute |
| + |index|: index for parsed |schema|, like the one returned by Generate() |
| + """ |
| + if not schema.has_key('id'): |
| + return index |
| + id_str = schema['id'] |
| + if self.id_map.has_key(id_str): |
| + raise RuntimeError('Duplicated id: ' + id_str) |
| + self.id_map[id_str] = index |
| + return index |
| + |
| + def ResolveReference(self): |
|
Joao da Silva
2014/04/08 15:02:10
ResolveReferences
binjin
2014/04/09 11:00:36
Done.
|
| + """ Resolve reference mapping, required to be called after Generate() |
|
Joao da Silva
2014/04/08 15:02:10
Remove the space after """
binjin
2014/04/09 11:00:36
Done.
|
| + |
| + After calling Generate(), the type of indices used in schema structures |
| + might be either int or string. An int type suggest that it's a resolved |
| + index, but for string type it's unresolved. Resolving a reference is as |
| + simple as looking up for corresponding index in self.id_map, and replace the |
|
Joao da Silva
2014/04/08 15:02:10
corresponding ID
binjin
2014/04/09 11:00:36
Done.
|
| + old index with it. |
|
Joao da Silva
2014/04/08 15:02:10
old index with the mapped index.
binjin
2014/04/09 11:00:36
Done.
|
| + """ |
| + for i in xrange(len(self.schema_nodes)): |
| + (type, extra, comment) = self.schema_nodes[i] |
| + if isinstance(extra, types.StringTypes): |
| + self.schema_nodes[i] = (type, self.GetByID(extra), comment) |
| + for i in xrange(len(self.property_nodes)): |
| + (key, schema) = self.property_nodes[i] |
| + if isinstance(schema, types.StringTypes): |
| + self.property_nodes[i] = (key, self.GetByID(schema)) |
| + for i in xrange(len(self.properties_nodes)): |
| + (begin, end, pattern_end, additional, name) = self.properties_nodes[i] |
| + if isinstance(additional, types.StringTypes): |
| + self.properties_nodes[i] = (begin, end, pattern_end, |
| + self.GetByID(additional), name) |
|
Joao da Silva
2014/04/08 15:02:10
This is a bit more complicated than it needs to be
binjin
2014/04/09 11:00:36
Done.
|
| + |
| + def GetByID(self, id_str): |
| + if not self.id_map.has_key(id_str): |
| + raise RuntimeError('Invalid $ref: ' + id_str) |
| + return self.id_map[id_str] |
| + |
| def _WritePolicyConstantSource(policies, os, f): |
| f.write('#include "policy/policy_constants.h"\n' |
| @@ -559,6 +607,7 @@ def _WritePolicyConstantSource(policies, os, f): |
| schema_generator = SchemaNodesGenerator(shared_strings) |
| schema_generator.Generate(chrome_schema, 'root node') |
| + schema_generator.ResolveReference() |
| schema_generator.Write(f) |
| f.write('bool CompareKeys(const internal::PropertyNode& node,\n' |