Esempio n. 1
0
 def _GenerateValueIsTypeExpression(self, var, type_):
   real_type = self._type_helper.FollowRef(type_)
   if real_type.property_type is PropertyType.CHOICES:
     return '(%s)' % ' || '.join(self._GenerateValueIsTypeExpression(var,
                                                                     choice)
                                 for choice in real_type.choices)
   return '%s.IsType(%s)' % (var, cpp_util.GetValueType(real_type))
Esempio n. 2
0
    def _GeneratePopulatePropertyFromValue(self,
                                           prop,
                                           value_var,
                                           dst,
                                           failure_value,
                                           check_type=True):
        """Generates code to populate a model.Property given a base::Value*. The
    existence of data inside the base::Value* is assumed so checks for existence
    should be performed before the code this generates.

    prop: the property the code is populating.
    value_var: a base::Value* that should represent |prop|.
    dst: the object with |prop| as a member.
    failure_value: the value to return if |prop| cannot be extracted from
    |value_var|
    check_type: if true, will check if |value_var| is the correct
    base::Value::Type
    """
        c = Code()
        c.Sblock('{')

        if self._IsFundamentalOrFundamentalRef(prop):
            self._GenerateFundamentalOrFundamentalRefPopulate(
                c, prop, value_var, dst)
        elif self._IsObjectOrObjectRef(prop):
            self._GenerateObjectOrObjectRefPopulate(c, prop)
        elif prop.type_ == PropertyType.FUNCTION:
            self._GenerateFunctionPopulate(c, prop)
        elif prop.type_ == PropertyType.ANY:
            self._GenerateAnyPopulate(c, prop, value_var, dst)
        elif self._IsArrayOrArrayRef(prop):
            self._GenerateArrayOrArrayRefPopulate(c, prop, dst)
        elif prop.type_ == PropertyType.CHOICES:
            self._GenerateChoicePopulate(c, prop, value_var, dst,
                                         failure_value)
        elif self._cpp_type_generator.IsEnumOrEnumRef(prop):
            self._GenerateEnumPopulate(c, prop, value_var)
        elif prop.type_ == PropertyType.BINARY:
            self._GenerateBinaryPopulate(c, prop)
        else:
            raise NotImplementedError(prop.type_)
        c.Eblock('}')
        sub = {
            'value_var': value_var,
            'name': prop.unix_name,
            'dst': dst,
            'failure_value': failure_value,
        }
        if prop.type_ not in (PropertyType.CHOICES, PropertyType.ANY):
            sub['ctype'] = self._cpp_type_generator.GetType(prop)
            sub['compiled_ctype'] = self._cpp_type_generator.GetCompiledType(
                prop)
            sub['value_type'] = cpp_util.GetValueType(
                self._cpp_type_generator.GetReferencedProperty(prop).type_)
        c.Substitute(sub)
        return c
Esempio n. 3
0
    def _GenerateTypePopulate(self, cpp_namespace, type_):
        """Generates the function for populating a type given a pointer to it.

    E.g for type "Foo", generates Foo::Populate()
    """
        classname = cpp_util.Classname(schema_util.StripNamespace(type_.name))
        c = Code()
        (c.Append('// static').Append('bool %(namespace)s::Populate(').Sblock(
            '    const base::Value& value, %(name)s* out) {'))
        if type_.property_type == PropertyType.CHOICES:
            for choice in type_.choices:
                value_type = cpp_util.GetValueType(
                    self._type_helper.FollowRef(choice))
                (c.Sblock('if (value.IsType(%s)) {' % value_type).Concat(
                    self._GeneratePopulateVariableFromValue(
                        choice,
                        '(&value)',
                        'out->as_%s' % choice.unix_name,
                        'false',
                        is_ptr=True)).Append('return true;').Eblock('}'))
            c.Append('return false;')
        elif type_.property_type == PropertyType.OBJECT:
            (c.Append('if (!value.IsType(base::Value::TYPE_DICTIONARY))').
             Append('  return false;'))
            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():
                c.Concat(self._InitializePropertyToDefault(prop, 'out'))
            for prop in type_.properties.values():
                c.Concat(
                    self._GenerateTypePopulateProperty(prop, 'dict', 'out'))
            if type_.additional_properties is not None:
                if type_.additional_properties.property_type == PropertyType.ANY:
                    c.Append(
                        'out->additional_properties.MergeDictionary(dict);')
                else:
                    cpp_type = self._type_helper.GetCppType(
                        type_.additional_properties, is_in_container=True)
                    (c.Append('for (base::DictionaryValue::Iterator it(*dict);'
                              ).Sblock('     !it.IsAtEnd(); it.Advance()) {').
                     Append('%s tmp;' % cpp_type).Concat(
                         self._GeneratePopulateVariableFromValue(
                             type_.additional_properties, '(&it.value())',
                             'tmp', 'false')).Append(
                                 'out->additional_properties[it.key()] = tmp;'
                             ).Eblock('}'))
            c.Append('return true;')
        (c.Eblock('}').Substitute({
            'namespace': cpp_namespace,
            'name': classname
        }))
        return c
Esempio n. 4
0
 def _GenerateChoicePopulate(self, c, prop, value_var, dst, failure_value):
     type_var = '%(dst)s->%(name)s_type'
     c.Sblock('switch (%(value_var)s->GetType()) {')
     for choice in self._cpp_type_generator.ExpandParams([prop]):
         (c.Sblock('case %s: {' % cpp_util.GetValueType(
             self._cpp_type_generator.GetReferencedProperty(choice).type_)).
          Concat(
              self._GeneratePopulatePropertyFromValue(
                  choice, value_var, dst, failure_value,
                  check_type=False)).Append(
                      '%s = %s;' % (type_var,
                                    self._cpp_type_generator.GetEnumValue(
                                        prop, choice.type_.name))).Append(
                                            'break;').Eblock('}'))
     (c.Append('default:').Append('  return %(failure_value)s;'))
     c.Eblock('}')
Esempio n. 5
0
    def _GeneratePopulatePropertyFromValue(self,
                                           prop,
                                           value_var,
                                           dst,
                                           failure_value,
                                           check_type=True):
        """Generates code to populate a model.Property given a Value*. The
    existence of data inside the Value* is assumed so checks for existence
    should be performed before the code this generates.

    prop: the property the code is populating.
    value_var: a Value* that should represent |prop|.
    dst: the object with |prop| as a member.
    failure_value: the value to return if |prop| cannot be extracted from
    |value_var|
    check_type: if true, will check if |value_var| is the correct Value::Type
    """
        c = Code()
        c.Sblock('{')

        if self._IsFundamentalOrFundamentalRef(prop):
            if prop.optional:
                (c.Append('%(ctype)s temp;').Append(
                    'if (!%s)' % cpp_util.GetAsFundamentalValue(
                        self._cpp_type_generator.GetReferencedProperty(prop),
                        value_var,
                        '&temp')).Append('  return %(failure_value)s;').Append(
                            '%(dst)s->%(name)s.reset(new %(ctype)s(temp));'))
            else:
                (c.Append('if (!%s)' % cpp_util.GetAsFundamentalValue(
                    self._cpp_type_generator.GetReferencedProperty(prop),
                    value_var, '&%s->%s' % (dst, prop.unix_name))).Append(
                        '  return %(failure_value)s;'))
        elif self._IsObjectOrObjectRef(prop):
            if prop.optional:
                (c.Append('DictionaryValue* dictionary = NULL;').Append(
                    'if (!%(value_var)s->GetAsDictionary(&dictionary))').
                 Append('  return %(failure_value)s;').Append(
                     'scoped_ptr<%(ctype)s> temp(new %(ctype)s());').Append(
                         'if (!%(ctype)s::Populate(*dictionary, temp.get()))').
                 Append('  return %(failure_value)s;').Append(
                     '%(dst)s->%(name)s = temp.Pass();'))
            else:
                (c.Append('DictionaryValue* dictionary = NULL;').Append(
                    'if (!%(value_var)s->GetAsDictionary(&dictionary))'
                ).Append('  return %(failure_value)s;').Append(
                    'if (!%(ctype)s::Populate(*dictionary, &%(dst)s->%(name)s))'
                ).Append('  return %(failure_value)s;'))
        elif prop.type_ == PropertyType.ANY:
            if prop.optional:
                c.Append('%(dst)s->%(name)s.reset(new Any());')
            c.Append(self._any_helper.Init(prop, value_var, dst) + ';')
        elif self._IsArrayOrArrayRef(prop):
            # util_cc_helper deals with optional and required arrays
            (c.Append('ListValue* list = NULL;').
             Append('if (!%(value_var)s->GetAsList(&list))').Append(
                 '  return %(failure_value)s;').Append(
                     'if (!%s)' % self._util_cc_helper.PopulateArrayFromList(
                         self._cpp_type_generator.GetReferencedProperty(prop),
                         'list', dst + '->' + prop.unix_name,
                         prop.optional)).Append('  return %(failure_value)s;'))
        elif prop.type_ == PropertyType.CHOICES:
            type_var = '%(dst)s->%(name)s_type'
            c.Sblock('switch (%(value_var)s->GetType()) {')
            for choice in self._cpp_type_generator.GetExpandedChoicesInParams(
                [prop]):
                (c.Sblock('case %s: {' % cpp_util.GetValueType(
                    self._cpp_type_generator.GetReferencedProperty(
                        choice).type_)).Concat(
                            self._GeneratePopulatePropertyFromValue(
                                choice,
                                value_var,
                                dst,
                                failure_value,
                                check_type=False)).Append(
                                    '%s = %s;' %
                                    (type_var,
                                     self._cpp_type_generator.GetEnumValue(
                                         prop, choice.type_.name))).Append(
                                             'break;').Eblock('}'))
            (c.Append('default:').Append('  return %(failure_value)s;'))
            c.Eblock('}')
        elif prop.type_ == PropertyType.ENUM:
            (c.Append('std::string enum_temp;').Append(
                'if (!%(value_var)s->GetAsString(&enum_temp))').Append(
                    '  return %(failure_value)s;'))
            for i, enum_value in enumerate(prop.enum_values):
                (c.Append(('if' if i == 0 else 'else if') +
                          '(enum_temp == "%s")' % enum_value).Append(
                              '  %s->%s = %s;' %
                              (dst, prop.unix_name,
                               self._cpp_type_generator.GetEnumValue(
                                   prop, enum_value))))
            (c.Append('else').Append('  return %(failure_value)s;'))
        elif prop.type_ == PropertyType.BINARY:
            # This is the same if the property is optional or not. We need a pointer
            # to the BinaryValue to be able to populate it, so a scoped_ptr is used
            # whether it is optional or required.
            (c.Append('if (!%(value_var)s->IsType(%(value_type)s))').Append(
                '  return %(failure_value)s;').
             Append('%(dst)s->%(name)s.reset(').Append(
                 '    static_cast<BinaryValue*>(%(value_var)s)->DeepCopy());'))
        else:
            raise NotImplementedError(prop.type_)
        c.Eblock('}')
        sub = {
            'value_var': value_var,
            'name': prop.unix_name,
            'dst': dst,
            'failure_value': failure_value,
        }
        if prop.type_ not in (PropertyType.CHOICES, PropertyType.ANY):
            sub['ctype'] = self._cpp_type_generator.GetType(prop)
            sub['value_type'] = cpp_util.GetValueType(
                self._cpp_type_generator.GetReferencedProperty(prop).type_)
        c.Substitute(sub)
        return c
Esempio n. 6
0
    def _GeneratePopulateVariableFromValue(self,
                                           type_,
                                           src_var,
                                           dst_var,
                                           failure_value,
                                           is_ptr=False):
        """Generates code to populate a variable |dst_var| of type |type_| from a
    Value* at |src_var|. The Value* is assumed to be non-NULL. In the generated
    code, if |dst_var| fails to be populated then Populate will return
    |failure_value|.
    """
        c = Code()
        c.Sblock('{')

        underlying_type = self._type_helper.FollowRef(type_)

        if underlying_type.property_type.is_fundamental:
            if is_ptr:
                (c.Append('%(cpp_type)s temp;').Append(
                    'if (!%s)' % cpp_util.GetAsFundamentalValue(
                        self._type_helper.FollowRef(type_), src_var,
                        '&temp')).Append('  return %(failure_value)s;').Append(
                            '%(dst_var)s.reset(new %(cpp_type)s(temp));'))
            else:
                (c.Append('if (!%s)' % cpp_util.GetAsFundamentalValue(
                    self._type_helper.FollowRef(type_), src_var,
                    '&%s' % dst_var)).Append('  return %(failure_value)s;'))
        elif underlying_type.property_type == PropertyType.OBJECT:
            if is_ptr:
                (c.Append('const base::DictionaryValue* dictionary = NULL;').
                 Append('if (!%(src_var)s->GetAsDictionary(&dictionary))').
                 Append('  return %(failure_value)s;').Append(
                     'scoped_ptr<%(cpp_type)s> temp(new %(cpp_type)s());').
                 Append('if (!%(cpp_type)s::Populate(*dictionary, temp.get()))'
                        ).Append('  return %(failure_value)s;').Append(
                            '%(dst_var)s = temp.Pass();'))
            else:
                (c.Append('const base::DictionaryValue* dictionary = NULL;').
                 Append('if (!%(src_var)s->GetAsDictionary(&dictionary))').
                 Append('  return %(failure_value)s;').Append(
                     'if (!%(cpp_type)s::Populate(*dictionary, &%(dst_var)s))'
                 ).Append('  return %(failure_value)s;'))
        elif underlying_type.property_type == PropertyType.FUNCTION:
            if is_ptr:
                c.Append('%(dst_var)s.reset(new base::DictionaryValue());')
        elif underlying_type.property_type == PropertyType.ANY:
            c.Append('%(dst_var)s.reset(%(src_var)s->DeepCopy());')
        elif underlying_type.property_type == PropertyType.ARRAY:
            # util_cc_helper deals with optional and required arrays
            (c.Append('const base::ListValue* list = NULL;').Append(
                'if (!%(src_var)s->GetAsList(&list))').Append(
                    '  return %(failure_value)s;'))
            item_type = underlying_type.item_type
            if item_type.property_type == PropertyType.ENUM:
                c.Concat(
                    self._GenerateListValueToEnumArrayConversion(
                        item_type,
                        'list',
                        dst_var,
                        failure_value,
                        is_ptr=is_ptr))
            else:
                (c.Append('if (!%s)' %
                          self._util_cc_helper.PopulateArrayFromList(
                              underlying_type, 'list', dst_var,
                              is_ptr)).Append('  return %(failure_value)s;'))
        elif underlying_type.property_type == PropertyType.CHOICES:
            if is_ptr:
                (c.Append('scoped_ptr<%(cpp_type)s> temp(new %(cpp_type)s());')
                 .Append(
                     'if (!%(cpp_type)s::Populate(*%(src_var)s, temp.get()))').
                 Append('  return %(failure_value)s;').Append(
                     '%(dst_var)s = temp.Pass();'))
            else:
                (c.Append(
                    'if (!%(cpp_type)s::Populate(*%(src_var)s, &%(dst_var)s))'
                ).Append('  return %(failure_value)s;'))
        elif underlying_type.property_type == PropertyType.ENUM:
            c.Concat(
                self._GenerateStringToEnumConversion(type_, src_var, dst_var,
                                                     failure_value))
        elif underlying_type.property_type == PropertyType.BINARY:
            (c.Append('if (!%(src_var)s->IsType(%(value_type)s))').Append(
                '  return %(failure_value)s;').
             Append('const base::BinaryValue* binary_value =').Append(
                 '    static_cast<const base::BinaryValue*>(%(src_var)s);'))
            if is_ptr:
                (c.Append('%(dst_var)s.reset(').Append(
                    '    new std::string(binary_value->GetBuffer(),').Append(
                        '                    binary_value->GetSize()));'))
            else:
                (c.Append('%(dst_var)s.assign(binary_value->GetBuffer(),').
                 Append('                   binary_value->GetSize());'))
        else:
            raise NotImplementedError(type_)

        sub = {
            'cpp_type': self._type_helper.GetCppType(type_),
            'src_var': src_var,
            'dst_var': dst_var,
            'failure_value': failure_value,
        }

        if underlying_type.property_type not in (PropertyType.ANY,
                                                 PropertyType.CHOICES):
            sub['value_type'] = cpp_util.GetValueType(underlying_type)

        return c.Eblock('}').Substitute(sub)