Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(428)

Unified Diff: components/policy/tools/generate_policy_source.py

Issue 138003003: Add additional restriction to policy schema internal (part1) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix python generator and C++ parser Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 315650de2510ed9de2adaabfd24361db4e36c3d3..9ddf97d14ea11c0b06f2ccb4a0b4a93d5ea4f641 100755
--- a/components/policy/tools/generate_policy_source.py
+++ b/components/policy/tools/generate_policy_source.py
@@ -257,7 +257,6 @@ SIMPLE_SCHEMA_NAME_MAP = {
'string' : 'TYPE_STRING',
}
-
class SchemaNodesGenerator:
"""Builds the internal structs to represent a JSON schema."""
@@ -271,6 +270,9 @@ class SchemaNodesGenerator:
self.schema_nodes = []
self.property_nodes = []
self.properties_nodes = []
+ self.restriction_nodes = []
+ self.int_enums = []
+ self.string_enums = []
self.simple_types = {
'boolean': None,
'integer': None,
@@ -288,6 +290,11 @@ class SchemaNodesGenerator:
self.schema_nodes.append((type, extra, comment))
return index
+ def AppendRestriction(self, first, second):
+ index = len(self.restriction_nodes)
+ self.restriction_nodes.append((first, second))
+ return index
+
def GetSimpleType(self, name):
if self.simple_types[name] == None:
self.simple_types[name] = self.AppendSchema(
@@ -304,14 +311,67 @@ class SchemaNodesGenerator:
'simple type: stringlist')
return self.stringlist_type
+ def SchemaHaveRestriction(self, schema):
+ return 'minimum' in schema or 'maximum' in schema or 'enum' in schema
+
+ def GetEnumIntegerType(self, schema):
+ offset_begin = len(self.int_enums)
Joao da Silva 2014/01/16 10:56:34 Add a check at the beginning: assert all(type(x
Joao da Silva 2014/01/16 10:56:34 You had a nice idea about converting enums into ra
binjin 2014/01/17 14:29:01 Done.
binjin 2014/01/17 14:29:01 Done.
+ self.int_enums += schema['enum']
+ offset_end = len(self.int_enums)
+ return self.AppendSchema('TYPE_INTEGER',
+ self.AppendRestriction(offset_begin, offset_end),
+ 'integer with enumeration restriction')
Joao da Silva 2014/01/16 10:56:34 Use "name" (from Generate()) for the 3rd argument
binjin 2014/01/17 14:29:01 Done.
+
+ def GetEnumStringType(self, schema):
+ offset_begin = len(self.string_enums)
Joao da Silva 2014/01/16 10:56:34 Add a check at the beginning: assert all(type(x
binjin 2014/01/17 14:29:01 Done.
+ self.string_enums += schema['enum']
+ offset_end = len(self.string_enums)
+ return self.AppendSchema('TYPE_STRING',
+ self.AppendRestriction(offset_begin, offset_end),
+ 'string with enumeration restriction')
Joao da Silva 2014/01/16 10:56:34 Use "name" from Generate() for the 3rd argument
binjin 2014/01/17 14:29:01 Done.
+
+ def GetEnumType(self, schema):
+ if len(schema['enum']) == 0:
+ raise RuntiemError('Empty enumeration in %s' % schema['name'])
Joao da Silva 2014/01/16 10:56:34 RuntimeError schema['name'] does not exist; you h
binjin 2014/01/17 14:29:01 Done.
+ elif schema['type'] == 'integer':
+ return self.GetEnumIntegerType(schema)
+ elif schema['type'] == 'string':
+ return self.GetEnumStringType(schema)
+ else:
+ raise RuntimeError('Unknown enumeration type in %s' % schema['name'])
Joao da Silva 2014/01/16 10:56:34 schema['name'] does not exist
binjin 2014/01/17 14:29:01 Done.
+
+ def GetRangedType(self, schema):
+ if schema['type'] != 'integer':
+ raise RuntimeError('Unknown ranged type in %s' % schema['name'])
Joao da Silva 2014/01/16 10:56:34 schema['name' does not exist; pass "name" from Gen
binjin 2014/01/17 14:29:01 Done.
+ min_value_set, max_value_set = False, False
+ if 'minimum' in schema:
+ min_value = int(schema['minimum'])
+ min_value_set = True
+ if 'maximum' in schema:
+ max_value = int(schema['minimum'])
+ max_value_set = True
+ if min_value_set and max_value_set and min_value > max_value:
+ raise RuntimeError('Invalid ranged type in %s' % schema['name'])
Joao da Silva 2014/01/16 10:56:34 schema['name'] does not exist
binjin 2014/01/17 14:29:01 Done.
+ index = self.AppendRestriction(
+ str(max_value) if max_value_set else 'INT_MAX',
+ str(min_value) if min_value_set else 'INT_MIN')
+ return self.AppendSchema('TYPE_INTEGER',
+ index,
+ 'integer with ranged restriction')
Joao da Silva 2014/01/16 10:56:34 Use "name" for the 3rd argument
binjin 2014/01/17 14:29:01 Done.
+
def Generate(self, schema, name):
"""Generates the structs for the given schema.
|schema|: a valid JSON schema in a dictionary.
|name|: the name of the current node, for the generated comments."""
- # Simple types use shared nodes.
if schema['type'] in self.simple_types:
- return self.GetSimpleType(schema['type'])
+ if not self.SchemaHaveRestriction(schema):
+ # Simple types use shared nodes.
+ return self.GetSimpleType(schema['type'])
+ elif 'enum' in schema:
+ return self.GetEnumType(schema)
+ else:
+ return self.GetRangedType(schema)
if schema['type'] == 'array':
# Special case for lists of strings, which is a common policy type.
@@ -380,10 +440,28 @@ class SchemaNodesGenerator:
f.write(' { %5d, %5d, %5d }, // %s\n' % node)
f.write('};\n\n')
+ f.write('const internal::RestrictionNode kRestrictionNodes[] = {\n')
+ for first, second in self.restriction_nodes:
+ f.write('{{%s,%s}},\n' % (first, second))
Joao da Silva 2014/01/16 10:56:34 Use spacing and a header comment like the arrays a
binjin 2014/01/17 14:29:01 Done.
+ f.write('};\n\n')
+
+ f.write('const int kIntegerEnumerations[] = {\n')
+ for possible_values in self.int_enums:
+ f.write('%d,\n' % possible_values)
Joao da Silva 2014/01/16 10:56:34 Indent with 2 spaces
binjin 2014/01/17 14:29:01 Done.
+ f.write('};\n\n')
+
+ f.write('const char* kStringEnumerations[] = {\n')
+ for possible_values in self.string_enums:
+ f.write('%s\n' % self.GetString(possible_values))
Joao da Silva 2014/01/16 10:56:34 Indent with 2 spaces
binjin 2014/01/17 14:29:01 Done.
+ f.write('};\n\n')
+
f.write('const internal::SchemaData kChromeSchemaData = {\n'
' kSchemas,\n'
' kPropertyNodes,\n'
' kProperties,\n'
+ ' kRestrictionNodes,\n'
+ ' kIntegerEnumerations,\n'
+ ' kStringEnumerations,\n'
Joao da Silva 2014/01/16 10:56:34 Compilation fails when an array is empty. So if an
binjin 2014/01/17 14:29:01 Done.
'};\n\n')
@@ -391,6 +469,7 @@ def _WritePolicyConstantSource(policies, os, f):
f.write('#include "policy/policy_constants.h"\n'
'\n'
'#include <algorithm>\n'
+ '#include <climits>\n'
'\n'
'#include "base/logging.h"\n'
'#include "components/policy/core/common/schema_internal.h"\n'

Powered by Google App Engine
This is Rietveld 408576698