def _parse_children()

in functions/source/KeyGen/asn1crypto/core.py [0:0]


    def _parse_children(self, recurse=False):
        """
        Parses the contents and generates Asn1Value objects based on the
        definitions from _fields.

        :param recurse:
            If child objects that are Sequence or SequenceOf objects should
            be recursively parsed

        :raises:
            ValueError - when an error occurs parsing child objects
        """

        cls = self.__class__
        if self._contents is None:
            if self._fields:
                self.children = [VOID] * len(self._fields)
                for index, (_, _, params) in enumerate(self._fields):
                    if 'default' in params:
                        if cls._precomputed_specs[index]:
                            field_name, field_spec, value_spec, field_params, _ = cls._precomputed_specs[index]
                        else:
                            field_name, field_spec, value_spec, field_params, _ = self._determine_spec(index)
                        self.children[index] = self._make_value(field_name, field_spec, value_spec, field_params, None)
            return

        try:
            child_map = {}
            contents_length = len(self.contents)
            child_pointer = 0
            seen_field = 0
            while child_pointer < contents_length:
                parts, child_pointer = _parse(self.contents, contents_length, pointer=child_pointer)

                id_ = (parts[0], parts[2])

                field = self._field_ids.get(id_)
                if field is None:
                    raise ValueError(unwrap(
                        '''
                        Data for field %s (%s class, %s method, tag %s) does
                        not match any of the field definitions
                        ''',
                        seen_field,
                        CLASS_NUM_TO_NAME_MAP.get(parts[0]),
                        METHOD_NUM_TO_NAME_MAP.get(parts[1]),
                        parts[2],
                    ))

                _, field_spec, value_spec, field_params, spec_override = (
                    cls._precomputed_specs[field] or self._determine_spec(field))

                if field_spec is None or (spec_override and issubclass(field_spec, Any)):
                    field_spec = value_spec
                    spec_override = None

                if spec_override:
                    child = parts + (field_spec, field_params, value_spec)
                else:
                    child = parts + (field_spec, field_params)

                if recurse:
                    child = _build(*child)
                    if isinstance(child, (Sequence, SequenceOf)):
                        child._parse_children(recurse=True)

                child_map[field] = child
                seen_field += 1

            total_fields = len(self._fields)

            for index in range(0, total_fields):
                if index in child_map:
                    continue

                name, field_spec, value_spec, field_params, spec_override = (
                    cls._precomputed_specs[index] or self._determine_spec(index))

                if field_spec is None or (spec_override and issubclass(field_spec, Any)):
                    field_spec = value_spec
                    spec_override = None

                missing = False

                if not field_params:
                    missing = True
                elif 'optional' not in field_params and 'default' not in field_params:
                    missing = True
                elif 'optional' in field_params:
                    child_map[index] = VOID
                elif 'default' in field_params:
                    child_map[index] = field_spec(**field_params)

                if missing:
                    raise ValueError(unwrap(
                        '''
                        Missing required field "%s" from %s
                        ''',
                        name,
                        type_name(self)
                    ))

            self.children = []
            for index in range(0, total_fields):
                self.children.append(child_map[index])

        except (ValueError, TypeError) as e:
            args = e.args[1:]
            e.args = (e.args[0] + '\n    while parsing %s' % type_name(self),) + args
            raise e