<commit_before>package schema

import (
	"fmt"
	"strconv"
	"strings"
	"sync"

	"github.com/hashicorp/terraform/terraform"
	"github.com/mitchellh/mapstructure"
)

// ConfigFieldReader reads fields out of an untyped map[string]string to the
// best of its ability. It also applies defaults from the Schema. (The other
// field readers do not need default handling because they source fully
// populated data structures.)
type ConfigFieldReader struct {
	Config *terraform.ResourceConfig
	Schema map[string]*Schema

	indexMaps map[string]map[string]int
	once      sync.Once
}

func (r *ConfigFieldReader) ReadField(address []string) (FieldReadResult, error) {
	r.once.Do(func() { r.indexMaps = make(map[string]map[string]int) })
	return r.readField(address, false)
}

func (r *ConfigFieldReader) readField(
	address []string, nested bool) (FieldReadResult, error) {
	schemaList := addrToSchema(address, r.Schema)
	if len(schemaList) == 0 {
		return FieldReadResult{}, nil
	}

	if !nested {
		// If we have a set anywhere in the address, then we need to
		// read that set out in order and actually replace that part of
		// the address with the real list index. i.e. set.50 might actually
		// map to set.12 in the config, since it is in list order in the
		// config, not indexed by set value.
		for i, v := range schemaList {
			// Sets are the only thing that cause this issue.
			if v.Type != TypeSet {
				continue
			}

			// If we're at the end of the list, then we don't have to worry
			// about this because we're just requesting the whole set.
			if i == len(schemaList)-1 {
				continue
			}

			// If we're looking for the count, then ignore...
			if address[i+1] == "#" {
				continue
			}

			indexMap, ok := r.indexMaps[strings.Join(address[:i+1], ".")]
			if !ok {
				// Get the set so we can get the index map that tells us the
				// mapping of the hash code to the list index
				_, err := r.readSet(address[:i+1], v)
				if err != nil {
					return FieldReadResult{}, err
				}
				indexMap = r.indexMaps[strings.Join(address[:i+1], ".")]
			}

			index, ok := indexMap[address[i+1]]
			if !ok {
				return FieldReadResult{}, nil
			}

			address[i+1] = strconv.FormatInt(int64(index), 10)
		}
	}

	k := strings.Join(address, ".")
	schema := schemaList[len(schemaList)-1]

	// If we're getting the single element of a promoted list, then
	// check to see if we have a single element we need to promote.
	if address[len(address)-1] == "0" && len(schemaList) > 1 {
		lastSchema := schemaList[len(schemaList)-2]
		if lastSchema.Type == TypeList && lastSchema.PromoteSingle {
			k := strings.Join(address[:len(address)-1], ".")
			result, err := r.readPrimitive(k, schema)
			if err == nil {
				return result, nil
			}
		}
	}

	switch schema.Type {
	case TypeBool, TypeFloat, TypeInt, TypeString:
		return r.readPrimitive(k, schema)
	case TypeList:
		// If we support promotion then we first check if we have a lone
		// value that we must promote.
		// a value that is alone.
		if schema.PromoteSingle {
			result, err := r.readPrimitive(k, schema.Elem.(*Schema))
			if err == nil && result.Exists {
				result.Value = []interface{}{result.Value}
				return result, nil
			}
		}

		return readListField(&nestedConfigFieldReader{r}, address, schema)
	case TypeMap:<commit_msg>check for computed values in the config<commit_after>package schema

import (
	"fmt"
	"strconv"
	"strings"
	"sync"

	"github.com/hashicorp/terraform/terraform"
	"github.com/mitchellh/mapstructure"
)

// ConfigFieldReader reads fields out of an untyped map[string]string to the
// best of its ability. It also applies defaults from the Schema. (The other
// field readers do not need default handling because they source fully
// populated data structures.)
type ConfigFieldReader struct {
	Config *terraform.ResourceConfig
	Schema map[string]*Schema

	indexMaps map[string]map[string]int
	once      sync.Once
}

func (r *ConfigFieldReader) ReadField(address []string) (FieldReadResult, error) {
	r.once.Do(func() { r.indexMaps = make(map[string]map[string]int) })
	return r.readField(address, false)
}

func (r *ConfigFieldReader) readField(
	address []string, nested bool) (FieldReadResult, error) {
	schemaList := addrToSchema(address, r.Schema)
	if len(schemaList) == 0 {
		return FieldReadResult{}, nil
	}

	if !nested {
		// If we have a set anywhere in the address, then we need to
		// read that set out in order and actually replace that part of
		// the address with the real list index. i.e. set.50 might actually
		// map to set.12 in the config, since it is in list order in the
		// config, not indexed by set value.
		for i, v := range schemaList {
			// Sets are the only thing that cause this issue.
			if v.Type != TypeSet {
				continue
			}

			// If we're at the end of the list, then we don't have to worry
			// about this because we're just requesting the whole set.
			if i == len(schemaList)-1 {
				continue
			}

			// If we're looking for the count, then ignore...
			if address[i+1] == "#" {
				continue
			}

			indexMap, ok := r.indexMaps[strings.Join(address[:i+1], ".")]
			if !ok {
				// Get the set so we can get the index map that tells us the
				// mapping of the hash code to the list index
				_, err := r.readSet(address[:i+1], v)
				if err != nil {
					return FieldReadResult{}, err
				}
				indexMap = r.indexMaps[strings.Join(address[:i+1], ".")]
			}

			index, ok := indexMap[address[i+1]]
			if !ok {
				return FieldReadResult{}, nil
			}

			address[i+1] = strconv.FormatInt(int64(index), 10)
		}
	}

	k := strings.Join(address, ".")
	schema := schemaList[len(schemaList)-1]

	// If we're getting the single element of a promoted list, then
	// check to see if we have a single element we need to promote.
	if address[len(address)-1] == "0" && len(schemaList) > 1 {
		lastSchema := schemaList[len(schemaList)-2]
		if lastSchema.Type == TypeList && lastSchema.PromoteSingle {
			k := strings.Join(address[:len(address)-1], ".")
			result, err := r.readPrimitive(k, schema)
			if err == nil {
				return result, nil
			}
		}
	}

	if protoVersion5 {
		// Check if the value itself is unknown.
		// The new protocol shims will add unknown values to this list of
		// ComputedKeys. THis is the only way we have to indicate that a
		// collection is unknown in the config
		for _, unknown := range r.Config.ComputedKeys {
			if k == unknown {
				return FieldReadResult{Computed: true, Exists: true}, nil
			}
		}
	}

	switch schema.Type {
	case TypeBool, TypeFloat, TypeInt, TypeString:
		return r.readPrimitive(k, schema)
	case TypeList:
		// If we support promotion then we first check if we have a lone
		// value that we must promote.
		// a value that is alone.
		if schema.PromoteSingle {
			result, err := r.readPrimitive(k, schema.Elem.(*Schema))
			if err == nil && result.Exists {
				result.Value = []interface{}{result.Value}
				return result, nil
			}
		}

		return readListField(&nestedConfigFieldReader{r}, address, schema)
	case TypeMap:
{'fraction_non_alphanumeric': 0.11822730521801286, 'fraction_numerical': 0.006433166547533953, 'mean_word_length': 3.263254113345521, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1541296', 'n_tokens_mistral': 2488, 'n_tokens_neox': 2207, 'n_words': 777}