Index: tools/json_schema_compiler/cc_generator.py |
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py |
index febd7bb769748ce159064a21336fdfaed0ed60ed..96492ba103056ce8a07358a5b30ec9e3df5fc7c9 100644 |
--- a/tools/json_schema_compiler/cc_generator.py |
+++ b/tools/json_schema_compiler/cc_generator.py |
@@ -366,12 +366,12 @@ class _Generator(object): |
# ANY is a base::Value which is abstract and cannot be a direct member, so |
# it will always be a pointer. |
is_ptr = prop.optional or prop.type_.property_type == PropertyType.ANY |
- c.Append('value->SetWithoutPathExpansion("%s", %s);' % ( |
+ c.Cblock(self._CreateValueFromType( |
+ 'value->SetWithoutPathExpansion("%s", %%s);' % prop.name, |
prop.name, |
- self._CreateValueFromType(cpp_namespace, |
- prop.type_, |
- prop_var, |
- is_ptr=is_ptr))) |
+ prop.type_, |
+ prop_var, |
+ is_ptr=is_ptr)) |
if prop.optional: |
c.Eblock('}') |
@@ -390,11 +390,11 @@ class _Generator(object): |
cpp_util.PadForGenerics(cpp_type)) |
.Append(' additional_properties.begin();') |
.Append(' it != additional_properties.end(); ++it) {') |
- .Append('value->SetWithoutPathExpansion(it->first, %s);' % |
- self._CreateValueFromType( |
- cpp_namespace, |
- type_.additional_properties, |
- '%sit->second' % ('*' if needs_unwrap else ''))) |
+ .Cblock(self._CreateValueFromType( |
+ 'value->SetWithoutPathExpansion(it->first, %s);', |
+ type_.additional_properties.name, |
+ type_.additional_properties, |
+ '%sit->second' % ('*' if needs_unwrap else ''))) |
.Eblock('}') |
) |
@@ -414,10 +414,10 @@ class _Generator(object): |
(c.Sblock('if (%s) {' % choice_var) |
.Append('DCHECK(!result) << "Cannot set multiple choices for %s";' % |
type_.unix_name) |
- .Append('result.reset(%s);' % self._CreateValueFromType( |
- cpp_namespace, |
- choice, |
- '*%s' % choice_var)) |
+ .Cblock(self._CreateValueFromType('result.reset(%s);', |
+ choice.name, |
+ choice, |
+ '*%s' % choice_var)) |
.Eblock('}') |
) |
(c.Append('DCHECK(result) << "Must set at least one choice for %s";' % |
@@ -474,7 +474,7 @@ class _Generator(object): |
) |
return c |
- def _CreateValueFromType(self, cpp_namespace, type_, var, is_ptr=False): |
+ def _CreateValueFromType(self, code, prop_name, type_, var, is_ptr=False): |
"""Creates a base::Value given a type. Generated code passes ownership |
to caller. |
@@ -482,6 +482,52 @@ class _Generator(object): |
E.g for std::string, generate new base::StringValue(var) |
""" |
+ c = Code() |
+ underlying_type = self._type_helper.FollowRef(type_) |
+ if underlying_type.property_type == PropertyType.ARRAY: |
+ # Enums are treated specially because C++ templating thinks that they're |
+ # ints, but really they're strings. So we create a vector of strings and |
+ # populate it with the names of the enum in the array. The |ToString| |
+ # function of the enum can be in another namespace when the enum is |
+ # referenced. Templates can not be used here because C++ templating does |
+ # not support passing a namespace as an argument. |
+ item_type = self._type_helper.FollowRef(underlying_type.item_type) |
+ if item_type.property_type == PropertyType.ENUM: |
+ vardot = '(%s)%s' % (var, '->' if is_ptr else '.') |
+ |
+ maybe_namespace = '' |
+ if type_.item_type.property_type == PropertyType.REF: |
+ maybe_namespace = '%s::' % item_type.namespace.unix_name |
+ |
+ enum_list_var = '%s_list' % prop_name |
+ # Scope the std::vector variable declaration inside braces. |
+ (c.Sblock('{') |
+ .Append('std::vector<std::string> %s;' % enum_list_var) |
+ .Append('for (std::vector<%s>::const_iterator it = %sbegin();' |
+ % (self._type_helper.GetCppType(item_type), vardot)) |
+ .Sblock(' it != %send(); ++it) {' % vardot) |
+ .Append('%s.push_back(%sToString(*it));' % (enum_list_var, |
+ maybe_namespace)) |
+ .Eblock('}')) |
+ |
+ # Because the std::vector above is always created for both required and |
+ # optional enum arrays, |is_ptr| is set to false and uses the |
+ # std::vector to create the values. |
+ (c.Append(code % |
+ self._GenerateCreateValueFromType(type_, enum_list_var, False)) |
+ .Eblock('}')) |
+ return c |
+ |
+ c.Append(code % self._GenerateCreateValueFromType(type_, var, is_ptr)) |
+ return c |
+ |
+ def _GenerateCreateValueFromType(self, type_, var, is_ptr): |
+ """Generates the statement to create a base::Value given a type. |
+ |
+ type_: The type of the values being converted. |
+ var: The name of the variable. |
+ is_ptr: Whether |type_| is optional. |
+ """ |
underlying_type = self._type_helper.FollowRef(type_) |
if (underlying_type.property_type == PropertyType.CHOICES or |
underlying_type.property_type == PropertyType.OBJECT): |
@@ -510,8 +556,6 @@ class _Generator(object): |
(vardot, vardot)) |
elif underlying_type.property_type == PropertyType.ARRAY: |
return '%s.release()' % self._util_cc_helper.CreateValueFromArray( |
- cpp_namespace, |
- underlying_type, |
var, |
is_ptr) |
elif underlying_type.property_type.is_fundamental: |
@@ -959,10 +1003,10 @@ class _Generator(object): |
for param in params: |
declaration_list.append(cpp_util.GetParameterDeclaration( |
param, self._type_helper.GetCppType(param.type_))) |
- c.Append('create_results->Append(%s);' % self._CreateValueFromType( |
- cpp_namespace, |
- param.type_, |
- param.unix_name)) |
+ c.Cblock(self._CreateValueFromType('create_results->Append(%s);', |
+ param.name, |
+ param.type_, |
+ param.unix_name)) |
c.Append('return create_results.Pass();') |
c.Eblock('}') |
c.Substitute({ |