...

Source file src/github.com/aws/smithy-go/document/json/decoder.go

Documentation: github.com/aws/smithy-go/document/json

     1  package json
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"math/big"
     7  	"reflect"
     8  
     9  	"github.com/aws/smithy-go/document"
    10  	"github.com/aws/smithy-go/document/internal/serde"
    11  )
    12  
    13  // DecoderOptions is the set of options that can be configured for a Decoder.
    14  type DecoderOptions struct{}
    15  
    16  // Decoder is a Smithy document decoder for JSON based protocols.
    17  type Decoder struct {
    18  	options DecoderOptions
    19  }
    20  
    21  // DecodeJSONInterface decodes the supported JSON input types and stores the result in the value pointed by toValue.
    22  //
    23  // If toValue is not a compatible type, or an error occurs while decoding DecodeJSONInterface will return an error.
    24  //
    25  // The supported input JSON types are:
    26  //   bool -> JSON boolean
    27  //   float64 -> JSON number
    28  //   json.Number -> JSON number
    29  //   string -> JSON string
    30  //   []interface{} -> JSON array
    31  //   map[string]interface{} -> JSON object
    32  //   nil -> JSON null
    33  //
    34  func (d *Decoder) DecodeJSONInterface(input interface{}, toValue interface{}) error {
    35  	if document.IsNoSerde(toValue) {
    36  		return fmt.Errorf("unsupported type: %T", toValue)
    37  	}
    38  
    39  	v := reflect.ValueOf(toValue)
    40  
    41  	if v.Kind() != reflect.Ptr || v.IsNil() || !v.IsValid() {
    42  		return &document.InvalidUnmarshalError{Type: reflect.TypeOf(toValue)}
    43  	}
    44  
    45  	return d.decode(input, v, serde.Tag{})
    46  }
    47  
    48  func (d *Decoder) decode(jv interface{}, rv reflect.Value, tag serde.Tag) error {
    49  	if jv == nil {
    50  		rv := serde.Indirect(rv, true)
    51  		return d.decodeJSONNull(rv)
    52  	}
    53  
    54  	rv = serde.Indirect(rv, false)
    55  
    56  	if err := d.unsupportedType(jv, rv); err != nil {
    57  		return err
    58  	}
    59  
    60  	switch tv := jv.(type) {
    61  	case bool:
    62  		return d.decodeJSONBoolean(tv, rv)
    63  	case json.Number:
    64  		return d.decodeJSONNumber(tv, rv)
    65  	case float64:
    66  		return d.decodeJSONFloat64(tv, rv)
    67  	case string:
    68  		return d.decodeJSONString(tv, rv)
    69  	case []interface{}:
    70  		return d.decodeJSONArray(tv, rv)
    71  	case map[string]interface{}:
    72  		return d.decodeJSONObject(tv, rv)
    73  	default:
    74  		return fmt.Errorf("unsupported json type, %T", tv)
    75  	}
    76  }
    77  
    78  func (d *Decoder) decodeJSONNull(rv reflect.Value) error {
    79  	if rv.IsValid() && rv.CanSet() {
    80  		rv.Set(reflect.Zero(rv.Type()))
    81  	}
    82  
    83  	return nil
    84  }
    85  
    86  func (d *Decoder) decodeJSONBoolean(tv bool, rv reflect.Value) error {
    87  	switch rv.Kind() {
    88  	case reflect.Bool, reflect.Interface:
    89  		rv.Set(reflect.ValueOf(tv).Convert(rv.Type()))
    90  	default:
    91  		return &document.UnmarshalTypeError{Value: "bool", Type: rv.Type()}
    92  	}
    93  
    94  	return nil
    95  }
    96  
    97  func (d *Decoder) decodeJSONNumber(tv json.Number, rv reflect.Value) error {
    98  	switch rv.Kind() {
    99  	case reflect.Interface:
   100  		rv.Set(reflect.ValueOf(document.Number(tv)))
   101  	case reflect.String:
   102  		// covers document.Number
   103  		rv.SetString(tv.String())
   104  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   105  		i, err := tv.Int64()
   106  		if err != nil {
   107  			return err
   108  		}
   109  		if rv.OverflowInt(i) {
   110  			return &document.UnmarshalTypeError{
   111  				Value: fmt.Sprintf("number overflow, %s", tv.String()),
   112  				Type:  rv.Type(),
   113  			}
   114  		}
   115  		rv.SetInt(i)
   116  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   117  		u, err := document.Number(tv).Uint64()
   118  		if err != nil {
   119  			return err
   120  		}
   121  		if rv.OverflowUint(u) {
   122  			return &document.UnmarshalTypeError{
   123  				Value: fmt.Sprintf("number overflow, %s", tv.String()),
   124  				Type:  rv.Type(),
   125  			}
   126  		}
   127  		rv.SetUint(u)
   128  	case reflect.Float32:
   129  		f, err := document.Number(tv).Float32()
   130  		if err != nil {
   131  			return err
   132  		}
   133  		if rv.OverflowFloat(f) {
   134  			return &document.UnmarshalTypeError{
   135  				Value: fmt.Sprintf("float overflow, %s", tv.String()),
   136  				Type:  rv.Type(),
   137  			}
   138  		}
   139  		rv.SetFloat(f)
   140  	case reflect.Float64:
   141  		f, err := document.Number(tv).Float64()
   142  		if err != nil {
   143  			return err
   144  		}
   145  		if rv.OverflowFloat(f) {
   146  			return &document.UnmarshalTypeError{
   147  				Value: fmt.Sprintf("float overflow, %s", tv.String()),
   148  				Type:  rv.Type(),
   149  			}
   150  		}
   151  		rv.SetFloat(f)
   152  	default:
   153  		rvt := rv.Type()
   154  		switch {
   155  		case rvt.ConvertibleTo(serde.ReflectTypeOf.BigFloat):
   156  			sv := tv.String()
   157  			f, ok := (&big.Float{}).SetString(sv)
   158  			if !ok {
   159  				return &document.UnmarshalTypeError{
   160  					Value: fmt.Sprintf("invalid number format, %s", sv),
   161  					Type:  rv.Type(),
   162  				}
   163  			}
   164  			rv.Set(reflect.ValueOf(*f).Convert(rvt))
   165  		case rvt.ConvertibleTo(serde.ReflectTypeOf.BigInt):
   166  			sv := tv.String()
   167  			i, ok := (&big.Int{}).SetString(sv, 10)
   168  			if !ok {
   169  				return &document.UnmarshalTypeError{
   170  					Value: fmt.Sprintf("invalid number format, %s", sv),
   171  					Type:  rv.Type(),
   172  				}
   173  			}
   174  			rv.Set(reflect.ValueOf(*i).Convert(rvt))
   175  		default:
   176  			return &document.UnmarshalTypeError{Value: "number", Type: rv.Type()}
   177  		}
   178  	}
   179  
   180  	return nil
   181  }
   182  
   183  func (d *Decoder) decodeJSONFloat64(tv float64, rv reflect.Value) error {
   184  	switch rv.Kind() {
   185  	case reflect.Interface:
   186  		rv.Set(reflect.ValueOf(tv))
   187  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   188  		i, accuracy := big.NewFloat(tv).Int64()
   189  		if accuracy != big.Exact || rv.OverflowInt(i) {
   190  			return &document.UnmarshalTypeError{
   191  				Value: fmt.Sprintf("number overflow, %e", tv),
   192  				Type:  rv.Type(),
   193  			}
   194  		}
   195  		rv.SetInt(i)
   196  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   197  		u, accuracy := big.NewFloat(tv).Uint64()
   198  		if accuracy != big.Exact || rv.OverflowUint(u) {
   199  			return &document.UnmarshalTypeError{
   200  				Value: fmt.Sprintf("number overflow, %e", tv),
   201  				Type:  rv.Type(),
   202  			}
   203  		}
   204  		rv.SetUint(u)
   205  	case reflect.Float32, reflect.Float64:
   206  		if rv.OverflowFloat(tv) {
   207  			return &document.UnmarshalTypeError{
   208  				Value: fmt.Sprintf("float overflow, %e", tv),
   209  				Type:  rv.Type(),
   210  			}
   211  		}
   212  		rv.SetFloat(tv)
   213  	default:
   214  		rvt := rv.Type()
   215  		switch {
   216  		case rvt.ConvertibleTo(serde.ReflectTypeOf.BigFloat):
   217  			f := big.NewFloat(tv)
   218  			rv.Set(reflect.ValueOf(*f).Convert(rvt))
   219  		case rvt.ConvertibleTo(serde.ReflectTypeOf.BigInt):
   220  			i, accuracy := big.NewFloat(tv).Int(nil)
   221  			if accuracy != big.Exact {
   222  				return &document.UnmarshalTypeError{
   223  					Value: fmt.Sprintf("int overflow, %e", tv),
   224  					Type:  rv.Type(),
   225  				}
   226  			}
   227  			rv.Set(reflect.ValueOf(*i).Convert(rvt))
   228  		default:
   229  			return &document.UnmarshalTypeError{Value: "number", Type: rv.Type()}
   230  		}
   231  	}
   232  
   233  	return nil
   234  }
   235  
   236  func (d *Decoder) decodeJSONArray(tv []interface{}, rv reflect.Value) error {
   237  	var isArray bool
   238  
   239  	switch rv.Kind() {
   240  	case reflect.Slice:
   241  		// Make room for the slice elements if needed
   242  		if rv.IsNil() || rv.Cap() < len(tv) {
   243  			rv.Set(reflect.MakeSlice(rv.Type(), 0, len(tv)))
   244  		}
   245  	case reflect.Array:
   246  		// Limited to capacity of existing array.
   247  		isArray = true
   248  	case reflect.Interface:
   249  		s := make([]interface{}, len(tv))
   250  		for i, av := range tv {
   251  			if err := d.decode(av, reflect.ValueOf(&s[i]).Elem(), serde.Tag{}); err != nil {
   252  				return err
   253  			}
   254  		}
   255  		rv.Set(reflect.ValueOf(s))
   256  		return nil
   257  	default:
   258  		return &document.UnmarshalTypeError{Value: "list", Type: rv.Type()}
   259  	}
   260  
   261  	// If rv is not a slice, array
   262  	for i := 0; i < rv.Cap() && i < len(tv); i++ {
   263  		if !isArray {
   264  			rv.SetLen(i + 1)
   265  		}
   266  		if err := d.decode(tv[i], rv.Index(i), serde.Tag{}); err != nil {
   267  			return err
   268  		}
   269  	}
   270  
   271  	return nil
   272  }
   273  
   274  func (d *Decoder) decodeJSONString(tv string, rv reflect.Value) error {
   275  	switch rv.Kind() {
   276  	case reflect.String:
   277  		rv.SetString(tv)
   278  	case reflect.Interface:
   279  		// Ensure type aliasing is handled properly
   280  		rv.Set(reflect.ValueOf(tv).Convert(rv.Type()))
   281  	default:
   282  		return &document.UnmarshalTypeError{Value: "string", Type: rv.Type()}
   283  	}
   284  
   285  	return nil
   286  }
   287  
   288  func (d *Decoder) decodeJSONObject(tv map[string]interface{}, rv reflect.Value) error {
   289  	switch rv.Kind() {
   290  	case reflect.Map:
   291  		t := rv.Type()
   292  		if t.Key().Kind() != reflect.String {
   293  			return &document.UnmarshalTypeError{Value: "map string key", Type: t.Key()}
   294  		}
   295  		if rv.IsNil() {
   296  			rv.Set(reflect.MakeMap(t))
   297  		}
   298  	case reflect.Struct:
   299  		if rv.CanInterface() && document.IsNoSerde(rv.Interface()) {
   300  			return &document.UnmarshalTypeError{
   301  				Value: fmt.Sprintf("unsupported type"),
   302  				Type:  rv.Type(),
   303  			}
   304  		}
   305  	case reflect.Interface:
   306  		rv.Set(reflect.MakeMap(serde.ReflectTypeOf.MapStringToInterface))
   307  		rv = rv.Elem()
   308  	default:
   309  		return &document.UnmarshalTypeError{Value: "map", Type: rv.Type()}
   310  	}
   311  
   312  	if rv.Kind() == reflect.Map {
   313  		for k, kv := range tv {
   314  			key := reflect.New(rv.Type().Key()).Elem()
   315  			key.SetString(k)
   316  			elem := reflect.New(rv.Type().Elem()).Elem()
   317  			if err := d.decode(kv, elem, serde.Tag{}); err != nil {
   318  				return err
   319  			}
   320  			rv.SetMapIndex(key, elem)
   321  		}
   322  	} else if rv.Kind() == reflect.Struct {
   323  		fields := serde.GetStructFields(rv.Type())
   324  		for k, kv := range tv {
   325  			if f, ok := fields.FieldByName(k); ok {
   326  				fv := serde.DecoderFieldByIndex(rv, f.Index)
   327  				if err := d.decode(kv, fv, f.Tag); err != nil {
   328  					return err
   329  				}
   330  			}
   331  		}
   332  	}
   333  
   334  	return nil
   335  }
   336  
   337  func (d *Decoder) unsupportedType(jv interface{}, rv reflect.Value) error {
   338  	if rv.Kind() == reflect.Interface && rv.NumMethod() != 0 {
   339  		return &document.UnmarshalTypeError{Value: "non-empty interface", Type: rv.Type()}
   340  	}
   341  
   342  	if rv.Type().ConvertibleTo(serde.ReflectTypeOf.Time) {
   343  		return &document.UnmarshalTypeError{
   344  			Type:  rv.Type(),
   345  			Value: fmt.Sprintf("time value: %v", jv),
   346  		}
   347  	}
   348  	return nil
   349  }
   350  

View as plain text