Пример #1
0
    def _GenerateFundamentalOrFundamentalRefPopulate(self, c, prop, value_var,
                                                     dst):
        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;'))
            if prop.type_ != prop.compiled_type:
                (c.Append('%(compiled_ctype)s temp2;').Append(
                    'if (!%s)' % cpp_util.GenerateTypeToCompiledTypeConversion(
                        self._cpp_type_generator.GetReferencedProperty(prop),
                        'temp', 'temp2')
                ).Append('  return %(failure_value)s;').Append(
                    '%(dst)s->%(name)s.reset(new %(compiled_ctype)s(temp2));'))
            else:
                c.Append('%(dst)s->%(name)s.reset(new %(ctype)s(temp));')

        else:
            if prop.type_ == prop.compiled_type:
                assignment_target = '&%s->%s' % (dst, prop.unix_name)
            else:
                c.Append('%(ctype)s temp;')
                assignment_target = '&temp'
            (c.Append('if (!%s)' % cpp_util.GetAsFundamentalValue(
                self._cpp_type_generator.GetReferencedProperty(prop),
                value_var,
                assignment_target)).Append('  return %(failure_value)s;'))
            if prop.type_ != prop.compiled_type:
                (c.Append(
                    'if (!%s)' % cpp_util.GenerateTypeToCompiledTypeConversion(
                        self._cpp_type_generator.GetReferencedProperty(prop),
                        'temp', '%s->%s' % (dst, prop.unix_name))).Append(
                            '  return %(failure_value)s;'))
Пример #2
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()

    underlying_type = self._type_helper.FollowRef(type_)

    if underlying_type.property_type.is_fundamental:
      if is_ptr:
        (c.Append('%(cpp_type)s temp;')
          .Sblock('if (!%s) {' % cpp_util.GetAsFundamentalValue(
                      self._type_helper.FollowRef(type_), src_var, '&temp'))
          .Concat(self._GenerateError(
            '"\'%%(key)s\': expected ' + '%s, got " + %s' % (
                type_.name,
                self._util_cc_helper.GetValueTypeString(
                    '%%(src_var)s', True)))))
        c.Append('%(dst_var)s.reset();')
        if not self._generate_error_messages:
          c.Append('return %(failure_value)s;')
        (c.Eblock('}')
          .Append('else')
          .Append('  %(dst_var)s.reset(new %(cpp_type)s(temp));')
        )
      else:
        (c.Sblock('if (!%s) {' % cpp_util.GetAsFundamentalValue(
                      self._type_helper.FollowRef(type_),
                      src_var,
                      '&%s' % dst_var))
          .Concat(self._GenerateError(
            '"\'%%(key)s\': expected ' + '%s, got " + %s' % (
                type_.name,
                self._util_cc_helper.GetValueTypeString(
                    '%%(src_var)s', True))))
          .Append('return %(failure_value)s;')
          .Eblock('}')
        )
    elif underlying_type.property_type == PropertyType.OBJECT:
      if is_ptr:
        (c.Append('const base::DictionaryValue* dictionary = NULL;')
          .Sblock('if (!%(src_var)s->GetAsDictionary(&dictionary)) {')
          .Concat(self._GenerateError(
            '"\'%%(key)s\': expected dictionary, got " + ' +
            self._util_cc_helper.GetValueTypeString('%%(src_var)s', True))))
        # If an optional property fails to populate, the population can still
        # succeed with a warning. If no error messages are generated, this
        # warning is not set and we fail out instead.
        if not self._generate_error_messages:
          c.Append('return %(failure_value)s;')
        (c.Eblock('}')
          .Sblock('else {')
          .Append('scoped_ptr<%(cpp_type)s> temp(new %(cpp_type)s());')
          .Append('if (!%%(cpp_type)s::Populate(%s)) {' % self._GenerateArgs(
            ('*dictionary', 'temp.get()')))
          .Append('  return %(failure_value)s;')
        )
        (c.Append('}')
          .Append('else')
          .Append('  %(dst_var)s = temp.Pass();')
          .Eblock('}')
        )
      else:
        (c.Append('const base::DictionaryValue* dictionary = NULL;')
          .Sblock('if (!%(src_var)s->GetAsDictionary(&dictionary)) {')
          .Concat(self._GenerateError(
            '"\'%%(key)s\': expected dictionary, got " + ' +
            self._util_cc_helper.GetValueTypeString('%%(src_var)s', True)))
          .Append('return %(failure_value)s;')
          .Eblock('}')
          .Append('if (!%%(cpp_type)s::Populate(%s)) {' % self._GenerateArgs(
            ('*dictionary', '&%(dst_var)s')))
          .Append('  return %(failure_value)s;')
          .Append('}')
        )
    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;')
        .Sblock('if (!%(src_var)s->GetAsList(&list)) {')
          .Concat(self._GenerateError(
            '"\'%%(key)s\': expected list, got " + ' +
            self._util_cc_helper.GetValueTypeString('%%(src_var)s', True)))
      )
      if is_ptr and self._generate_error_messages:
        c.Append('%(dst_var)s.reset();')
      else:
        c.Append('return %(failure_value)s;')
      c.Eblock('}')
      c.Sblock('else {')
      item_type = self._type_helper.FollowRef(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.Sblock('if (!%s(%s)) {' % (
            self._util_cc_helper.PopulateArrayFromListFunction(is_ptr),
            self._GenerateArgs(('*list', '&%(dst_var)s'))))
        c.Concat(self._GenerateError(
            '"unable to populate array \'%%(parent_key)s\'"'))
        if is_ptr and self._generate_error_messages:
          c.Append('%(dst_var)s.reset();')
        else:
          c.Append('return %(failure_value)s;')
        c.Eblock('}')
      c.Eblock('}')
    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(%s))' % self._GenerateArgs(
            ('*%(src_var)s', 'temp.get()')))
          .Append('  return %(failure_value)s;')
          .Append('%(dst_var)s = temp.Pass();')
        )
      else:
        (c.Append('if (!%%(cpp_type)s::Populate(%s))' % self._GenerateArgs(
            ('*%(src_var)s', '&%(dst_var)s')))
          .Append('  return %(failure_value)s;'))
    elif underlying_type.property_type == PropertyType.ENUM:
      c.Concat(self._GenerateStringToEnumConversion(underlying_type,
                                                    src_var,
                                                    dst_var,
                                                    failure_value))
    elif underlying_type.property_type == PropertyType.BINARY:
      (c.Append('const base::BinaryValue* binary_value = NULL;')
        .Sblock('if (!%(src_var)s->IsType(base::Value::TYPE_BINARY)) {')
        .Concat(self._GenerateError(
          '"\'%%(key)s\': expected binary, got " + ' +
          self._util_cc_helper.GetValueTypeString('%%(src_var)s', True)))
      )
      if not self._generate_error_messages:
        c.Append('return %(failure_value)s;')
      (c.Eblock('}')
        .Sblock('else {')
        .Append(' binary_value =')
        .Append('   static_cast<const base::BinaryValue*>(%(src_var)s);')
      )
      if is_ptr:
        (c.Append('%(dst_var)s.reset(new std::vector<char>(')
          .Append('    binary_value->GetBuffer(),')
          .Append('    binary_value->GetBuffer() + binary_value->GetSize()));')
        )
      else:
        (c.Append('%(dst_var)s.assign(')
          .Append('    binary_value->GetBuffer(),')
          .Append('    binary_value->GetBuffer() + binary_value->GetSize());')
        )
      c.Eblock('}')
    else:
      raise NotImplementedError(type_)
    if c.IsEmpty():
      return c
    return Code().Sblock('{').Concat(c.Substitute({
      'cpp_type': self._type_helper.GetCppType(type_),
      'src_var': src_var,
      'dst_var': dst_var,
      'failure_value': failure_value,
      'key': type_.name,
      'parent_key': type_.parent.name,
    })).Eblock('}')
Пример #3
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
Пример #4
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)