mapslice.go raw

   1  // Copyright (c) Microsoft Corporation.
   2  // Licensed under the MIT license.
   3  
   4  package json
   5  
   6  import (
   7  	"encoding/json"
   8  	"fmt"
   9  	"reflect"
  10  )
  11  
  12  // unmarshalMap unmarshal's a map.
  13  func unmarshalMap(dec *json.Decoder, m reflect.Value) error {
  14  	if m.Kind() != reflect.Ptr || m.Elem().Kind() != reflect.Map {
  15  		panic("unmarshalMap called on non-*map value")
  16  	}
  17  	mapValueType := m.Elem().Type().Elem()
  18  	walk := mapWalk{dec: dec, m: m, valueType: mapValueType}
  19  	if err := walk.run(); err != nil {
  20  		return err
  21  	}
  22  	return nil
  23  }
  24  
  25  type mapWalk struct {
  26  	dec       *json.Decoder
  27  	key       string
  28  	m         reflect.Value
  29  	valueType reflect.Type
  30  }
  31  
  32  // run runs our decoder state machine.
  33  func (m *mapWalk) run() error {
  34  	var state = m.start
  35  	var err error
  36  	for {
  37  		state, err = state()
  38  		if err != nil {
  39  			return err
  40  		}
  41  		if state == nil {
  42  			return nil
  43  		}
  44  	}
  45  }
  46  
  47  func (m *mapWalk) start() (stateFn, error) {
  48  	// maps can have custom unmarshaler's.
  49  	if hasUnmarshalJSON(m.m) {
  50  		err := m.dec.Decode(m.m.Interface())
  51  		if err != nil {
  52  			return nil, err
  53  		}
  54  		return nil, nil
  55  	}
  56  
  57  	// We only want to use this if the map value is:
  58  	// *struct/struct/map/slice
  59  	// otherwise use standard decode
  60  	t, _ := m.valueBaseType()
  61  	switch t.Kind() {
  62  	case reflect.Struct, reflect.Map, reflect.Slice:
  63  		delim, err := m.dec.Token()
  64  		if err != nil {
  65  			return nil, err
  66  		}
  67  		// This indicates the value was set to JSON null.
  68  		if delim == nil {
  69  			return nil, nil
  70  		}
  71  		if !delimIs(delim, '{') {
  72  			return nil, fmt.Errorf("Unmarshal expected opening {, received %v", delim)
  73  		}
  74  		return m.next, nil
  75  	case reflect.Ptr:
  76  		return nil, fmt.Errorf("do not support maps with values of '**type' or '*reference")
  77  	}
  78  
  79  	// This is a basic map type, so just use Decode().
  80  	if err := m.dec.Decode(m.m.Interface()); err != nil {
  81  		return nil, err
  82  	}
  83  
  84  	return nil, nil
  85  }
  86  
  87  func (m *mapWalk) next() (stateFn, error) {
  88  	if m.dec.More() {
  89  		key, err := m.dec.Token()
  90  		if err != nil {
  91  			return nil, err
  92  		}
  93  		m.key = key.(string)
  94  		return m.storeValue, nil
  95  	}
  96  	// No more entries, so remove final }.
  97  	_, err := m.dec.Token()
  98  	if err != nil {
  99  		return nil, err
 100  	}
 101  	return nil, nil
 102  }
 103  
 104  func (m *mapWalk) storeValue() (stateFn, error) {
 105  	v := m.valueType
 106  	for {
 107  		switch v.Kind() {
 108  		case reflect.Ptr:
 109  			v = v.Elem()
 110  			continue
 111  		case reflect.Struct:
 112  			return m.storeStruct, nil
 113  		case reflect.Map:
 114  			return m.storeMap, nil
 115  		case reflect.Slice:
 116  			return m.storeSlice, nil
 117  		}
 118  		return nil, fmt.Errorf("bug: mapWalk.storeValue() called on unsupported type: %v", v.Kind())
 119  	}
 120  }
 121  
 122  func (m *mapWalk) storeStruct() (stateFn, error) {
 123  	v := newValue(m.valueType)
 124  	if err := unmarshalStruct(m.dec, v.Interface()); err != nil {
 125  		return nil, err
 126  	}
 127  
 128  	if m.valueType.Kind() == reflect.Ptr {
 129  		m.m.Elem().SetMapIndex(reflect.ValueOf(m.key), v)
 130  		return m.next, nil
 131  	}
 132  	m.m.Elem().SetMapIndex(reflect.ValueOf(m.key), v.Elem())
 133  
 134  	return m.next, nil
 135  }
 136  
 137  func (m *mapWalk) storeMap() (stateFn, error) {
 138  	v := reflect.MakeMap(m.valueType)
 139  	ptr := newValue(v.Type())
 140  	ptr.Elem().Set(v)
 141  	if err := unmarshalMap(m.dec, ptr); err != nil {
 142  		return nil, err
 143  	}
 144  
 145  	m.m.Elem().SetMapIndex(reflect.ValueOf(m.key), v)
 146  
 147  	return m.next, nil
 148  }
 149  
 150  func (m *mapWalk) storeSlice() (stateFn, error) {
 151  	v := newValue(m.valueType)
 152  	if err := unmarshalSlice(m.dec, v); err != nil {
 153  		return nil, err
 154  	}
 155  
 156  	m.m.Elem().SetMapIndex(reflect.ValueOf(m.key), v.Elem())
 157  
 158  	return m.next, nil
 159  }
 160  
 161  // valueType returns the underlying Type. So a *struct would yield
 162  // struct, etc...
 163  func (m *mapWalk) valueBaseType() (reflect.Type, bool) {
 164  	ptr := false
 165  	v := m.valueType
 166  	if v.Kind() == reflect.Ptr {
 167  		ptr = true
 168  		v = v.Elem()
 169  	}
 170  	return v, ptr
 171  }
 172  
 173  // unmarshalSlice unmarshal's the next value, which must be a slice, into
 174  // ptrSlice, which must be a pointer to a slice. newValue() can be use to
 175  // create the slice.
 176  func unmarshalSlice(dec *json.Decoder, ptrSlice reflect.Value) error {
 177  	if ptrSlice.Kind() != reflect.Ptr || ptrSlice.Elem().Kind() != reflect.Slice {
 178  		panic("unmarshalSlice called on non-*[]slice value")
 179  	}
 180  	sliceValueType := ptrSlice.Elem().Type().Elem()
 181  	walk := sliceWalk{
 182  		dec:       dec,
 183  		s:         ptrSlice,
 184  		valueType: sliceValueType,
 185  	}
 186  	if err := walk.run(); err != nil {
 187  		return err
 188  	}
 189  
 190  	return nil
 191  }
 192  
 193  type sliceWalk struct {
 194  	dec       *json.Decoder
 195  	s         reflect.Value // *[]slice
 196  	valueType reflect.Type
 197  }
 198  
 199  // run runs our decoder state machine.
 200  func (s *sliceWalk) run() error {
 201  	var state = s.start
 202  	var err error
 203  	for {
 204  		state, err = state()
 205  		if err != nil {
 206  			return err
 207  		}
 208  		if state == nil {
 209  			return nil
 210  		}
 211  	}
 212  }
 213  
 214  func (s *sliceWalk) start() (stateFn, error) {
 215  	// slices can have custom unmarshaler's.
 216  	if hasUnmarshalJSON(s.s) {
 217  		err := s.dec.Decode(s.s.Interface())
 218  		if err != nil {
 219  			return nil, err
 220  		}
 221  		return nil, nil
 222  	}
 223  
 224  	// We only want to use this if the slice value is:
 225  	// []*struct/[]struct/[]map/[]slice
 226  	// otherwise use standard decode
 227  	t := s.valueBaseType()
 228  
 229  	switch t.Kind() {
 230  	case reflect.Ptr:
 231  		return nil, fmt.Errorf("cannot unmarshal into a **<type> or *<reference>")
 232  	case reflect.Struct, reflect.Map, reflect.Slice:
 233  		delim, err := s.dec.Token()
 234  		if err != nil {
 235  			return nil, err
 236  		}
 237  		// This indicates the value was set to nil.
 238  		if delim == nil {
 239  			return nil, nil
 240  		}
 241  		if !delimIs(delim, '[') {
 242  			return nil, fmt.Errorf("Unmarshal expected opening [, received %v", delim)
 243  		}
 244  		return s.next, nil
 245  	}
 246  
 247  	if err := s.dec.Decode(s.s.Interface()); err != nil {
 248  		return nil, err
 249  	}
 250  	return nil, nil
 251  }
 252  
 253  func (s *sliceWalk) next() (stateFn, error) {
 254  	if s.dec.More() {
 255  		return s.storeValue, nil
 256  	}
 257  	// Nothing left in the slice, remove closing ]
 258  	_, err := s.dec.Token()
 259  	return nil, err
 260  }
 261  
 262  func (s *sliceWalk) storeValue() (stateFn, error) {
 263  	t := s.valueBaseType()
 264  	switch t.Kind() {
 265  	case reflect.Ptr:
 266  		return nil, fmt.Errorf("do not support 'pointer to pointer' or 'pointer to reference' types")
 267  	case reflect.Struct:
 268  		return s.storeStruct, nil
 269  	case reflect.Map:
 270  		return s.storeMap, nil
 271  	case reflect.Slice:
 272  		return s.storeSlice, nil
 273  	}
 274  	return nil, fmt.Errorf("bug: sliceWalk.storeValue() called on unsupported type: %v", t.Kind())
 275  }
 276  
 277  func (s *sliceWalk) storeStruct() (stateFn, error) {
 278  	v := newValue(s.valueType)
 279  	if err := unmarshalStruct(s.dec, v.Interface()); err != nil {
 280  		return nil, err
 281  	}
 282  
 283  	if s.valueType.Kind() == reflect.Ptr {
 284  		s.s.Elem().Set(reflect.Append(s.s.Elem(), v))
 285  		return s.next, nil
 286  	}
 287  
 288  	s.s.Elem().Set(reflect.Append(s.s.Elem(), v.Elem()))
 289  	return s.next, nil
 290  }
 291  
 292  func (s *sliceWalk) storeMap() (stateFn, error) {
 293  	v := reflect.MakeMap(s.valueType)
 294  	ptr := newValue(v.Type())
 295  	ptr.Elem().Set(v)
 296  
 297  	if err := unmarshalMap(s.dec, ptr); err != nil {
 298  		return nil, err
 299  	}
 300  
 301  	s.s.Elem().Set(reflect.Append(s.s.Elem(), v))
 302  
 303  	return s.next, nil
 304  }
 305  
 306  func (s *sliceWalk) storeSlice() (stateFn, error) {
 307  	v := newValue(s.valueType)
 308  	if err := unmarshalSlice(s.dec, v); err != nil {
 309  		return nil, err
 310  	}
 311  
 312  	s.s.Elem().Set(reflect.Append(s.s.Elem(), v.Elem()))
 313  
 314  	return s.next, nil
 315  }
 316  
 317  // valueType returns the underlying Type. So a *struct would yield
 318  // struct, etc...
 319  func (s *sliceWalk) valueBaseType() reflect.Type {
 320  	v := s.valueType
 321  	if v.Kind() == reflect.Ptr {
 322  		v = v.Elem()
 323  	}
 324  	return v
 325  }
 326  
 327  // newValue() returns a new *type that represents type passed.
 328  func newValue(valueType reflect.Type) reflect.Value {
 329  	if valueType.Kind() == reflect.Ptr {
 330  		return reflect.New(valueType.Elem())
 331  	}
 332  	return reflect.New(valueType)
 333  }
 334