unmarshal.go 18 KB

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