.Append('#include "base/strings/utf_string_conversions.h"')
.Append('#include "%s/%s.h"' %
(self._namespace.source_file_dir, self._namespace.short_filename))
+ .Append('#include <set>')
.Cblock(self._type_helper.GenerateIncludes(include_soft=True))
.Append()
.Append('using base::UTF8ToUTF16;')
.Sblock(' %s) {' % self._GenerateParams(
('const base::Value& value', '%(name)s* out'))))
+ if self._generate_error_messages:
+ c.Append('DCHECK(error);')
+
if type_.property_type == PropertyType.CHOICES:
for choice in type_.choices:
(c.Sblock('if (%s) {' % self._GenerateValueIsTypeExpression('value',
if type_.properties or type_.additional_properties is not None:
c.Append('const base::DictionaryValue* dict = '
'static_cast<const base::DictionaryValue*>(&value);')
- for prop in type_.properties.values():
+ if self._generate_error_messages:
+ c.Append('std::set<std::string> keys;')
+ for prop in type_.properties.itervalues():
c.Concat(self._InitializePropertyToDefault(prop, 'out'))
- for prop in type_.properties.values():
+ for prop in type_.properties.itervalues():
+ if self._generate_error_messages:
+ c.Append('keys.insert("%s");' % (prop.name))
c.Concat(self._GenerateTypePopulateProperty(prop, 'dict', 'out'))
+ # Check for extra values.
+ if self._generate_error_messages:
+ (c.Sblock('for (base::DictionaryValue::Iterator it(*dict); '
+ '!it.IsAtEnd(); it.Advance()) {')
+ .Sblock('if (!keys.count(it.key())) {')
+ .Concat(self._GenerateError('"found unexpected key \'" + '
+ 'it.key() + "\'"'))
+ .Eblock('}')
+ .Eblock('}')
+ )
if type_.additional_properties is not None:
if type_.additional_properties.property_type == PropertyType.ANY:
c.Append('out->additional_properties.MergeDictionary(dict);')
(c.Append('// static')
.Append('scoped_ptr<%s> %s::FromValue(%s) {' % (classname,
cpp_namespace, self._GenerateParams(('const base::Value& value',))))
- .Append(' scoped_ptr<%s> out(new %s());' % (classname, classname))
+ )
+ if self._generate_error_messages:
+ c.Append('DCHECK(error);')
+ (c.Append(' scoped_ptr<%s> out(new %s());' % (classname, classname))
.Append(' if (!Populate(%s))' % self._GenerateArgs(
('value', 'out.get()')))
.Append(' return scoped_ptr<%s>();' % classname)
)
for prop in type_.properties.values():
+ prop_var = 'this->%s' % prop.unix_name
if prop.optional:
# Optional enum values are generated with a NONE enum value.
underlying_type = self._type_helper.FollowRef(prop.type_)
if underlying_type.property_type == PropertyType.ENUM:
c.Sblock('if (%s != %s) {' %
- (prop.unix_name,
+ (prop_var,
self._type_helper.GetEnumNoneValue(prop.type_)))
else:
- c.Sblock('if (%s.get()) {' % prop.unix_name)
+ c.Sblock('if (%s.get()) {' % prop_var)
# 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);' % (
prop.name,
- self._CreateValueFromType(prop.type_,
- 'this->%s' % prop.unix_name,
+ self._CreateValueFromType(cpp_namespace,
+ prop.type_,
+ prop_var,
is_ptr=is_ptr)))
if prop.optional:
.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 '')))
.Eblock('}')
(c.Sblock('if (%s) {' % choice_var)
.Append('DCHECK(!result) << "Cannot set multiple choices for %s";' %
type_.unix_name)
- .Append('result.reset(%s);' %
- self._CreateValueFromType(choice, '*%s' % choice_var))
+ .Append('result.reset(%s);' % self._CreateValueFromType(
+ cpp_namespace,
+ choice,
+ '*%s' % choice_var))
.Eblock('}')
)
(c.Append('DCHECK(result) << "Must set at least one choice for %s";' %
# Results::Create function
if function.callback:
- c.Concat(self._GenerateCreateCallbackArguments('Results',
+ c.Concat(self._GenerateCreateCallbackArguments(function_namespace,
+ 'Results',
function.callback))
c.Append('} // namespace %s' % function_namespace)
(c.Append('namespace %s {' % event_namespace)
.Append()
.Cblock(self._GenerateEventNameConstant(None, event))
- .Cblock(self._GenerateCreateCallbackArguments(None, event))
+ .Cblock(self._GenerateCreateCallbackArguments(event_namespace,
+ None,
+ event))
.Append('} // namespace %s' % event_namespace)
)
return c
- def _CreateValueFromType(self, type_, var, is_ptr=False):
+ def _CreateValueFromType(self, cpp_namespace, type_, var, is_ptr=False):
"""Creates a base::Value given a type. Generated code passes ownership
to caller.
vardot = '(%s).' % var
return '%sDeepCopy()' % vardot
elif underlying_type.property_type == PropertyType.ENUM:
- return 'new base::StringValue(ToString(%s))' % var
+ classname = cpp_util.Classname(schema_util.StripNamespace(
+ underlying_type.name))
+ return 'new base::StringValue(%sToString(%s))' % (classname, var)
elif underlying_type.property_type == PropertyType.BINARY:
if is_ptr:
vardot = var + '->'
(vardot, vardot))
elif underlying_type.property_type == PropertyType.ARRAY:
return '%s.release()' % self._util_cc_helper.CreateValueFromArray(
+ cpp_namespace,
underlying_type,
var,
is_ptr)
(c.Append('// static')
.Sblock('scoped_ptr<Params> Params::Create(%s) {' % self._GenerateParams(
['const base::ListValue& args']))
- .Concat(self._GenerateParamsCheck(function, 'args'))
+ )
+ if self._generate_error_messages:
+ c.Append('DCHECK(error);')
+ (c.Concat(self._GenerateParamsCheck(function, 'args'))
.Append('scoped_ptr<Params> params(new Params());')
)
is_ptr=is_ptr))
else:
(c.Sblock('if (!%s) {' % self._util_cc_helper.PopulateArrayFromList(
- underlying_type,
'list',
dst_var,
is_ptr)))
('*%(src_var)s', '&%(dst_var)s')))
.Append(' return %(failure_value)s;'))
elif underlying_type.property_type == PropertyType.ENUM:
- c.Concat(self._GenerateStringToEnumConversion(type_,
+ c.Concat(self._GenerateStringToEnumConversion(underlying_type,
src_var,
dst_var,
failure_value))
type |type_| in |dst_var|. In the generated code, if |src_var| is not
a valid enum name then the function will return |failure_value|.
"""
+ if type_.property_type != PropertyType.ENUM:
+ raise TypeError(type_)
c = Code()
enum_as_string = '%s_as_string' % type_.unix_name
+ cpp_type_namespace = ''
+ if type_.namespace != self._namespace:
+ cpp_type_namespace = '%s::' % type_.namespace.unix_name
+ cpp_type_name = self._type_helper.GetCppType(type_)
(c.Append('std::string %s;' % enum_as_string)
.Sblock('if (!%s->GetAsString(&%s)) {' % (src_var, enum_as_string))
.Concat(self._GenerateError(
self._util_cc_helper.GetValueTypeString('%%(src_var)s', True)))
.Append('return %s;' % failure_value)
.Eblock('}')
- .Append('%s = Parse%s(%s);' % (dst_var,
- self._type_helper.GetCppType(type_),
- enum_as_string))
- .Sblock('if (%s == %s) {' % (dst_var,
- self._type_helper.GetEnumNoneValue(type_)))
+ .Append('%s = %sParse%s(%s);' % (dst_var,
+ cpp_type_namespace,
+ cpp_util.Classname(type_.name),
+ enum_as_string))
+ .Sblock('if (%s == %s%s) {' % (dst_var,
+ cpp_type_namespace,
+ self._type_helper.GetEnumNoneValue(type_)))
.Concat(self._GenerateError(
'\"\'%%(key)s\': expected \\"' +
'\\" or \\"'.join(
c.Append('// static')
maybe_namespace = '' if cpp_namespace is None else '%s::' % cpp_namespace
- c.Sblock('std::string %sToString(%s enum_param) {' %
- (maybe_namespace, classname))
+ c.Sblock('std::string %s%sToString(%s enum_param) {' %
+ (maybe_namespace, classname, classname))
c.Sblock('switch (enum_param) {')
for enum_value in self._type_helper.FollowRef(type_).enum_values:
(c.Append('case %s: ' % self._type_helper.GetEnumValue(type_, enum_value))
.Append('return "";')
.Eblock('}')
)
+
+ (c.Append()
+ .Sblock('std::string %sToString(%s enum_param) {' %
+ (maybe_namespace, classname))
+ .Append('return %s%sToString(enum_param);' % (maybe_namespace, classname))
+ .Eblock('}'))
return c
def _GenerateEnumFromString(self, cpp_namespace, type_):
)
return c
- def _GenerateCreateCallbackArguments(self, function_scope, callback):
+ def _GenerateCreateCallbackArguments(self,
+ cpp_namespace,
+ function_scope,
+ callback):
"""Generate all functions to create Value parameters for a callback.
E.g for function "Bar", generate Bar::Results::Create
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(param.type_, param.unix_name))
+ c.Append('create_results->Append(%s);' % self._CreateValueFromType(
+ cpp_namespace,
+ param.type_,
+ param.unix_name))
c.Append('return create_results.Pass();')
c.Eblock('}')
c.Substitute({
c = Code()
if not self._generate_error_messages:
return c
- (c.Append('if (error) {')
- .Append(' if (error->length())')
- .Append(' error->append(UTF8ToUTF16("; "));')
- .Append(' error->append(UTF8ToUTF16(%s));' % body)
- .Append('}')
- .Append('else')
- .Append(' *error = UTF8ToUTF16(%s);' % body))
+ (c.Append('if (error->length())')
+ .Append(' error->append(UTF8ToUTF16("; "));')
+ .Append('error->append(UTF8ToUTF16(%s));' % body))
return c
def _GenerateParams(self, params):