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

Side by Side Diff: tools/json_schema_compiler/cc_generator.py

Issue 22228002: Add optional schema compiler error messages (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Synced up to latest master. Created 7 years, 4 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 unified diff | Download patch
« no previous file with comments | « chrome/chrome_tests_unit.gypi ('k') | tools/json_schema_compiler/code.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 from code import Code 5 from code import Code
6 from model import PropertyType, Type 6 from model import PropertyType, Type
7 import cpp_util 7 import cpp_util
8 import model 8 import model
9 import schema_util 9 import schema_util
10 import sys 10 import sys
(...skipping 13 matching lines...) Expand all
24 """A .cc generator for a namespace. 24 """A .cc generator for a namespace.
25 """ 25 """
26 def __init__(self, namespace, cpp_type_generator, cpp_namespace): 26 def __init__(self, namespace, cpp_type_generator, cpp_namespace):
27 self._namespace = namespace 27 self._namespace = namespace
28 self._type_helper = cpp_type_generator 28 self._type_helper = cpp_type_generator
29 self._cpp_namespace = cpp_namespace 29 self._cpp_namespace = cpp_namespace
30 self._target_namespace = ( 30 self._target_namespace = (
31 self._type_helper.GetCppNamespaceName(self._namespace)) 31 self._type_helper.GetCppNamespaceName(self._namespace))
32 self._util_cc_helper = ( 32 self._util_cc_helper = (
33 util_cc_helper.UtilCCHelper(self._type_helper)) 33 util_cc_helper.UtilCCHelper(self._type_helper))
34 self._generate_error_messages = namespace.compiler_options.get(
35 'generate_error_messages', False)
34 36
35 def Generate(self): 37 def Generate(self):
36 """Generates a Code object with the .cc for a single namespace. 38 """Generates a Code object with the .cc for a single namespace.
37 """ 39 """
38 c = Code() 40 c = Code()
39 (c.Append(cpp_util.CHROMIUM_LICENSE) 41 (c.Append(cpp_util.CHROMIUM_LICENSE)
40 .Append() 42 .Append()
41 .Append(cpp_util.GENERATED_FILE_MESSAGE % self._namespace.source_file) 43 .Append(cpp_util.GENERATED_FILE_MESSAGE % self._namespace.source_file)
42 .Append() 44 .Append()
43 .Append(self._util_cc_helper.GetIncludePath()) 45 .Append(self._util_cc_helper.GetIncludePath())
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 177
176 def _GenerateTypePopulate(self, cpp_namespace, type_): 178 def _GenerateTypePopulate(self, cpp_namespace, type_):
177 """Generates the function for populating a type given a pointer to it. 179 """Generates the function for populating a type given a pointer to it.
178 180
179 E.g for type "Foo", generates Foo::Populate() 181 E.g for type "Foo", generates Foo::Populate()
180 """ 182 """
181 classname = cpp_util.Classname(schema_util.StripNamespace(type_.name)) 183 classname = cpp_util.Classname(schema_util.StripNamespace(type_.name))
182 c = Code() 184 c = Code()
183 (c.Append('// static') 185 (c.Append('// static')
184 .Append('bool %(namespace)s::Populate(') 186 .Append('bool %(namespace)s::Populate(')
185 .Sblock(' const base::Value& value, %(name)s* out) {') 187 .Sblock(' %s) {' % self._GenerateParams(
186 ) 188 ('const base::Value& value', '%(name)s* out'))))
189
187 if type_.property_type == PropertyType.CHOICES: 190 if type_.property_type == PropertyType.CHOICES:
188 for choice in type_.choices: 191 for choice in type_.choices:
189 (c.Sblock('if (%s) {' % self._GenerateValueIsTypeExpression('value', 192 (c.Sblock('if (%s) {' % self._GenerateValueIsTypeExpression('value',
190 choice)) 193 choice))
191 .Concat(self._GeneratePopulateVariableFromValue( 194 .Concat(self._GeneratePopulateVariableFromValue(
192 choice, 195 choice,
193 '(&value)', 196 '(&value)',
194 'out->as_%s' % choice.unix_name, 197 'out->as_%s' % choice.unix_name,
195 'false', 198 'false',
196 is_ptr=True)) 199 is_ptr=True))
197 .Append('return true;') 200 .Append('return true;')
198 .Eblock('}') 201 .Eblock('}')
199 ) 202 )
200 c.Append('return false;') 203 (c.Concat(self._GenerateError(
204 '"expected %s, got " + %s' %
205 (" or ".join(choice.name for choice in type_.choices),
206 self._util_cc_helper.GetValueTypeString('value'))))
207 .Append('return false;'))
201 elif type_.property_type == PropertyType.OBJECT: 208 elif type_.property_type == PropertyType.OBJECT:
202 (c.Append('if (!value.IsType(base::Value::TYPE_DICTIONARY))') 209 (c.Sblock('if (!value.IsType(base::Value::TYPE_DICTIONARY)) {')
203 .Append(' return false;') 210 .Concat(self._GenerateError(
204 ) 211 '"expected dictionary, got " + ' +
212 self._util_cc_helper.GetValueTypeString('value')))
213 .Append('return false;')
214 .Eblock('}'))
215
205 if type_.properties or type_.additional_properties is not None: 216 if type_.properties or type_.additional_properties is not None:
206 c.Append('const base::DictionaryValue* dict = ' 217 c.Append('const base::DictionaryValue* dict = '
207 'static_cast<const base::DictionaryValue*>(&value);') 218 'static_cast<const base::DictionaryValue*>(&value);')
208 for prop in type_.properties.values(): 219 for prop in type_.properties.values():
209 c.Concat(self._InitializePropertyToDefault(prop, 'out')) 220 c.Concat(self._InitializePropertyToDefault(prop, 'out'))
210 for prop in type_.properties.values(): 221 for prop in type_.properties.values():
211 c.Concat(self._GenerateTypePopulateProperty(prop, 'dict', 'out')) 222 c.Concat(self._GenerateTypePopulateProperty(prop, 'dict', 'out'))
212 if type_.additional_properties is not None: 223 if type_.additional_properties is not None:
213 if type_.additional_properties.property_type == PropertyType.ANY: 224 if type_.additional_properties.property_type == PropertyType.ANY:
214 c.Append('out->additional_properties.MergeDictionary(dict);') 225 c.Append('out->additional_properties.MergeDictionary(dict);')
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 'if (%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s)) {') 264 'if (%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s)) {')
254 .Concat(self._GeneratePopulatePropertyFromValue( 265 .Concat(self._GeneratePopulatePropertyFromValue(
255 prop, value_var, dst, 'false'))) 266 prop, value_var, dst, 'false')))
256 underlying_type = self._type_helper.FollowRef(prop.type_) 267 underlying_type = self._type_helper.FollowRef(prop.type_)
257 if underlying_type.property_type == PropertyType.ENUM: 268 if underlying_type.property_type == PropertyType.ENUM:
258 (c.Append('} else {') 269 (c.Append('} else {')
259 .Append('%%(dst)s->%%(name)s = %s;' % 270 .Append('%%(dst)s->%%(name)s = %s;' %
260 self._type_helper.GetEnumNoneValue(prop.type_))) 271 self._type_helper.GetEnumNoneValue(prop.type_)))
261 c.Eblock('}') 272 c.Eblock('}')
262 else: 273 else:
263 (c.Append( 274 (c.Sblock(
264 'if (!%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s))') 275 'if (!%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s)) {')
265 .Append(' return false;') 276 .Concat(self._GenerateError('"\'%%(key)s\' is required"'))
277 .Append('return false;')
278 .Eblock('}')
266 .Concat(self._GeneratePopulatePropertyFromValue( 279 .Concat(self._GeneratePopulatePropertyFromValue(
267 prop, value_var, dst, 'false')) 280 prop, value_var, dst, 'false'))
268 ) 281 )
269 c.Append() 282 c.Append()
270 c.Substitute({ 283 c.Substitute({
271 'value_var': value_var, 284 'value_var': value_var,
272 'key': prop.name, 285 'key': prop.name,
273 'src': src, 286 'src': src,
274 'dst': dst, 287 'dst': dst,
275 'name': prop.unix_name 288 'name': prop.unix_name
276 }) 289 })
277 return c 290 return c
278 291
279 def _GenerateTypeFromValue(self, cpp_namespace, type_): 292 def _GenerateTypeFromValue(self, cpp_namespace, type_):
280 classname = cpp_util.Classname(schema_util.StripNamespace(type_.name)) 293 classname = cpp_util.Classname(schema_util.StripNamespace(type_.name))
281 c = Code() 294 c = Code()
282 (c.Append('// static') 295 (c.Append('// static')
283 .Append('scoped_ptr<%s> %s::FromValue(const base::Value& value) {' % ( 296 .Append('scoped_ptr<%s> %s::FromValue(%s) {' % (classname,
284 classname, cpp_namespace)) 297 cpp_namespace, self._GenerateParams(('const base::Value& value',))))
285 .Append(' scoped_ptr<%s> out(new %s());' % (classname, classname)) 298 .Append(' scoped_ptr<%s> out(new %s());' % (classname, classname))
286 .Append(' if (!Populate(value, out.get()))') 299 .Append(' if (!Populate(%s))' % self._GenerateArgs(
300 ('value', 'out.get()')))
287 .Append(' return scoped_ptr<%s>();' % classname) 301 .Append(' return scoped_ptr<%s>();' % classname)
288 .Append(' return out.Pass();') 302 .Append(' return out.Pass();')
289 .Append('}') 303 .Append('}')
290 ) 304 )
291 return c 305 return c
292 306
293 def _GenerateTypeToValue(self, cpp_namespace, type_): 307 def _GenerateTypeToValue(self, cpp_namespace, type_):
294 """Generates a function that serializes the type into a base::Value. 308 """Generates a function that serializes the type into a base::Value.
295 E.g. for type "Foo" generates Foo::ToValue() 309 E.g. for type "Foo" generates Foo::ToValue()
296 """ 310 """
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 def _GenerateParamsCheck(self, function, var): 493 def _GenerateParamsCheck(self, function, var):
480 """Generates a check for the correct number of arguments when creating 494 """Generates a check for the correct number of arguments when creating
481 Params. 495 Params.
482 """ 496 """
483 c = Code() 497 c = Code()
484 num_required = 0 498 num_required = 0
485 for param in function.params: 499 for param in function.params:
486 if not param.optional: 500 if not param.optional:
487 num_required += 1 501 num_required += 1
488 if num_required == len(function.params): 502 if num_required == len(function.params):
489 c.Append('if (%(var)s.GetSize() != %(total)d)') 503 c.Sblock('if (%(var)s.GetSize() != %(total)d) {')
490 elif not num_required: 504 elif not num_required:
491 c.Append('if (%(var)s.GetSize() > %(total)d)') 505 c.Sblock('if (%(var)s.GetSize() > %(total)d) {')
492 else: 506 else:
493 c.Append('if (%(var)s.GetSize() < %(required)d' 507 c.Sblock('if (%(var)s.GetSize() < %(required)d'
494 ' || %(var)s.GetSize() > %(total)d)') 508 ' || %(var)s.GetSize() > %(total)d) {')
495 c.Append(' return scoped_ptr<Params>();') 509 (c.Concat(self._GenerateError(
496 c.Substitute({ 510 '"expected %%(total)d arguments, got " '
511 '+ base::IntToString(%%(var)s.GetSize())'))
512 .Append('return scoped_ptr<Params>();')
513 .Eblock('}')
514 .Substitute({
497 'var': var, 515 'var': var,
498 'required': num_required, 516 'required': num_required,
499 'total': len(function.params), 517 'total': len(function.params),
500 }) 518 }))
501 return c 519 return c
502 520
503 def _GenerateFunctionParamsCreate(self, function): 521 def _GenerateFunctionParamsCreate(self, function):
504 """Generate function to create an instance of Params. The generated 522 """Generate function to create an instance of Params. The generated
505 function takes a base::ListValue of arguments. 523 function takes a base::ListValue of arguments.
506 524
507 E.g for function "Bar", generate Bar::Params::Create() 525 E.g for function "Bar", generate Bar::Params::Create()
508 """ 526 """
509 c = Code() 527 c = Code()
510 (c.Append('// static') 528 (c.Append('// static')
511 .Sblock('scoped_ptr<Params> ' 529 .Sblock('scoped_ptr<Params> Params::Create(%s) {' % self._GenerateParams(
512 'Params::Create(const base::ListValue& args) {') 530 ['const base::ListValue& args']))
513 .Concat(self._GenerateParamsCheck(function, 'args')) 531 .Concat(self._GenerateParamsCheck(function, 'args'))
514 .Append('scoped_ptr<Params> params(new Params());') 532 .Append('scoped_ptr<Params> params(new Params());'))
515 )
516 533
517 for param in function.params: 534 for param in function.params:
518 c.Concat(self._InitializePropertyToDefault(param, 'params')) 535 c.Concat(self._InitializePropertyToDefault(param, 'params'))
519 536
520 for i, param in enumerate(function.params): 537 for i, param in enumerate(function.params):
521 # Any failure will cause this function to return. If any argument is 538 # Any failure will cause this function to return. If any argument is
522 # incorrect or missing, those following it are not processed. Note that 539 # incorrect or missing, those following it are not processed. Note that
523 # for optional arguments, we allow missing arguments and proceed because 540 # for optional arguments, we allow missing arguments and proceed because
524 # there may be other arguments following it. 541 # there may be other arguments following it.
525 failure_value = 'scoped_ptr<Params>()' 542 failure_value = 'scoped_ptr<Params>()'
526 c.Append() 543 c.Append()
527 value_var = param.unix_name + '_value' 544 value_var = param.unix_name + '_value'
528 (c.Append('const base::Value* %(value_var)s = NULL;') 545 (c.Append('const base::Value* %(value_var)s = NULL;')
529 .Append('if (args.Get(%(i)s, &%(value_var)s) &&') 546 .Append('if (args.Get(%(i)s, &%(value_var)s) &&')
530 .Sblock(' !%(value_var)s->IsType(base::Value::TYPE_NULL)) {') 547 .Sblock(' !%(value_var)s->IsType(base::Value::TYPE_NULL)) {')
531 .Concat(self._GeneratePopulatePropertyFromValue( 548 .Concat(self._GeneratePopulatePropertyFromValue(
532 param, value_var, 'params', failure_value)) 549 param, value_var, 'params', failure_value))
533 .Eblock('}') 550 .Eblock('}')
534 ) 551 )
535 if not param.optional: 552 if not param.optional:
536 (c.Sblock('else {') 553 (c.Sblock('else {')
554 .Concat(self._GenerateError('"\'%%(key)s\' is required"'))
537 .Append('return %s;' % failure_value) 555 .Append('return %s;' % failure_value)
538 .Eblock('}') 556 .Eblock('}'))
539 ) 557 c.Substitute({'value_var': value_var, 'i': i, 'key': param.name})
540 c.Substitute({'value_var': value_var, 'i': i})
541 (c.Append() 558 (c.Append()
542 .Append('return params.Pass();') 559 .Append('return params.Pass();')
543 .Eblock('}') 560 .Eblock('}')
544 .Append() 561 .Append()
545 ) 562 )
546 563
547 return c 564 return c
548 565
549 def _GeneratePopulatePropertyFromValue(self, 566 def _GeneratePopulatePropertyFromValue(self,
550 prop, 567 prop,
(...skipping 23 matching lines...) Expand all
574 |failure_value|. 591 |failure_value|.
575 """ 592 """
576 c = Code() 593 c = Code()
577 c.Sblock('{') 594 c.Sblock('{')
578 595
579 underlying_type = self._type_helper.FollowRef(type_) 596 underlying_type = self._type_helper.FollowRef(type_)
580 597
581 if underlying_type.property_type.is_fundamental: 598 if underlying_type.property_type.is_fundamental:
582 if is_ptr: 599 if is_ptr:
583 (c.Append('%(cpp_type)s temp;') 600 (c.Append('%(cpp_type)s temp;')
584 .Append('if (!%s)' % cpp_util.GetAsFundamentalValue( 601 .Sblock('if (!%s) {' % cpp_util.GetAsFundamentalValue(
585 self._type_helper.FollowRef(type_), src_var, '&temp')) 602 self._type_helper.FollowRef(type_), src_var, '&temp'))
586 .Append(' return %(failure_value)s;') 603 .Concat(self._GenerateError(
604 '"\'%%(key)s\': expected ' + '%s, got " + %s' % (
605 type_.name,
606 self._util_cc_helper.GetValueTypeString(
607 '%%(src_var)s', True))))
608 .Append('return %(failure_value)s;')
609 .Eblock('}')
587 .Append('%(dst_var)s.reset(new %(cpp_type)s(temp));') 610 .Append('%(dst_var)s.reset(new %(cpp_type)s(temp));')
588 ) 611 )
589 else: 612 else:
590 (c.Append('if (!%s)' % cpp_util.GetAsFundamentalValue( 613 (c.Sblock('if (!%s) {' % cpp_util.GetAsFundamentalValue(
591 self._type_helper.FollowRef(type_), 614 self._type_helper.FollowRef(type_),
592 src_var, 615 src_var,
593 '&%s' % dst_var)) 616 '&%s' % dst_var))
594 .Append(' return %(failure_value)s;') 617 .Concat(self._GenerateError(
618 '"\'%%(key)s\': expected ' + '%s, got " + %s' % (
619 type_.name,
620 self._util_cc_helper.GetValueTypeString(
621 '%%(src_var)s', True))))
622 .Append('return %(failure_value)s;')
623 .Eblock('}')
595 ) 624 )
596 elif underlying_type.property_type == PropertyType.OBJECT: 625 elif underlying_type.property_type == PropertyType.OBJECT:
597 if is_ptr: 626 if is_ptr:
598 (c.Append('const base::DictionaryValue* dictionary = NULL;') 627 (c.Append('const base::DictionaryValue* dictionary = NULL;')
599 .Append('if (!%(src_var)s->GetAsDictionary(&dictionary))') 628 .Sblock('if (!%(src_var)s->GetAsDictionary(&dictionary)) {')
629 .Concat(self._GenerateError(
630 '"\'%%(key)s\': expected dictionary, got " + ' +
631 self._util_cc_helper.GetValueTypeString('%%(src_var)s', True)))
632 .Append('return %(failure_value)s;')
633 .Eblock('}')
634 .Append('scoped_ptr<%(cpp_type)s> temp(new %(cpp_type)s());')
635 .Append('if (!%%(cpp_type)s::Populate(%s)) {' % self._GenerateArgs(
636 ('*dictionary', 'temp.get()')))
600 .Append(' return %(failure_value)s;') 637 .Append(' return %(failure_value)s;')
601 .Append('scoped_ptr<%(cpp_type)s> temp(new %(cpp_type)s());') 638 .Append('}')
602 .Append('if (!%(cpp_type)s::Populate(*dictionary, temp.get()))')
603 .Append(' return %(failure_value)s;')
604 .Append('%(dst_var)s = temp.Pass();') 639 .Append('%(dst_var)s = temp.Pass();')
605 ) 640 )
606 else: 641 else:
607 (c.Append('const base::DictionaryValue* dictionary = NULL;') 642 (c.Append('const base::DictionaryValue* dictionary = NULL;')
608 .Append('if (!%(src_var)s->GetAsDictionary(&dictionary))') 643 .Sblock('if (!%(src_var)s->GetAsDictionary(&dictionary)) {')
644 .Concat(self._GenerateError(
645 '"\'%%(key)s\': expected dictionary, got " + ' +
646 self._util_cc_helper.GetValueTypeString('%%(src_var)s', True)))
647 .Append('return %(failure_value)s;')
648 .Eblock('}')
649 .Append('if (!%%(cpp_type)s::Populate(%s)) {' % self._GenerateArgs(
650 ('*dictionary', '&%(dst_var)s')))
609 .Append(' return %(failure_value)s;') 651 .Append(' return %(failure_value)s;')
610 .Append('if (!%(cpp_type)s::Populate(*dictionary, &%(dst_var)s))') 652 .Append('}')
611 .Append(' return %(failure_value)s;')
612 ) 653 )
613 elif underlying_type.property_type == PropertyType.FUNCTION: 654 elif underlying_type.property_type == PropertyType.FUNCTION:
614 if is_ptr: 655 if is_ptr:
615 c.Append('%(dst_var)s.reset(new base::DictionaryValue());') 656 c.Append('%(dst_var)s.reset(new base::DictionaryValue());')
616 elif underlying_type.property_type == PropertyType.ANY: 657 elif underlying_type.property_type == PropertyType.ANY:
617 c.Append('%(dst_var)s.reset(%(src_var)s->DeepCopy());') 658 c.Append('%(dst_var)s.reset(%(src_var)s->DeepCopy());')
618 elif underlying_type.property_type == PropertyType.ARRAY: 659 elif underlying_type.property_type == PropertyType.ARRAY:
619 # util_cc_helper deals with optional and required arrays 660 # util_cc_helper deals with optional and required arrays
620 (c.Append('const base::ListValue* list = NULL;') 661 (c.Append('const base::ListValue* list = NULL;')
621 .Append('if (!%(src_var)s->GetAsList(&list))') 662 .Sblock('if (!%(src_var)s->GetAsList(&list)) {')
622 .Append(' return %(failure_value)s;')) 663 .Concat(self._GenerateError(
664 '"\'%%(key)s\': expected list, got " + ' +
665 self._util_cc_helper.GetValueTypeString('%%(src_var)s', True)))
666 .Append('return %(failure_value)s;')
667 .Eblock('}'))
623 item_type = self._type_helper.FollowRef(underlying_type.item_type) 668 item_type = self._type_helper.FollowRef(underlying_type.item_type)
624 if item_type.property_type == PropertyType.ENUM: 669 if item_type.property_type == PropertyType.ENUM:
625 c.Concat(self._GenerateListValueToEnumArrayConversion( 670 c.Concat(self._GenerateListValueToEnumArrayConversion(
626 item_type, 671 item_type,
627 'list', 672 'list',
628 dst_var, 673 dst_var,
629 failure_value, 674 failure_value,
630 is_ptr=is_ptr)) 675 is_ptr=is_ptr))
631 else: 676 else:
632 (c.Append('if (!%s)' % self._util_cc_helper.PopulateArrayFromList( 677 (c.Sblock('if (!%s) {' % self._util_cc_helper.PopulateArrayFromList(
633 underlying_type, 678 underlying_type,
634 'list', 679 'list',
635 dst_var, 680 dst_var,
636 is_ptr)) 681 is_ptr))
637 .Append(' return %(failure_value)s;') 682 .Concat(self._GenerateError(
683 '"unable to populate array \'%%(parent_key)s\'"'))
684 .Append('return %(failure_value)s;')
685 .Eblock('}')
638 ) 686 )
639 elif underlying_type.property_type == PropertyType.CHOICES: 687 elif underlying_type.property_type == PropertyType.CHOICES:
640 if is_ptr: 688 if is_ptr:
641 (c.Append('scoped_ptr<%(cpp_type)s> temp(new %(cpp_type)s());') 689 (c.Append('scoped_ptr<%(cpp_type)s> temp(new %(cpp_type)s());')
642 .Append('if (!%(cpp_type)s::Populate(*%(src_var)s, temp.get()))') 690 .Append('if (!%%(cpp_type)s::Populate(%s))' % self._GenerateArgs(
691 ('*%(src_var)s', 'temp.get()')))
643 .Append(' return %(failure_value)s;') 692 .Append(' return %(failure_value)s;')
644 .Append('%(dst_var)s = temp.Pass();') 693 .Append('%(dst_var)s = temp.Pass();')
645 ) 694 )
646 else: 695 else:
647 (c.Append('if (!%(cpp_type)s::Populate(*%(src_var)s, &%(dst_var)s))') 696 (c.Append('if (!%%(cpp_type)s::Populate(%s))' % self._GenerateArgs(
648 .Append(' return %(failure_value)s;') 697 ('*%(src_var)s', '&%(dst_var)s')))
649 ) 698 .Append(' return %(failure_value)s;'))
650 elif underlying_type.property_type == PropertyType.ENUM: 699 elif underlying_type.property_type == PropertyType.ENUM:
651 c.Concat(self._GenerateStringToEnumConversion(type_, 700 c.Concat(self._GenerateStringToEnumConversion(type_,
652 src_var, 701 src_var,
653 dst_var, 702 dst_var,
654 failure_value)) 703 failure_value))
655 elif underlying_type.property_type == PropertyType.BINARY: 704 elif underlying_type.property_type == PropertyType.BINARY:
656 (c.Append('if (!%(src_var)s->IsType(base::Value::TYPE_BINARY))') 705 (c.Sblock('if (!%(src_var)s->IsType(base::Value::TYPE_BINARY)) {')
657 .Append(' return %(failure_value)s;') 706 .Concat(self._GenerateError(
707 '"\'%%(key)s\': expected binary, got " + ' +
708 self._util_cc_helper.GetValueTypeString('%%(src_var)s', True)))
709 .Append('return %(failure_value)s;')
710 .Eblock('}')
658 .Append('const base::BinaryValue* binary_value =') 711 .Append('const base::BinaryValue* binary_value =')
659 .Append(' static_cast<const base::BinaryValue*>(%(src_var)s);') 712 .Append(' static_cast<const base::BinaryValue*>(%(src_var)s);')
660 ) 713 )
661 if is_ptr: 714 if is_ptr:
662 (c.Append('%(dst_var)s.reset(') 715 (c.Append('%(dst_var)s.reset(')
663 .Append(' new std::string(binary_value->GetBuffer(),') 716 .Append(' new std::string(binary_value->GetBuffer(),')
664 .Append(' binary_value->GetSize()));') 717 .Append(' binary_value->GetSize()));')
665 ) 718 )
666 else: 719 else:
667 (c.Append('%(dst_var)s.assign(binary_value->GetBuffer(),') 720 (c.Append('%(dst_var)s.assign(binary_value->GetBuffer(),')
668 .Append(' binary_value->GetSize());') 721 .Append(' binary_value->GetSize());')
669 ) 722 )
670 else: 723 else:
671 raise NotImplementedError(type_) 724 raise NotImplementedError(type_)
672 return c.Eblock('}').Substitute({ 725 return c.Eblock('}').Substitute({
673 'cpp_type': self._type_helper.GetCppType(type_), 726 'cpp_type': self._type_helper.GetCppType(type_),
674 'src_var': src_var, 727 'src_var': src_var,
675 'dst_var': dst_var, 728 'dst_var': dst_var,
676 'failure_value': failure_value, 729 'failure_value': failure_value,
730 'key': type_.name,
731 'parent_key': type_.parent.name
677 }) 732 })
678 733
679 def _GenerateListValueToEnumArrayConversion(self, 734 def _GenerateListValueToEnumArrayConversion(self,
680 item_type, 735 item_type,
681 src_var, 736 src_var,
682 dst_var, 737 dst_var,
683 failure_value, 738 failure_value,
684 is_ptr=False): 739 is_ptr=False):
685 """Returns Code that converts a ListValue of string constants from 740 """Returns Code that converts a ListValue of string constants from
686 |src_var| into an array of enums of |type_| in |dst_var|. On failure, 741 |src_var| into an array of enums of |type_| in |dst_var|. On failure,
(...skipping 23 matching lines...) Expand all
710 src_var, 765 src_var,
711 dst_var, 766 dst_var,
712 failure_value): 767 failure_value):
713 """Returns Code that converts a string type in |src_var| to an enum with 768 """Returns Code that converts a string type in |src_var| to an enum with
714 type |type_| in |dst_var|. In the generated code, if |src_var| is not 769 type |type_| in |dst_var|. In the generated code, if |src_var| is not
715 a valid enum name then the function will return |failure_value|. 770 a valid enum name then the function will return |failure_value|.
716 """ 771 """
717 c = Code() 772 c = Code()
718 enum_as_string = '%s_as_string' % type_.unix_name 773 enum_as_string = '%s_as_string' % type_.unix_name
719 (c.Append('std::string %s;' % enum_as_string) 774 (c.Append('std::string %s;' % enum_as_string)
720 .Append('if (!%s->GetAsString(&%s))' % (src_var, enum_as_string)) 775 .Sblock('if (!%s->GetAsString(&%s)) {' % (src_var, enum_as_string))
721 .Append(' return %s;' % failure_value) 776 .Concat(self._GenerateError(
777 '"\'%%(key)s\': expected string, got " + ' +
778 self._util_cc_helper.GetValueTypeString('%%(src_var)s', True)))
779 .Append('return %s;' % failure_value)
780 .Eblock('}')
722 .Append('%s = Parse%s(%s);' % (dst_var, 781 .Append('%s = Parse%s(%s);' % (dst_var,
723 self._type_helper.GetCppType(type_), 782 self._type_helper.GetCppType(type_),
724 enum_as_string)) 783 enum_as_string))
725 .Append('if (%s == %s)' % (dst_var, 784 .Sblock('if (%s == %s) {' % (dst_var,
726 self._type_helper.GetEnumNoneValue(type_))) 785 self._type_helper.GetEnumNoneValue(type_)))
727 .Append(' return %s;' % failure_value) 786 .Concat(self._GenerateError(
787 '\"\'%%(key)s\': expected \\"' +
788 '\\" or \\"'.join(self._type_helper.FollowRef(type_).enum_values) +
789 '\\", got \\"" + %s + "\\""' % enum_as_string))
790 .Append('return %s;' % failure_value)
791 .Eblock('}')
792 .Substitute({'src_var': src_var, 'key': type_.name})
728 ) 793 )
729 return c 794 return c
730 795
731 def _GeneratePropertyFunctions(self, namespace, params): 796 def _GeneratePropertyFunctions(self, namespace, params):
732 """Generates the member functions for a list of parameters. 797 """Generates the member functions for a list of parameters.
733 """ 798 """
734 return self._GenerateTypes(namespace, (param.type_ for param in params)) 799 return self._GenerateTypes(namespace, (param.type_ for param in params))
735 800
736 def _GenerateTypes(self, namespace, types): 801 def _GenerateTypes(self, namespace, types):
737 """Generates the member functions for a list of types. 802 """Generates the member functions for a list of types.
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 """ 908 """
844 c = Code() 909 c = Code()
845 underlying_type = self._type_helper.FollowRef(prop.type_) 910 underlying_type = self._type_helper.FollowRef(prop.type_)
846 if (underlying_type.property_type == PropertyType.ENUM and 911 if (underlying_type.property_type == PropertyType.ENUM and
847 prop.optional): 912 prop.optional):
848 c.Append('%s->%s = %s;' % ( 913 c.Append('%s->%s = %s;' % (
849 dst, 914 dst,
850 prop.unix_name, 915 prop.unix_name,
851 self._type_helper.GetEnumNoneValue(prop.type_))) 916 self._type_helper.GetEnumNoneValue(prop.type_)))
852 return c 917 return c
918
919 def _GenerateError(self, body):
920 """Generates an error message pertaining to population failure.
921
922 E.g 'expected bool, got int'
923 """
924 c = Code()
925 if not self._generate_error_messages:
926 return c
927 (c.Append('if (error)')
928 .Append(' *error = ' + body + ';'))
929 return c
930
931 def _GenerateParams(self, params):
932 """Builds the parameter list for a function, given an array of parameters.
933 """
934 if self._generate_error_messages:
935 params = list(params) + ['std::string* error']
936 return ', '.join(str(p) for p in params)
937
938 def _GenerateArgs(self, args):
939 """Builds the argument list for a function, given an array of arguments.
940 """
941 if self._generate_error_messages:
942 args = list(args) + ['error']
943 return ', '.join(str(a) for a in args)
OLDNEW
« no previous file with comments | « chrome/chrome_tests_unit.gypi ('k') | tools/json_schema_compiler/code.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698