yunion.io/x/jsonutils@v1.0.0/unmarshal.go (about)

     1  // Copyright 2019 Yunion
     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  package jsonutils
    16  
    17  /**
    18  jsonutils.Unmarshal
    19  
    20  Fill the value of JSONObject into any object
    21  
    22  */
    23  
    24  import (
    25  	"fmt"
    26  	"reflect"
    27  	"strconv"
    28  	"strings"
    29  	"time"
    30  
    31  	"yunion.io/x/log"
    32  	"yunion.io/x/pkg/errors"
    33  	"yunion.io/x/pkg/gotypes"
    34  	"yunion.io/x/pkg/sortedmap"
    35  	"yunion.io/x/pkg/tristate"
    36  	"yunion.io/x/pkg/util/reflectutils"
    37  	"yunion.io/x/pkg/util/timeutils"
    38  	"yunion.io/x/pkg/utils"
    39  )
    40  
    41  func (this *JSONValue) Unmarshal(obj interface{}, keys ...string) error {
    42  	return jsonUnmarshal(this, obj, keys)
    43  }
    44  
    45  func (this *JSONArray) Unmarshal(obj interface{}, keys ...string) error {
    46  	return jsonUnmarshal(this, obj, keys)
    47  }
    48  
    49  func (this *JSONDict) Unmarshal(obj interface{}, keys ...string) error {
    50  	return jsonUnmarshal(this, obj, keys)
    51  }
    52  
    53  func jsonUnmarshal(jo JSONObject, o interface{}, keys []string) error {
    54  	if len(keys) > 0 {
    55  		var err error = nil
    56  		jo, err = jo.Get(keys...)
    57  		if err != nil {
    58  			return errors.Wrap(err, "Get")
    59  		}
    60  	}
    61  	value := reflect.ValueOf(o)
    62  	err := jo.unmarshalValue(reflect.Indirect(value))
    63  	if err != nil {
    64  		return errors.Wrap(err, "jo.unmarshalValue")
    65  	}
    66  	return nil
    67  }
    68  
    69  func (this *JSONValue) unmarshalValue(val reflect.Value) error {
    70  	if val.CanSet() {
    71  		zeroVal := reflect.New(val.Type()).Elem()
    72  		val.Set(zeroVal)
    73  	}
    74  	return nil
    75  }
    76  
    77  func (this *JSONInt) unmarshalValue(val reflect.Value) error {
    78  	switch val.Type() {
    79  	case JSONIntType:
    80  		json := val.Interface().(JSONInt)
    81  		json.data = this.data
    82  		return nil
    83  	case JSONIntPtrType, JSONObjectType:
    84  		val.Set(reflect.ValueOf(this))
    85  		return nil
    86  	case JSONStringType:
    87  		json := val.Interface().(JSONString)
    88  		json.data = fmt.Sprintf("%d", this.data)
    89  		return nil
    90  	case JSONStringPtrType:
    91  		json := val.Interface().(*JSONString)
    92  		data := fmt.Sprintf("%d", this.data)
    93  		if json == nil {
    94  			json = NewString(data)
    95  			val.Set(reflect.ValueOf(json))
    96  		} else {
    97  			json.data = data
    98  		}
    99  		return nil
   100  	case JSONBoolType, JSONFloatType, JSONArrayType, JSONDictType, JSONBoolPtrType, JSONFloatPtrType, JSONArrayPtrType, JSONDictPtrType:
   101  		return ErrTypeMismatch // fmt.Errorf("JSONInt type mismatch %s", val.Type())
   102  	case tristate.TriStateType:
   103  		if this.data == 0 {
   104  			val.Set(tristate.TriStateFalseValue)
   105  		} else {
   106  			val.Set(tristate.TriStateTrueValue)
   107  		}
   108  	}
   109  	switch val.Kind() {
   110  	case reflect.Int, reflect.Int8, reflect.Int16,
   111  		reflect.Int32, reflect.Int64:
   112  		val.SetInt(this.data)
   113  	case reflect.Uint, reflect.Uint8, reflect.Uint16,
   114  		reflect.Uint32, reflect.Uint64:
   115  		val.SetUint(uint64(this.data))
   116  	case reflect.Float32, reflect.Float64:
   117  		val.SetFloat(float64(this.data))
   118  	case reflect.Bool:
   119  		if this.data == 0 {
   120  			val.SetBool(false)
   121  		} else {
   122  			val.SetBool(true)
   123  		}
   124  	case reflect.String:
   125  		val.SetString(fmt.Sprintf("%d", this.data))
   126  	case reflect.Ptr:
   127  		if val.IsNil() {
   128  			val.Set(reflect.New(val.Type().Elem()))
   129  		}
   130  		return this.unmarshalValue(val.Elem())
   131  	case reflect.Interface:
   132  		val.Set(reflect.ValueOf(this.data))
   133  	default:
   134  		return errors.Wrapf(ErrTypeMismatch, "JSONInt vs. %s", val.Type())
   135  	}
   136  	return nil
   137  }
   138  
   139  func (this *JSONBool) unmarshalValue(val reflect.Value) error {
   140  	switch val.Type() {
   141  	case JSONBoolType:
   142  		json := val.Interface().(JSONBool)
   143  		json.data = this.data
   144  		return nil
   145  	case JSONBoolPtrType, JSONObjectType:
   146  		val.Set(reflect.ValueOf(this))
   147  		return nil
   148  	case JSONStringType:
   149  		json := val.Interface().(JSONString)
   150  		json.data = strconv.FormatBool(this.data)
   151  		return nil
   152  	case JSONStringPtrType:
   153  		json := val.Interface().(*JSONString)
   154  		data := strconv.FormatBool(this.data)
   155  		if json == nil {
   156  			json = NewString(data)
   157  			val.Set(reflect.ValueOf(json))
   158  		} else {
   159  			json.data = data
   160  		}
   161  		return nil
   162  	case JSONIntType, JSONFloatType, JSONArrayType, JSONDictType, JSONIntPtrType, JSONFloatPtrType, JSONArrayPtrType, JSONDictPtrType:
   163  		return ErrTypeMismatch // fmt.Errorf("JSONBool type mismatch %s", val.Type())
   164  	case tristate.TriStateType:
   165  		if this.data {
   166  			val.Set(tristate.TriStateTrueValue)
   167  		} else {
   168  			val.Set(tristate.TriStateFalseValue)
   169  		}
   170  	}
   171  	switch val.Kind() {
   172  	case reflect.Int, reflect.Uint, reflect.Int8, reflect.Uint8,
   173  		reflect.Int16, reflect.Uint16, reflect.Int32, reflect.Uint32, reflect.Int64, reflect.Uint64:
   174  		if this.data {
   175  			val.SetInt(1)
   176  		} else {
   177  			val.SetInt(0)
   178  		}
   179  	case reflect.Float32, reflect.Float64:
   180  		if this.data {
   181  			val.SetFloat(1.0)
   182  		} else {
   183  			val.SetFloat(0.0)
   184  		}
   185  	case reflect.Bool:
   186  		val.SetBool(this.data)
   187  	case reflect.String:
   188  		if this.data {
   189  			val.SetString("true")
   190  		} else {
   191  			val.SetString("false")
   192  		}
   193  	case reflect.Ptr:
   194  		if val.IsNil() {
   195  			val.Set(reflect.New(val.Type().Elem()))
   196  		}
   197  		return this.unmarshalValue(val.Elem())
   198  	case reflect.Interface:
   199  		val.Set(reflect.ValueOf(this.data))
   200  	default:
   201  		return errors.Wrapf(ErrTypeMismatch, "JSONBool vs. %s", val.Type())
   202  	}
   203  	return nil
   204  }
   205  
   206  func (this *JSONFloat) unmarshalValue(val reflect.Value) error {
   207  	switch val.Type() {
   208  	case JSONFloatType:
   209  		json := val.Interface().(JSONFloat)
   210  		json.data = this.data
   211  		return nil
   212  	case JSONFloatPtrType, JSONObjectType:
   213  		val.Set(reflect.ValueOf(this))
   214  		return nil
   215  	case JSONStringType:
   216  		json := val.Interface().(JSONString)
   217  		json.data = fmt.Sprintf("%f", this.data)
   218  		return nil
   219  	case JSONStringPtrType:
   220  		json := val.Interface().(*JSONString)
   221  		data := fmt.Sprintf("%f", this.data)
   222  		if json == nil {
   223  			json = NewString(data)
   224  			val.Set(reflect.ValueOf(json))
   225  		} else {
   226  			json.data = data
   227  		}
   228  		return nil
   229  	case JSONIntType:
   230  		json := val.Interface().(JSONInt)
   231  		json.data = int64(this.data)
   232  		return nil
   233  	case JSONIntPtrType:
   234  		json := val.Interface().(*JSONInt)
   235  		if json == nil {
   236  			json = NewInt(int64(this.data))
   237  			val.Set(reflect.ValueOf(json))
   238  		} else {
   239  			json.data = int64(this.data)
   240  		}
   241  		return nil
   242  	case JSONBoolType:
   243  		json := val.Interface().(JSONBool)
   244  		json.data = (int(this.data) != 0)
   245  		return nil
   246  	case JSONArrayType, JSONDictType, JSONBoolPtrType, JSONArrayPtrType, JSONDictPtrType:
   247  		return ErrTypeMismatch // fmt.Errorf("JSONFloat type mismatch %s", val.Type())
   248  	case tristate.TriStateType:
   249  		if int(this.data) == 0 {
   250  			val.Set(tristate.TriStateFalseValue)
   251  		} else {
   252  			val.Set(tristate.TriStateTrueValue)
   253  		}
   254  	}
   255  	switch val.Kind() {
   256  	case reflect.Int, reflect.Uint, reflect.Int8, reflect.Uint8,
   257  		reflect.Int16, reflect.Uint16, reflect.Int32, reflect.Uint32, reflect.Int64, reflect.Uint64:
   258  		val.SetInt(int64(this.data))
   259  	case reflect.Float32, reflect.Float64:
   260  		val.SetFloat(this.data)
   261  	case reflect.Bool:
   262  		if this.data == 0 {
   263  			val.SetBool(false)
   264  		} else {
   265  			val.SetBool(true)
   266  		}
   267  	case reflect.String:
   268  		val.SetString(fmt.Sprintf("%f", this.data))
   269  	case reflect.Ptr:
   270  		if val.IsNil() {
   271  			val.Set(reflect.New(val.Type().Elem()))
   272  		}
   273  		return this.unmarshalValue(val.Elem())
   274  	case reflect.Interface:
   275  		val.Set(reflect.ValueOf(this.data))
   276  	default:
   277  		return errors.Wrapf(ErrTypeMismatch, "JSONFloat vs. %s", val.Type())
   278  	}
   279  	return nil
   280  }
   281  
   282  func (this *JSONString) unmarshalValue(val reflect.Value) error {
   283  	switch val.Type() {
   284  	case JSONStringType:
   285  		json := val.Interface().(JSONString)
   286  		json.data = this.data
   287  		return nil
   288  	case JSONStringPtrType, JSONObjectType:
   289  		val.Set(reflect.ValueOf(this))
   290  		return nil
   291  	case gotypes.TimeType:
   292  		var tm time.Time
   293  		var err error
   294  		if len(this.data) > 0 {
   295  			tm, err = timeutils.ParseTimeStr(this.data)
   296  			if err != nil {
   297  				log.Warningf("timeutils.ParseTimeStr %s %s", this.data, err)
   298  			}
   299  		} else {
   300  			tm = time.Time{}
   301  		}
   302  		val.Set(reflect.ValueOf(tm))
   303  		return nil
   304  	case JSONBoolType:
   305  		json := val.Interface().(JSONBool)
   306  		switch strings.ToLower(this.data) {
   307  		case "true", "yes", "on", "1":
   308  			json.data = true
   309  		default:
   310  			json.data = false
   311  		}
   312  		return nil
   313  	case JSONBoolPtrType:
   314  		json := val.Interface().(*JSONBool)
   315  		var data bool
   316  		switch strings.ToLower(this.data) {
   317  		case "true", "yes", "on", "1":
   318  			data = true
   319  		default:
   320  			data = false
   321  		}
   322  		if json == nil {
   323  			json = &JSONBool{data: data}
   324  		} else {
   325  			json.data = data
   326  		}
   327  		return nil
   328  	case JSONIntType, JSONFloatType, JSONArrayType, JSONDictType,
   329  		JSONBoolPtrType, JSONIntPtrType, JSONFloatPtrType, JSONArrayPtrType, JSONDictPtrType:
   330  		return ErrTypeMismatch // fmt.Errorf("JSONString type mismatch %s", val.Type())
   331  	case tristate.TriStateType:
   332  		switch strings.ToLower(this.data) {
   333  		case "true", "yes", "on", "1":
   334  			val.Set(tristate.TriStateTrueValue)
   335  		case "false", "no", "off", "0":
   336  			val.Set(tristate.TriStateFalseValue)
   337  		default:
   338  			val.Set(tristate.TriStateNoneValue)
   339  		}
   340  	}
   341  	switch val.Kind() {
   342  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   343  		if len(this.data) > 0 {
   344  			intVal, err := strconv.ParseInt(normalizeCurrencyString(this.data), 10, 64)
   345  			if err != nil {
   346  				return err
   347  			}
   348  			val.SetInt(intVal)
   349  		}
   350  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   351  		if len(this.data) > 0 {
   352  			intVal, err := strconv.ParseUint(normalizeCurrencyString(this.data), 10, 64)
   353  			if err != nil {
   354  				return err
   355  			}
   356  			val.SetUint(intVal)
   357  		}
   358  	case reflect.Float32, reflect.Float64:
   359  		if len(this.data) > 0 {
   360  			floatVal, err := strconv.ParseFloat(normalizeCurrencyString(this.data), 64)
   361  			if err != nil {
   362  				return err
   363  			}
   364  			val.SetFloat(floatVal)
   365  		}
   366  	case reflect.Bool:
   367  		val.SetBool(utils.ToBool(this.data))
   368  	case reflect.String:
   369  		val.SetString(this.data)
   370  	case reflect.Ptr:
   371  		if val.IsNil() {
   372  			val.Set(reflect.New(val.Type().Elem()))
   373  		}
   374  		return this.unmarshalValue(val.Elem())
   375  	case reflect.Interface:
   376  		val.Set(reflect.ValueOf(this.data))
   377  	case reflect.Slice:
   378  		dataLen := 1
   379  		if val.Cap() < dataLen {
   380  			newVal := reflect.MakeSlice(val.Type(), dataLen, dataLen)
   381  			val.Set(newVal)
   382  		} else if val.Len() != dataLen {
   383  			val.SetLen(dataLen)
   384  		}
   385  		return this.unmarshalValue(val.Index(0))
   386  	default:
   387  		return errors.Wrapf(ErrTypeMismatch, "JSONString vs. %s", val.Type())
   388  	}
   389  	return nil
   390  }
   391  
   392  func (this *JSONArray) unmarshalValue(val reflect.Value) error {
   393  	switch val.Type() {
   394  	case JSONArrayType:
   395  		array := val.Interface().(JSONArray)
   396  		if this.data != nil {
   397  			array.Add(this.data...)
   398  		}
   399  		val.Set(reflect.ValueOf(array))
   400  		return nil
   401  	case JSONArrayPtrType, JSONObjectType:
   402  		val.Set(reflect.ValueOf(this))
   403  		return nil
   404  	case JSONDictType, JSONIntType, JSONStringType, JSONBoolType, JSONFloatType,
   405  		JSONDictPtrType, JSONIntPtrType, JSONStringPtrType, JSONBoolPtrType, JSONFloatPtrType:
   406  		return ErrTypeMismatch //fmt.Errorf("JSONArray type mismatch %s", val.Type())
   407  	}
   408  	switch val.Kind() {
   409  	case reflect.String:
   410  		val.SetString(this.String())
   411  		return nil
   412  	case reflect.Ptr:
   413  		kind := val.Type().Elem().Kind()
   414  		if kind == reflect.Array || kind == reflect.Slice {
   415  			if val.IsNil() {
   416  				val.Set(reflect.New(val.Type().Elem()))
   417  			}
   418  			return this.unmarshalValue(val.Elem())
   419  		}
   420  		return ErrTypeMismatch // fmt.Errorf("JSONArray type mismatch %s", val.Type())
   421  	case reflect.Interface:
   422  		val.Set(reflect.ValueOf(this.data))
   423  	case reflect.Slice, reflect.Array:
   424  		if val.Kind() == reflect.Array {
   425  			if val.Len() != len(this.data) {
   426  				return ErrArrayLengthMismatch // fmt.Errorf("JSONArray length unmatch %s: %d != %d", val.Type(), val.Len(), len(this.data))
   427  			}
   428  		} else if val.Kind() == reflect.Slice {
   429  			dataLen := len(this.data)
   430  			if val.Cap() < dataLen {
   431  				newVal := reflect.MakeSlice(val.Type(), dataLen, dataLen)
   432  				val.Set(newVal)
   433  			} else if val.Len() != dataLen {
   434  				val.SetLen(dataLen)
   435  			}
   436  		}
   437  		for i, json := range this.data {
   438  			err := json.unmarshalValue(val.Index(i))
   439  			if err != nil {
   440  				return errors.Wrap(err, "unmarshalValue")
   441  			}
   442  		}
   443  	default:
   444  		return errors.Wrapf(ErrTypeMismatch, "JSONArray vs. %s", val.Type())
   445  	}
   446  	return nil
   447  }
   448  
   449  func (this *JSONDict) unmarshalValue(val reflect.Value) error {
   450  	switch val.Type() {
   451  	case JSONDictType:
   452  		dict := val.Interface().(JSONDict)
   453  		dict.Update(this)
   454  		val.Set(reflect.ValueOf(dict))
   455  		return nil
   456  	case JSONDictPtrType, JSONObjectType:
   457  		val.Set(reflect.ValueOf(this))
   458  		return nil
   459  	case JSONArrayType, JSONIntType, JSONBoolType, JSONFloatType, JSONStringType,
   460  		JSONArrayPtrType, JSONIntPtrType, JSONBoolPtrType, JSONFloatPtrType, JSONStringPtrType:
   461  		return ErrTypeMismatch // fmt.Errorf("JSONDict type mismatch %s", val.Type())
   462  	}
   463  	switch val.Kind() {
   464  	case reflect.String:
   465  		val.SetString(this.String())
   466  		return nil
   467  	case reflect.Map:
   468  		return this.unmarshalMap(val)
   469  	case reflect.Struct:
   470  		return this.unmarshalStruct(val)
   471  	case reflect.Interface:
   472  		if val.Type().Implements(gotypes.ISerializableType) {
   473  			objPtr, err := gotypes.NewSerializable(val.Type())
   474  			if err != nil {
   475  				return err
   476  			}
   477  			if objPtr == nil {
   478  				val.Set(reflect.ValueOf(this.data)) // ???
   479  				return nil
   480  			}
   481  			err = this.unmarshalValue(reflect.ValueOf(objPtr))
   482  			if err != nil {
   483  				return errors.Wrap(err, "unmarshalValue")
   484  			}
   485  			//
   486  			// XXX
   487  			//
   488  			// cannot unmarshal nested anonymous interface
   489  			// as nested anonymous interface is treated as a named field
   490  			// please use jsonutils.Deserialize to descrialize such interface
   491  			// ...
   492  			// objPtr = gotypes.Transform(val.Type(), objPtr)
   493  			//
   494  			val.Set(reflect.ValueOf(objPtr).Convert(val.Type()))
   495  		} else {
   496  			return errors.Wrapf(ErrInterfaceUnsupported, "JSONDict.unmarshalValue: %s", val.Type())
   497  		}
   498  	case reflect.Ptr:
   499  		kind := val.Type().Elem().Kind()
   500  		if kind == reflect.Struct || kind == reflect.Map {
   501  			if val.IsNil() {
   502  				newVal := reflect.New(val.Type().Elem())
   503  				val.Set(newVal)
   504  			}
   505  			return this.unmarshalValue(val.Elem())
   506  		}
   507  		fallthrough
   508  	default:
   509  		return errors.Wrapf(ErrTypeMismatch, "JSONDict.unmarshalValue: %s", val.Type())
   510  	}
   511  	return nil
   512  }
   513  
   514  func (this *JSONDict) unmarshalMap(val reflect.Value) error {
   515  	if val.IsNil() {
   516  		mapVal := reflect.MakeMap(val.Type())
   517  		val.Set(mapVal)
   518  	}
   519  	valType := val.Type()
   520  	keyType := valType.Key()
   521  	if keyType.Kind() != reflect.String {
   522  		return ErrMapKeyMustString // fmt.Errorf("map key must be string")
   523  	}
   524  	for iter := sortedmap.NewIterator(this.data); iter.HasMore(); iter.Next() {
   525  		k, vinf := iter.Get()
   526  		v := vinf.(JSONObject)
   527  		keyVal := reflect.ValueOf(k)
   528  		if keyType != keyVal.Type() {
   529  			keyVal = keyVal.Convert(keyType)
   530  		}
   531  		valVal := reflect.New(valType.Elem()).Elem()
   532  
   533  		err := v.unmarshalValue(valVal)
   534  		if err != nil {
   535  			return errors.Wrap(err, "JSONDict.unmarshalMap")
   536  		}
   537  		val.SetMapIndex(keyVal, valVal)
   538  	}
   539  	return nil
   540  }
   541  
   542  func setStructFieldAt(key string, v JSONObject, fieldValues reflectutils.SStructFieldValueSet, keyIndexMap map[string][]int, visited map[string]bool) error {
   543  	if visited == nil {
   544  		visited = make(map[string]bool)
   545  	}
   546  	if _, ok := visited[key]; ok {
   547  		// reference loop detected
   548  		return nil
   549  	}
   550  	visited[key] = true
   551  	indexes, ok := keyIndexMap[key]
   552  	if !ok || len(indexes) == 0 {
   553  		// try less strict match name
   554  		indexes = fieldValues.GetStructFieldIndexes2(key, false)
   555  		if len(indexes) == 0 {
   556  			// no field match k, ignore
   557  			return nil
   558  		}
   559  	}
   560  	for _, index := range indexes {
   561  		err := v.unmarshalValue(fieldValues[index].Value)
   562  		if err != nil {
   563  			return errors.Wrap(err, "JSONDict.unmarshalStruct")
   564  		}
   565  		depInfo, ok := fieldValues[index].Info.Tags[TAG_DEPRECATED_BY]
   566  		if ok {
   567  			err := setStructFieldAt(depInfo, v, fieldValues, keyIndexMap, visited)
   568  			if err != nil {
   569  				return errors.Wrap(err, "setStructFieldAt")
   570  			}
   571  		}
   572  	}
   573  	return nil
   574  }
   575  
   576  func (this *JSONDict) unmarshalStruct(val reflect.Value) error {
   577  	fieldValues := reflectutils.FetchStructFieldValueSetForWrite(val)
   578  	keyIndexMap := fieldValues.GetStructFieldIndexesMap()
   579  	errs := make([]error, 0)
   580  	for iter := sortedmap.NewIterator(this.data); iter.HasMore(); iter.Next() {
   581  		k, vinf := iter.Get()
   582  		v := vinf.(JSONObject)
   583  		err := setStructFieldAt(k, v, fieldValues, keyIndexMap, nil)
   584  		if err != nil {
   585  			// store error, not interrupt the process
   586  			errs = append(errs, errors.Wrapf(err, "setStructFieldAt %s: %s", k, v))
   587  		}
   588  	}
   589  	callStructAfterUnmarshal(val)
   590  	if len(errs) > 0 {
   591  		return errors.NewAggregate(errs)
   592  	} else {
   593  		return nil
   594  	}
   595  }
   596  
   597  func callStructAfterUnmarshal(val reflect.Value) {
   598  	switch val.Kind() {
   599  	case reflect.Struct:
   600  		structType := val.Type()
   601  		for i := 0; i < val.NumField(); i++ {
   602  			fieldType := structType.Field(i)
   603  			if fieldType.Anonymous {
   604  				callStructAfterUnmarshal(val.Field(i))
   605  			}
   606  		}
   607  		valPtr := val.Addr()
   608  		afterMarshalFunc := valPtr.MethodByName("AfterUnmarshal")
   609  		if afterMarshalFunc.IsValid() && !afterMarshalFunc.IsNil() {
   610  			afterMarshalFunc.Call([]reflect.Value{})
   611  		}
   612  	case reflect.Ptr:
   613  		callStructAfterUnmarshal(val.Elem())
   614  	}
   615  }