func (ctx *Context) decodeSlice(data []byte, value reflect.Value) error {
	slice := reflect.New(value.Type()).Elem()
	var err error
	for len(data) > 0 {
		elem := reflect.New(value.Type().Elem()).Elem()
		data, err = ctx.DecodeWithOptions(data, elem.Addr().Interface(), "")
		if err != nil {
			return err
		}
		slice.Set(reflect.Append(slice, elem))
	}
	value.Set(slice)
	return nil
}
decodeSlice decodes a SET(OF) as a slice
package asn1
import (
	"bytes"
	"io"
	"reflect"
	"sort"
)
type expectedElement struct {
	class   uint
	tag     uint
	decoder decoderFunction
}
type expectedFieldElement struct {
	expectedElement
	value reflect.Value
	opts  *fieldOptions
}
func (ctx *Context) Decode(data []byte, obj interface{}) (rest []byte, err error) {
	return ctx.DecodeWithOptions(data, obj, "")
}
func (ctx *Context) DecodeWithOptions(data []byte, obj interface{}, options string) (rest []byte, err error) {
	opts, err := parseOptions(options)
	if err != nil {
		return nil, err
	}
	value := reflect.ValueOf(obj)
	switch value.Kind() {
	case reflect.Ptr, reflect.Interface:
		value = value.Elem()
	}
	if !value.CanSet() {
		return nil, syntaxError("go type '%s' is read-only", value.Type())
	}
	reader := bytes.NewBuffer(data)
	err = ctx.decode(reader, value, opts)
	if err != nil {
		return nil, err
	}
	return reader.Bytes(), nil
}
func (ctx *Context) decode(reader io.Reader, value reflect.Value, opts *fieldOptions) error {
	raw, err := decodeRawValue(reader)
	if err != nil {
		return err
	}
	if ctx.der.decoding && raw.Indefinite {
		return parseError("indefinite length form is not supported by DER mode")
	}
	elem, err := ctx.getExpectedElement(raw, value.Type(), opts)
	if err != nil {
		return err
	}
	if raw.Class != elem.class || raw.Tag != elem.tag {
		ctx.log.Printf("%#v\n", opts)
		return parseError("expected tag (%d,%d) but found (%d,%d)",
			elem.class, elem.tag, raw.Class, raw.Tag)
	}
	return elem.decoder(raw.Content, value)
}
func (ctx *Context) getExpectedElement(raw *rawValue, elemType reflect.Type, opts *fieldOptions) (elem expectedElement, err error) {
	elem, err = ctx.getUniversalTag(elemType, opts)
	if err != nil {
		return
	}
	if opts.tag != nil {
		elem.class = classContextSpecific
		elem.tag = uint(*opts.tag)
	}
	if opts.universal {
		elem.class = classUniversal
	}
	if opts.application {
		elem.class = classApplication
	}
	if opts.explicit {
		elem.decoder = func(data []byte, value reflect.Value) error {
			opts.explicit = false
			opts.tag = nil
			opts.application = false
			reader := bytes.NewBuffer(data)
			return ctx.decode(reader, value, opts)
		}
		return
	}
	if opts.choice != nil {
		var entry choiceEntry
		entry, err = ctx.getChoiceByTag(*opts.choice, raw.Class, raw.Tag)
		if err != nil {
			return
		}
		elem.class, elem.tag = raw.Class, raw.Tag
		elem.decoder = func(data []byte, value reflect.Value) error {
			nestedValue := reflect.New(entry.typ).Elem()
			err = entry.decoder(data, nestedValue)
			if err != nil {
				return err
			}
			value.Set(nestedValue)
			return nil
		}
	}
	if elem.decoder == nil {
		err = parseError("go type not supported '%s'", elemType)
	}
	return
}
func (ctx *Context) getUniversalTag(objType reflect.Type, opts *fieldOptions) (elem expectedElement, err error) {
	elem.class = classUniversal
	switch objType {
	case bigIntType:
		elem.tag = tagInteger
		elem.decoder = ctx.decodeBigInt
	case oidType:
		elem.tag = tagOid
		elem.decoder = ctx.decodeOid
	case nullType:
		elem.tag = tagNull
		elem.decoder = ctx.decodeNull
	default:
		elem = ctx.getUniversalTagByKind(objType, opts)
	}
	if opts.set {
		if elem.tag != tagSequence {
			err = syntaxError(
				"'set' cannot be used with Go type '%s'", objType)
		}
		elem.tag = tagSet
	}
	return
}
func (ctx *Context) getUniversalTagByKind(objType reflect.Type, opts *fieldOptions) (elem expectedElement) {
	switch objType.Kind() {
	case reflect.Bool:
		elem.tag = tagBoolean
		elem.decoder = ctx.decodeBool
	case reflect.String:
		elem.tag = tagOctetString
		elem.decoder = ctx.decodeString
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		elem.tag = tagInteger
		elem.decoder = ctx.decodeInt
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		elem.tag = tagInteger
		elem.decoder = ctx.decodeUint
	case reflect.Struct:
		elem.tag = tagSequence
		elem.decoder = ctx.decodeStruct
		if opts.set {
			elem.decoder = ctx.decodeStructAsSet
		}
	case reflect.Array:
		if objType.Elem().Kind() == reflect.Uint8 {
			elem.tag = tagOctetString
			elem.decoder = ctx.decodeOctetString
		} else {
			elem.tag = tagSequence
			elem.decoder = ctx.decodeArray
		}
	case reflect.Slice:
		if objType.Elem().Kind() == reflect.Uint8 {
			elem.tag = tagOctetString
			elem.decoder = ctx.decodeOctetString
		} else {
			elem.tag = tagSequence
			elem.decoder = ctx.decodeSlice
		}
	}
	return
}
func (ctx *Context) getExpectedFieldElements(value reflect.Value) ([]expectedFieldElement, error) {
	expectedValues := []expectedFieldElement{}
	for i := 0; i < value.NumField(); i++ {
		if value.CanSet() {
			field := value.Field(i)
			opts, err := parseOptions(value.Type().Field(i).Tag.Get(tagKey))
			if err != nil {
				return nil, err
			}
			raw := &rawValue{}
			if opts.choice == nil {
				elem, err := ctx.getExpectedElement(raw, field.Type(), opts)
				if err != nil {
					return nil, err
				}
				expectedValues = append(expectedValues,
					expectedFieldElement{elem, field, opts})
			} else {
				entries, err := ctx.getChoices(*opts.choice)
				if err != nil {
					return nil, err
				}
				for _, entry := range entries {
					raw.Class = entry.class
					raw.Tag = entry.tag
					elem, err := ctx.getExpectedElement(raw, field.Type(), opts)
					if err != nil {
						return nil, err
					}
					expectedValues = append(expectedValues,
						expectedFieldElement{elem, field, opts})
				}
			}
		}
	}
	return expectedValues, nil
}
func (ctx *Context) getRawValuesFromBytes(data []byte, max int) ([]*rawValue, error) {
	rawValues := []*rawValue{}
	reader := bytes.NewBuffer(data)
	for i := 0; i < max; i++ {
		raw, err := decodeRawValue(reader)
		if err != nil {
			return nil, err
		}
		rawValues = append(rawValues, raw)
		if reader.Len() == 0 {
			return rawValues, nil
		}
	}
	return nil, parseError("too many items for Sequence")
}
func (ctx *Context) matchExpectedValues(eValues []expectedFieldElement, rValues []*rawValue) error {
	rIndex := 0
	for eIndex := 0; eIndex < len(eValues); eIndex++ {
		e := eValues[eIndex]
		if e.decoder == nil {
			continue
		}
		missing := true
		if rIndex < len(rValues) {
			raw := rValues[rIndex]
			if e.class == raw.Class && e.tag == raw.Tag {
				err := e.decoder(raw.Content, e.value)
				if err != nil {
					return err
				}
				missing = false
				rIndex++
				if e.opts.choice != nil {
					for i := eIndex + 1; i < len(eValues); i++ {
						c := eValues[i].opts.choice
						if c != nil && *c == *e.opts.choice {
							eValues[i].decoder = nil
						}
					}
				}
			}
		}
		if missing {
			if err := ctx.setMissingFieldValue(e); err != nil {
				return err
			}
		}
	}
	return nil
}
func (ctx *Context) setMissingFieldValue(e expectedFieldElement) error {
	if e.opts.optional || e.opts.choice != nil {
		return nil
	}
	if e.opts.defaultValue != nil {
		err := ctx.setDefaultValue(e.value, e.opts)
		if err != nil {
			return err
		}
		return nil
	}
	return parseError("missing value for [%d %d]", e.class, e.tag)
}
func (ctx *Context) decodeStruct(data []byte, value reflect.Value) error {
	expectedValues, err := ctx.getExpectedFieldElements(value)
	if err != nil {
		return err
	}
	rawValues, err := ctx.getRawValuesFromBytes(data, len(expectedValues))
	if err != nil {
		return err
	}
	return ctx.matchExpectedValues(expectedValues, rawValues)
}
func (ctx *Context) decodeStructAsSet(data []byte, value reflect.Value) error {
	expectedElements, err := ctx.getExpectedFieldElements(value)
	if err != nil {
		return err
	}
	sort.Sort(expectedFieldElementSlice(expectedElements))
	for i := 1; i < len(expectedElements); i++ {
		curr := expectedElements[i]
		prev := expectedElements[i-1]
		if curr.class == prev.class &&
			curr.tag == prev.tag {
			return syntaxError("duplicated tag (%d,%d)", curr.class, curr.tag)
		}
	}
	rawValues, err := ctx.getRawValuesFromBytes(data, len(expectedElements))
	if err != nil {
		return err
	}
	if !ctx.der.decoding {
		sort.Sort(rawValueSlice(rawValues))
	}
	return ctx.matchExpectedValues(expectedElements, rawValues)
}