rostran/providers/cloudformation/template.py [267:364]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            final_name = prop_rule.get("To")
            prop_type = prop_rule.get("Type")
            prop_schema = prop_rule.get("Schema")

            if final_name is None and prop_type != "Map":
                raise InvalidRuleSchema(
                    path=rule_id,
                    reason=f"{name} is invalid. The Type should be 'Map' when To is None",
                )
            if prop_type == "List" and prop_schema:
                final_value = []
                for each in transformed_value:
                    val = self._transform_resource_props(
                        resource_type,
                        each,
                        prop_schema,
                        rule_id,
                    )
                    final_value.append(val)
            elif prop_type == "Map" and prop_schema:
                if isinstance(transformed_value, list):
                    transformed_value = transformed_value[0]
                final_value = self._transform_resource_props(
                    resource_type, transformed_value, prop_schema, rule_id
                )
            else:
                final_value = transformed_value

            handler_name = prop_rule.get("Handler")
            if handler_name is not None:
                handler_func = getattr(basic_handler_module, handler_name)
                final_value = handler_func(final_value, resolved)

            if final_value is not None:
                if final_name is None:
                    assert isinstance(final_value, dict)
                    final_props.update(final_value)
                else:
                    # If To is duplicated, merge it
                    if final_name in final_props:
                        merged_value = final_props[final_name]
                        merge_handler_name = prop_rule.get("MergeHandler")
                        if merge_handler_name is not None:
                            merge_handler_func = getattr(
                                merge_handler_module, merge_handler_name
                            )
                            final_value = merge_handler_func(
                                final_value, merged_value, resolved
                            )

                    # If To is a multi-level attribute, it needs to be converted level by level.
                    # For example, if To is RuleList.0.Url, it should be converted to
                    # final_props["RuleList"][0]["Url"] = value.
                    self._handle_props_and_value(
                        final_props, final_name.split("."), final_value, rule_id
                    )

        return final_props

    def _handle_props_and_value(self, data, names: list, value, rule_id, _name_path=""):
        if not names:
            return

        name = names[0]
        if name.isdigit():
            name = int(name)

        _name_path = f"{_name_path}.{name}" if _name_path else f"{name}"
        if len(names) == 1:
            if name == "__single_to_multi_handler__":
                if value:
                    data.update(value)
            else:
                try:
                    data[name] = value
                except IndexError:
                    if name != len(data):
                        raise InvalidRuleSchema(
                            path=rule_id,
                            reason=f"{_name_path} is invalid. The index should be {len(data)}",
                        )
                    data.append(value)
        else:
            default_sub_data = [] if names[1].isdigit() else {}
            try:
                sub_data = data[name]
            except KeyError:
                sub_data = data[name] = default_sub_data
            except IndexError:
                if name != len(data):
                    raise InvalidRuleSchema(
                        path=rule_id,
                        reason=f"{_name_path} is invalid. The index should be {len(data)}",
                    )
                data.append(default_sub_data)
                sub_data = default_sub_data

            self._handle_props_and_value(sub_data, names[1:], value, _name_path)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



rostran/providers/terraform/template.py [546:643]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            final_name = prop_rule.get("To")
            prop_type = prop_rule.get("Type")
            prop_schema = prop_rule.get("Schema")

            if final_name is None and prop_type != "Map":
                raise InvalidRuleSchema(
                    path=rule_id,
                    reason=f"{name} is invalid. The Type should be 'Map' when To is None",
                )
            if prop_type == "List" and prop_schema:
                final_value = []
                for each in transformed_value:
                    val = self._transform_resource_props(
                        resource_type,
                        each,
                        prop_schema,
                        rule_id,
                    )
                    final_value.append(val)
            elif prop_type == "Map" and prop_schema:
                if isinstance(transformed_value, list):
                    transformed_value = transformed_value[0]
                final_value = self._transform_resource_props(
                    resource_type, transformed_value, prop_schema, rule_id
                )
            else:
                final_value = transformed_value

            handler_name = prop_rule.get("Handler")
            if handler_name is not None:
                handler_func = getattr(basic_handler_module, handler_name)
                final_value = handler_func(final_value, resolved)

            if final_value is not None:
                if final_name is None:
                    assert isinstance(final_value, dict)
                    final_props.update(final_value)
                else:
                    # If To is duplicated, merge it
                    if final_name in final_props:
                        merged_value = final_props[final_name]
                        merge_handler_name = prop_rule.get("MergeHandler")
                        if merge_handler_name is not None:
                            merge_handler_func = getattr(
                                merge_handler_module, merge_handler_name
                            )
                            final_value = merge_handler_func(
                                final_value, merged_value, resolved
                            )

                    # If To is a multi-level attribute, it needs to be converted level by level.
                    # For example, if To is RuleList.0.Url, it should be converted to
                    # final_props["RuleList"][0]["Url"] = value.
                    self._handle_props_and_value(
                        final_props, final_name.split("."), final_value, rule_id
                    )

        return final_props

    def _handle_props_and_value(self, data, names: list, value, rule_id, _name_path=""):
        if not names:
            return

        name = names[0]
        if name.isdigit():
            name = int(name)

        _name_path = f"{_name_path}.{name}" if _name_path else f"{name}"
        if len(names) == 1:
            if name == "__single_to_multi_handler__":
                if value:
                    data.update(value)
            else:
                try:
                    data[name] = value
                except IndexError:
                    if name != len(data):
                        raise InvalidRuleSchema(
                            path=rule_id,
                            reason=f"{_name_path} is invalid. The index should be {len(data)}",
                        )
                    data.append(value)
        else:
            default_sub_data = [] if names[1].isdigit() else {}
            try:
                sub_data = data[name]
            except KeyError:
                sub_data = data[name] = default_sub_data
            except IndexError:
                if name != len(data):
                    raise InvalidRuleSchema(
                        path=rule_id,
                        reason=f"{_name_path} is invalid. The index should be {len(data)}",
                    )
                data.append(default_sub_data)
                sub_data = default_sub_data

            self._handle_props_and_value(sub_data, names[1:], value, _name_path)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



