github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/store/marshal/decode.go (about)

     1  // Copyright 2019 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  // This file incorporates work covered by the following copyright and
    16  // permission notice:
    17  //
    18  // Copyright 2016 Attic Labs, Inc. All rights reserved.
    19  // Licensed under the Apache License, version 2.0:
    20  // http://www.apache.org/licenses/LICENSE-2.0
    21  
    22  package marshal
    23  
    24  import (
    25  	"context"
    26  	"fmt"
    27  	"reflect"
    28  	"sync"
    29  
    30  	"github.com/dolthub/dolt/go/store/types"
    31  )
    32  
    33  // Unmarshal converts a Noms value into a Go value. It decodes v and stores the
    34  // result in the value pointed to by out.
    35  //
    36  // Unmarshal uses the inverse of the encodings that Marshal uses with the
    37  // following additional rules:
    38  //
    39  // To unmarshal a Noms struct into a Go struct, Unmarshal matches incoming
    40  // object fields to the fields used by Marshal (either the struct field name or
    41  // its tag).  Unmarshal will only set exported fields of the struct.  The name
    42  // of the Go struct must match (ignoring case) the name of the Noms struct. All
    43  // exported fields on the Go struct must be present in the Noms struct, unless
    44  // the field on the Go struct is marked with the "omitempty" tag. Go struct
    45  // fields also support the "original" tag which causes the Go field to receive
    46  // the entire original unmarshaled Noms struct.
    47  //
    48  // To unmarshal a Noms list or set into a slice, Unmarshal resets the slice
    49  // length to zero and then appends each element to the slice. If the Go slice
    50  // was nil a new slice is created when an element is added.
    51  //
    52  // To unmarshal a Noms list into a Go array, Unmarshal decodes Noms list
    53  // elements into corresponding Go array elements.
    54  //
    55  // To unmarshal a Noms map into a Go map, Unmarshal decodes Noms key and values
    56  // into corresponding Go array elements. If the Go map was nil a new map is
    57  // created if any value is set.
    58  //
    59  // To unmarshal a Noms set into a Go map, the field must be tagged with `noms:",set"`,
    60  // and it must have a type of map[<value-type>]struct{}. Unmarshal decodes into
    61  // Go map keys corresponding to the set values and assigns each key a value of struct{}{}.
    62  //
    63  // When unmarshalling onto interface{} the following rules are used:
    64  //  - types.Bool -> bool
    65  //  - types.List -> []T, where T is determined recursively using the same rules.
    66  //  - types.Set -> depends on `noms:",set"` annotation and field type:
    67  //    - without the annotation, same as types.List
    68  //    - with the annotation, same as types.Map for map[T]struct{} fields and same as types.List for slice fields
    69  //  - types.Map -> map[T]V, where T and V is determined recursively using the
    70  //    same rules.
    71  //  - types.Float -> float64
    72  //  - types.String -> string
    73  //  - *types.Type -> *types.Type
    74  //  - types.Union -> interface
    75  //  - Everything else an error
    76  //
    77  // Unmarshal returns an UnmarshalTypeMismatchError if:
    78  //  - a Noms value is not appropriate for a given target type
    79  //  - a Noms number overflows the target type
    80  //  - a Noms list is decoded into a Go array of a different length
    81  func Unmarshal(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, out interface{}) (err error) {
    82  	return UnmarshalOpt(ctx, nbf, v, Opt{}, out)
    83  }
    84  
    85  // UnmarshalOpt is like Unmarshal but provides additional options.
    86  func UnmarshalOpt(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, opt Opt, out interface{}) (err error) {
    87  	rv := reflect.ValueOf(out)
    88  	if rv.Kind() != reflect.Ptr || rv.IsNil() {
    89  		return &InvalidUnmarshalError{reflect.TypeOf(out)}
    90  	}
    91  	rv = rv.Elem()
    92  	nt := nomsTags{
    93  		set: opt.Set,
    94  	}
    95  	d, err := typeDecoder(rv.Type(), nt)
    96  
    97  	if err != nil {
    98  		return err
    99  	}
   100  
   101  	err = d(ctx, nbf, v, rv)
   102  
   103  	if err != nil {
   104  		return err
   105  	}
   106  
   107  	return err
   108  }
   109  
   110  // Unmarshaler is an interface types can implement to provide their own
   111  // decoding.
   112  //
   113  // You probably want to implement this on a pointer to a type, otherwise
   114  // calling UnmarshalNoms will effectively do nothing. For example, to unmarshal
   115  // a MyType you would define:
   116  //
   117  //  func (t *MyType) UnmarshalNoms(v types.Value) error {}
   118  type Unmarshaler interface {
   119  	// UnmarshalNoms decodes v, or returns an error.
   120  	UnmarshalNoms(ctx context.Context, nbf *types.NomsBinFormat, v types.Value) error
   121  }
   122  
   123  var unmarshalerInterface = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
   124  
   125  // InvalidUnmarshalError describes an invalid argument passed to Unmarshal. (The
   126  // argument to Unmarshal must be a non-nil pointer.)
   127  type InvalidUnmarshalError struct {
   128  	Type reflect.Type
   129  }
   130  
   131  func (e *InvalidUnmarshalError) Error() string {
   132  	if e.Type == nil {
   133  		return "Cannot unmarshal into Go nil value"
   134  	}
   135  
   136  	if e.Type.Kind() != reflect.Ptr {
   137  		return "Cannot unmarshal into Go non pointer of type " + e.Type.String()
   138  	}
   139  	return "Cannot unmarshal into Go nil pointer of type " + e.Type.String()
   140  }
   141  
   142  // UnmarshalTypeMismatchError describes a Noms value that was not appropriate
   143  // for a value of a specific Go type.
   144  type UnmarshalTypeMismatchError struct {
   145  	Value   types.Value
   146  	Type    reflect.Type // type of Go value it could not be assigned to
   147  	details string
   148  	nbf     *types.NomsBinFormat
   149  }
   150  
   151  func (e *UnmarshalTypeMismatchError) Error() string {
   152  	var tStr string
   153  	if e.Type != nil {
   154  		tStr = "to: " + e.Type.String()
   155  	}
   156  
   157  	valType, err := types.TypeOf(e.Value)
   158  
   159  	var valTStr string
   160  	if err == nil {
   161  		valTStr, err = valType.Describe(context.Background())
   162  
   163  		if err == nil {
   164  			valTStr = "from: " + valTStr
   165  		}
   166  	}
   167  
   168  	return fmt.Sprintf("Cannot unmarshal %s %s details: %s", valTStr, tStr, e.details)
   169  }
   170  
   171  func overflowError(nbf *types.NomsBinFormat, v types.Float, t reflect.Type) *UnmarshalTypeMismatchError {
   172  	return &UnmarshalTypeMismatchError{v, t, fmt.Sprintf("(%g does not fit in %s)", v, t), nbf}
   173  }
   174  
   175  type decoderFunc func(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, rv reflect.Value) error
   176  
   177  func typeDecoder(t reflect.Type, tags nomsTags) (decoderFunc, error) {
   178  	if reflect.PtrTo(t).Implements(unmarshalerInterface) {
   179  		return marshalerDecoder(t), nil
   180  	}
   181  
   182  	switch t.Kind() {
   183  	case reflect.Bool:
   184  		return boolDecoder, nil
   185  	case reflect.Float32, reflect.Float64:
   186  		return floatDecoder, nil
   187  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   188  		return intDecoder, nil
   189  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   190  		return uintDecoder, nil
   191  	case reflect.String:
   192  		return stringDecoder, nil
   193  	case reflect.Struct:
   194  		return structDecoder(t)
   195  	case reflect.Interface:
   196  		return interfaceDecoder(t)
   197  	case reflect.Slice:
   198  		return sliceDecoder(t)
   199  	case reflect.Array:
   200  		return arrayDecoder(t)
   201  	case reflect.Map:
   202  		if shouldMapDecodeFromSet(t, tags) {
   203  			return mapFromSetDecoder(t)
   204  		}
   205  		return mapDecoder(t, tags)
   206  	case reflect.Ptr:
   207  		// Allow implementations of types.Value (like *types.Type)
   208  		if t.Implements(nomsValueInterface) {
   209  			return nomsValueDecoder, nil
   210  		}
   211  		fallthrough
   212  	default:
   213  		return nil, &UnsupportedTypeError{Type: t}
   214  	}
   215  }
   216  
   217  func boolDecoder(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, rv reflect.Value) error {
   218  	if b, ok := v.(types.Bool); ok {
   219  		rv.SetBool(bool(b))
   220  	} else {
   221  		return &UnmarshalTypeMismatchError{v, rv.Type(), "", nbf}
   222  	}
   223  
   224  	return nil
   225  }
   226  
   227  func stringDecoder(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, rv reflect.Value) error {
   228  	if s, ok := v.(types.String); ok {
   229  		rv.SetString(string(s))
   230  	} else {
   231  		return &UnmarshalTypeMismatchError{v, rv.Type(), "", nbf}
   232  	}
   233  
   234  	return nil
   235  }
   236  
   237  func floatDecoder(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, rv reflect.Value) error {
   238  	if n, ok := v.(types.Float); ok {
   239  		rv.SetFloat(float64(n))
   240  	} else {
   241  		return &UnmarshalTypeMismatchError{v, rv.Type(), "", nbf}
   242  	}
   243  
   244  	return nil
   245  }
   246  
   247  func intDecoder(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, rv reflect.Value) error {
   248  	if n, ok := v.(types.Float); ok {
   249  		i := int64(n)
   250  		if rv.OverflowInt(i) {
   251  			return overflowError(nbf, n, rv.Type())
   252  		}
   253  		rv.SetInt(i)
   254  		return nil
   255  	}
   256  
   257  	// types.Int is currently encoded as types.Float during marshalling
   258  	// the block below exists to prepare for a compatibility breaking change
   259  	// todo: update comment after breaking change is made
   260  	if n, ok := v.(types.Int); ok {
   261  		rv.SetInt(int64(n))
   262  		return nil
   263  	}
   264  
   265  	return &UnmarshalTypeMismatchError{v, rv.Type(), "", nbf}
   266  }
   267  
   268  func uintDecoder(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, rv reflect.Value) error {
   269  	if n, ok := v.(types.Float); ok {
   270  		u := uint64(n)
   271  		if rv.OverflowUint(u) {
   272  			return overflowError(nbf, n, rv.Type())
   273  		}
   274  		rv.SetUint(u)
   275  		return nil
   276  	}
   277  
   278  	// types.Uint is currently encoded as types.Float during marshalling
   279  	// the block below exists to prepare for a compatibility breaking change
   280  	// todo: update comment after breaking change is made
   281  	if n, ok := v.(types.Uint); ok {
   282  		rv.SetUint(uint64(n))
   283  		return nil
   284  	}
   285  
   286  	return &UnmarshalTypeMismatchError{v, rv.Type(), "", nbf}
   287  }
   288  
   289  type decoderCacheT struct {
   290  	sync.RWMutex
   291  	m map[reflect.Type]decoderFunc
   292  }
   293  
   294  var decoderCache = &decoderCacheT{}
   295  
   296  // Separate Set decoder cache because the same type with and without the
   297  // `noms:",set"` tag decode differently (Set vs Map).
   298  var setDecoderCache = &decoderCacheT{}
   299  
   300  func (c *decoderCacheT) get(t reflect.Type) decoderFunc {
   301  	c.RLock()
   302  	defer c.RUnlock()
   303  	return c.m[t]
   304  }
   305  
   306  func (c *decoderCacheT) set(t reflect.Type, d decoderFunc) {
   307  	c.Lock()
   308  	defer c.Unlock()
   309  	if c.m == nil {
   310  		c.m = map[reflect.Type]decoderFunc{}
   311  	}
   312  	c.m[t] = d
   313  }
   314  
   315  type decField struct {
   316  	name      string
   317  	decoder   decoderFunc
   318  	index     []int
   319  	omitEmpty bool
   320  	original  bool
   321  }
   322  
   323  func structDecoderFields(t reflect.Type) ([]decField, error) {
   324  	fields := make([]decField, 0, t.NumField())
   325  	for i := 0; i < t.NumField(); i++ {
   326  		index := make([]int, 1)
   327  		index[0] = i
   328  		f := t.Field(i)
   329  		tags, err := getTags(f)
   330  
   331  		if err != nil {
   332  			return nil, err
   333  		}
   334  
   335  		if tags.skip {
   336  			continue
   337  		}
   338  
   339  		if f.Anonymous && f.PkgPath == "" && !tags.hasName {
   340  			embeddedFields, err := structDecoderFields(f.Type)
   341  
   342  			if err != nil {
   343  				return nil, err
   344  			}
   345  
   346  			for _, ef := range embeddedFields {
   347  				ef.index = append(index, ef.index...)
   348  				fields = append(fields, ef)
   349  			}
   350  			continue
   351  		}
   352  
   353  		err = validateField(f, t)
   354  
   355  		if err != nil {
   356  			return nil, err
   357  		}
   358  
   359  		decFunc, err := typeDecoder(f.Type, tags)
   360  
   361  		if err != nil {
   362  			return nil, err
   363  		}
   364  
   365  		fields = append(fields, decField{
   366  			name:      tags.name,
   367  			decoder:   decFunc,
   368  			index:     index,
   369  			omitEmpty: tags.omitEmpty,
   370  			original:  tags.original,
   371  		})
   372  	}
   373  	return fields, nil
   374  }
   375  
   376  func structDecoder(t reflect.Type) (decoderFunc, error) {
   377  	if t.Implements(nomsValueInterface) {
   378  		return nomsValueDecoder, nil
   379  	}
   380  
   381  	d := decoderCache.get(t)
   382  	if d != nil {
   383  		return d, nil
   384  	}
   385  
   386  	fields, err := structDecoderFields(t)
   387  
   388  	if err != nil {
   389  		return nil, err
   390  	}
   391  
   392  	d = func(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, rv reflect.Value) error {
   393  		s, ok := v.(types.Struct)
   394  		if !ok {
   395  			return &UnmarshalTypeMismatchError{v, rv.Type(), "expected struct", nbf}
   396  		}
   397  
   398  		for _, f := range fields {
   399  			sf := rv.FieldByIndex(f.index)
   400  			if f.original {
   401  				if sf.Type() != reflect.TypeOf(s) {
   402  					return &UnmarshalTypeMismatchError{v, rv.Type(), "field with tag \"original\" must have type Struct", nbf}
   403  				}
   404  				sf.Set(reflect.ValueOf(s))
   405  				continue
   406  			}
   407  			fv, ok, err := s.MaybeGet(f.name)
   408  
   409  			if err != nil {
   410  				return err
   411  			}
   412  
   413  			if ok {
   414  				err = f.decoder(ctx, nbf, fv, sf)
   415  
   416  				if err != nil {
   417  					return err
   418  				}
   419  			} else if !f.omitEmpty {
   420  				return &UnmarshalTypeMismatchError{v, rv.Type(), "missing field \"" + f.name + "\"", nbf}
   421  			}
   422  		}
   423  
   424  		return nil
   425  	}
   426  
   427  	decoderCache.set(t, d)
   428  	return d, nil
   429  }
   430  
   431  func nomsValueDecoder(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, rv reflect.Value) error {
   432  	if !reflect.TypeOf(v).AssignableTo(rv.Type()) {
   433  		return &UnmarshalTypeMismatchError{v, rv.Type(), "", nbf}
   434  	}
   435  	rv.Set(reflect.ValueOf(v))
   436  
   437  	return nil
   438  }
   439  
   440  func marshalerDecoder(t reflect.Type) decoderFunc {
   441  	return func(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, rv reflect.Value) error {
   442  		ptr := reflect.New(t)
   443  		err := ptr.Interface().(Unmarshaler).UnmarshalNoms(ctx, nbf, v)
   444  		if err != nil {
   445  			return err
   446  		}
   447  		rv.Set(ptr.Elem())
   448  		return nil
   449  	}
   450  }
   451  
   452  func iterListOrSlice(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, t reflect.Type, f func(c types.Value, i uint64) error) error {
   453  	switch v := v.(type) {
   454  	case types.List:
   455  		err := v.Iter(ctx, func(v types.Value, idx uint64) (stop bool, err error) {
   456  			err = f(v, idx)
   457  			return
   458  		})
   459  		if err != nil {
   460  			return err
   461  		}
   462  
   463  	case types.Set:
   464  		i := uint64(0)
   465  		err := v.IterAll(ctx, func(cv types.Value) error {
   466  			err := f(cv, i)
   467  			i++
   468  
   469  			return err
   470  		})
   471  
   472  		if err != nil {
   473  			return err
   474  		}
   475  	default:
   476  		return &UnmarshalTypeMismatchError{v, t, "", nbf}
   477  	}
   478  
   479  	return nil
   480  }
   481  
   482  func sliceDecoder(t reflect.Type) (decoderFunc, error) {
   483  	d := decoderCache.get(t)
   484  	if d != nil {
   485  		return d, nil
   486  	}
   487  
   488  	var decoder decoderFunc
   489  	var init sync.RWMutex
   490  	init.Lock()
   491  	defer init.Unlock()
   492  	d = func(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, rv reflect.Value) error {
   493  		var slice reflect.Value
   494  		if rv.IsNil() {
   495  			slice = rv
   496  		} else {
   497  			slice = rv.Slice(0, 0)
   498  		}
   499  		init.RLock()
   500  		defer init.RUnlock()
   501  		err := iterListOrSlice(ctx, nbf, v, t, func(v types.Value, _ uint64) error {
   502  			elemRv := reflect.New(t.Elem()).Elem()
   503  			err := decoder(ctx, nbf, v, elemRv)
   504  
   505  			if err != nil {
   506  				return err
   507  			}
   508  
   509  			slice = reflect.Append(slice, elemRv)
   510  			return nil
   511  		})
   512  
   513  		if err != nil {
   514  			return err
   515  		}
   516  
   517  		rv.Set(slice)
   518  
   519  		return nil
   520  	}
   521  
   522  	decoderCache.set(t, d)
   523  
   524  	var err error
   525  	decoder, err = typeDecoder(t.Elem(), nomsTags{})
   526  
   527  	if err != nil {
   528  		return nil, err
   529  	}
   530  
   531  	return d, nil
   532  }
   533  
   534  func arrayDecoder(t reflect.Type) (decoderFunc, error) {
   535  	d := decoderCache.get(t)
   536  	if d != nil {
   537  		return d, nil
   538  	}
   539  
   540  	var decoder decoderFunc
   541  	var init sync.RWMutex
   542  	init.Lock()
   543  	defer init.Unlock()
   544  	d = func(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, rv reflect.Value) error {
   545  		size := t.Len()
   546  		list, ok := v.(types.Collection)
   547  		if !ok {
   548  			return &UnmarshalTypeMismatchError{v, t, "", nbf}
   549  		}
   550  
   551  		l := int(list.Len())
   552  		if l != size {
   553  			return &UnmarshalTypeMismatchError{v, t, "length does not match", nbf}
   554  		}
   555  		init.RLock()
   556  		defer init.RUnlock()
   557  		return iterListOrSlice(ctx, nbf, list, t, func(v types.Value, i uint64) error {
   558  			return decoder(ctx, nbf, v, rv.Index(int(i)))
   559  		})
   560  	}
   561  
   562  	decoderCache.set(t, d)
   563  
   564  	var err error
   565  	decoder, err = typeDecoder(t.Elem(), nomsTags{})
   566  
   567  	if err != nil {
   568  		return nil, err
   569  	}
   570  
   571  	return d, nil
   572  }
   573  
   574  func mapFromSetDecoder(t reflect.Type) (decoderFunc, error) {
   575  	d := setDecoderCache.get(t)
   576  	if d != nil {
   577  		return d, nil
   578  	}
   579  
   580  	var decoder decoderFunc
   581  	var init sync.RWMutex
   582  	init.Lock()
   583  	defer init.Unlock()
   584  	d = func(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, rv reflect.Value) error {
   585  		m := rv
   586  
   587  		nomsSet, ok := v.(types.Set)
   588  		if !ok {
   589  			return &UnmarshalTypeMismatchError{v, t, `field has "set" tag`, nbf}
   590  		}
   591  
   592  		init.RLock()
   593  		defer init.RUnlock()
   594  		err := nomsSet.IterAll(ctx, func(v types.Value) error {
   595  			keyRv := reflect.New(t.Key()).Elem()
   596  			err := decoder(ctx, nbf, v, keyRv)
   597  
   598  			if err != nil {
   599  				return err
   600  			}
   601  
   602  			if m.IsNil() {
   603  				m = reflect.MakeMap(t)
   604  			}
   605  
   606  			m.SetMapIndex(keyRv, reflect.New(t.Elem()).Elem())
   607  			return nil
   608  		})
   609  
   610  		if err != nil {
   611  			return err
   612  		}
   613  
   614  		rv.Set(m)
   615  		return nil
   616  	}
   617  
   618  	setDecoderCache.set(t, d)
   619  
   620  	var err error
   621  	decoder, err = typeDecoder(t.Key(), nomsTags{})
   622  
   623  	if err != nil {
   624  		return nil, err
   625  	}
   626  
   627  	return d, nil
   628  }
   629  
   630  func mapDecoder(t reflect.Type, tags nomsTags) (decoderFunc, error) {
   631  	d := decoderCache.get(t)
   632  	if d != nil {
   633  		return d, nil
   634  	}
   635  
   636  	var keyDecoder decoderFunc
   637  	var valueDecoder decoderFunc
   638  	var init sync.RWMutex
   639  	init.Lock()
   640  	defer init.Unlock()
   641  	d = func(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, rv reflect.Value) error {
   642  		m := rv
   643  
   644  		// Special case decoding failure if it looks like the "set" tag is missing,
   645  		// because it's helpful.
   646  		if _, ok := v.(types.Set); ok && !tags.set {
   647  			return &UnmarshalTypeMismatchError{v, t, `field missing "set" tag`, nbf}
   648  		}
   649  
   650  		nomsMap, ok := v.(types.Map)
   651  		if !ok {
   652  			return &UnmarshalTypeMismatchError{v, t, "", nbf}
   653  		}
   654  
   655  		init.RLock()
   656  		defer init.RUnlock()
   657  		err := nomsMap.Iter(ctx, func(k, v types.Value) (stop bool, err error) {
   658  			keyRv := reflect.New(t.Key()).Elem()
   659  			err = keyDecoder(ctx, nbf, k, keyRv)
   660  
   661  			if err != nil {
   662  				return
   663  			}
   664  
   665  			valueRv := reflect.New(t.Elem()).Elem()
   666  			err = valueDecoder(ctx, nbf, v, valueRv)
   667  
   668  			if err != nil {
   669  				return
   670  			}
   671  
   672  			if m.IsNil() {
   673  				m = reflect.MakeMap(t)
   674  			}
   675  
   676  			m.SetMapIndex(keyRv, valueRv)
   677  			return
   678  		})
   679  
   680  		if err != nil {
   681  			return err
   682  		}
   683  
   684  		rv.Set(m)
   685  		return nil
   686  	}
   687  
   688  	decoderCache.set(t, d)
   689  
   690  	var err error
   691  	keyDecoder, err = typeDecoder(t.Key(), nomsTags{})
   692  
   693  	if err != nil {
   694  		return nil, err
   695  	}
   696  
   697  	valueDecoder, err = typeDecoder(t.Elem(), nomsTags{})
   698  
   699  	if err != nil {
   700  		return nil, err
   701  	}
   702  
   703  	return d, nil
   704  }
   705  
   706  func interfaceDecoder(t reflect.Type) (decoderFunc, error) {
   707  	if t.Implements(nomsValueInterface) {
   708  		return nomsValueDecoder, nil
   709  	}
   710  
   711  	if t != emptyInterface {
   712  		return nil, &UnsupportedTypeError{Type: t}
   713  	}
   714  
   715  	return func(ctx context.Context, nbf *types.NomsBinFormat, v types.Value, rv reflect.Value) error {
   716  		// TODO: Go directly from value to go type
   717  		vt, err := types.TypeOf(v)
   718  
   719  		if err != nil {
   720  			return err
   721  		}
   722  
   723  		t, err := getGoTypeForNomsType(vt, rv.Type(), v)
   724  
   725  		if err != nil {
   726  			return err
   727  		}
   728  
   729  		i := reflect.New(t).Elem()
   730  		tdec, err := typeDecoder(t, nomsTags{})
   731  
   732  		if err != nil {
   733  			return err
   734  		}
   735  
   736  		err = tdec(ctx, nbf, v, i)
   737  
   738  		if err != nil {
   739  			return err
   740  		}
   741  
   742  		rv.Set(i)
   743  		return nil
   744  	}, nil
   745  }
   746  
   747  func getGoTypeForNomsType(nt *types.Type, rt reflect.Type, v types.Value) (reflect.Type, error) {
   748  	switch nt.TargetKind() {
   749  	case types.BoolKind:
   750  		return reflect.TypeOf(false), nil
   751  	case types.FloatKind:
   752  		return reflect.TypeOf(float64(0)), nil
   753  	case types.StringKind:
   754  		return reflect.TypeOf(""), nil
   755  	case types.ListKind, types.SetKind:
   756  		et, err := getGoTypeForNomsType(nt.Desc.(types.CompoundDesc).ElemTypes[0], rt, v)
   757  
   758  		if err != nil {
   759  			return nil, err
   760  		}
   761  
   762  		return reflect.SliceOf(et), nil
   763  	case types.MapKind:
   764  		kt, err := getGoTypeForNomsType(nt.Desc.(types.CompoundDesc).ElemTypes[0], rt, v)
   765  
   766  		if err != nil {
   767  			return nil, err
   768  		}
   769  
   770  		vt, err := getGoTypeForNomsType(nt.Desc.(types.CompoundDesc).ElemTypes[1], rt, v)
   771  
   772  		if err != nil {
   773  			return nil, err
   774  		}
   775  
   776  		return reflect.MapOf(kt, vt), nil
   777  	case types.UnionKind:
   778  		// Visit union types to raise potential errors
   779  		for _, ut := range nt.Desc.(types.CompoundDesc).ElemTypes {
   780  			getGoTypeForNomsType(ut, rt, v)
   781  		}
   782  		return emptyInterface, nil
   783  	// case types.StructKind:
   784  	// 	reflect.StructOf was not added until Go 1.7
   785  	default:
   786  		return nil, &UnmarshalTypeMismatchError{Value: v, Type: rt}
   787  	}
   788  }
   789  
   790  func shouldMapDecodeFromSet(rt reflect.Type, tags nomsTags) bool {
   791  	// map[T]struct{} `noms:,"set"`
   792  	return tags.set &&
   793  		rt.Elem().Kind() == reflect.Struct &&
   794  		rt.Elem().NumField() == 0
   795  }