package queryutil

import (
	
	
	
	
	
	
	
	

	
)
Parse parses an object i and fills a url.Values object. The isEC2 flag indicates if this is the EC2 Query sub-protocol.
func ( url.Values,  interface{},  bool) error {
	 := queryParser{isEC2: }
	return .parseValue(, reflect.ValueOf(), "", "")
}

func ( reflect.Value) reflect.Value {
	for .Kind() == reflect.Ptr {
		 = .Elem()
	}
	return 
}

type queryParser struct {
	isEC2 bool
}

func ( *queryParser) ( url.Values,  reflect.Value,  string,  reflect.StructTag) error {
	 = elemOf()
no need to handle zero values
	if !.IsValid() {
		return nil
	}

	 := .Get("type")
	if  == "" {
		switch .Kind() {
		case reflect.Struct:
			 = "structure"
		case reflect.Slice:
			 = "list"
		case reflect.Map:
			 = "map"
		}
	}

	switch  {
	case "structure":
		return .parseStruct(, , )
	case "list":
		return .parseList(, , , )
	case "map":
		return .parseMap(, , , )
	default:
		return .parseScalar(, , , )
	}
}

func ( *queryParser) ( url.Values,  reflect.Value,  string) error {
	if !.IsValid() {
		return nil
	}

	 := .Type()
	for  := 0;  < .NumField(); ++ {
		 := elemOf(.Field())
		 := .Field()

		if .PkgPath != "" {
			continue // ignore unexported fields
		}
		if .Tag.Get("ignore") != "" {
			continue
		}

		if protocol.CanSetIdempotencyToken(.Field(), ) {
			 := protocol.GetIdempotencyToken()
			 = reflect.ValueOf()
		}

		var  string
		if .isEC2 {
			 = .Tag.Get("queryName")
		}
		if  == "" {
			if .Tag.Get("flattened") != "" && .Tag.Get("locationNameList") != "" {
				 = .Tag.Get("locationNameList")
			} else if  := .Tag.Get("locationName");  != "" {
				 = 
			}
			if  != "" && .isEC2 {
				 = strings.ToUpper([0:1]) + [1:]
			}
		}
		if  == "" {
			 = .Name
		}

		if  != "" {
			 =  + "." + 
		}

		if  := .parseValue(, , , .Tag);  != nil {
			return 
		}
	}
	return nil
}

If it's empty, generate an empty value
	if !.IsNil() && .Len() == 0 {
		.Set(, "")
		return nil
	}

	if ,  := .Interface().([]byte);  {
		return .parseScalar(, , , )
	}
check for unflattened list member
	if !.isEC2 && .Get("flattened") == "" {
		if  := .Get("locationNameList");  == "" {
			 += ".member"
		} else {
			 += "." + 
		}
	}

	for  := 0;  < .Len(); ++ {
		 := 
		if  == "" {
			 = strconv.Itoa( + 1)
		} else {
			 =  + "." + strconv.Itoa(+1)
		}
		if  := .parseValue(, .Index(), , "");  != nil {
			return 
		}
	}
	return nil
}

If it's empty, generate an empty value
	if !.IsNil() && .Len() == 0 {
		.Set(, "")
		return nil
	}
check for unflattened list member
	if !.isEC2 && .Get("flattened") == "" {
		 += ".entry"
	}
sort keys for improved serialization consistency. this is not strictly necessary for protocol support.
	 := .MapKeys()
	 := map[string]reflect.Value{}
	 := make([]string, len())
	for ,  := range  {
		 := .String()
		[] = 
		[] = 
	}
	sort.Strings()

	for ,  := range  {
		 := []
		 := .MapIndex()

		 := .Get("locationNameKey")
		if  == "" {
			 = "key"
		}
		 := .Get("locationNameValue")
		if  == "" {
			 = "value"
		}
serialize key
		var  string
		if  == "" {
			 = strconv.Itoa(+1) + "." + 
		} else {
			 =  + "." + strconv.Itoa(+1) + "." + 
		}

		if  := .parseValue(, , , "");  != nil {
			return 
		}
serialize value
		var  string
		if  == "" {
			 = strconv.Itoa(+1) + "." + 
		} else {
			 =  + "." + strconv.Itoa(+1) + "." + 
		}

		if  := .parseValue(, , , "");  != nil {
			return 
		}
	}

	return nil
}

func ( *queryParser) ( url.Values,  reflect.Value,  string,  reflect.StructTag) error {
	switch value := .Interface().(type) {
	case string:
		.Set(, )
	case []byte:
		if !.IsNil() {
			.Set(, base64.StdEncoding.EncodeToString())
		}
	case bool:
		.Set(, strconv.FormatBool())
	case int64:
		.Set(, strconv.FormatInt(, 10))
	case int:
		.Set(, strconv.Itoa())
	case float64:
		.Set(, strconv.FormatFloat(, 'f', -1, 64))
	case float32:
		.Set(, strconv.FormatFloat(float64(), 'f', -1, 32))
	case time.Time:
		const  = "2006-01-02T15:04:05Z"
		 := .Get("timestampFormat")
		if len() == 0 {
			 = protocol.ISO8601TimeFormatName
		}

		.Set(, protocol.FormatTime(, ))
	default:
		return fmt.Errorf("unsupported value for param %s: %v (%s)", , .Interface(), .Type().Name())
	}
	return nil