decodeStruct decodes a struct value.
(ods *objectDecodeState, obj reflect.Value, encoded *wire.Struct)
| 381 | |
| 382 | // decodeStruct decodes a struct value. |
| 383 | func (ds *decodeState) decodeStruct(ods *objectDecodeState, obj reflect.Value, encoded *wire.Struct) { |
| 384 | if encoded.TypeID == 0 { |
| 385 | // Allow anonymous empty structs, but only if the encoded |
| 386 | // object also has no fields. |
| 387 | if encoded.Fields() == 0 && obj.NumField() == 0 { |
| 388 | return |
| 389 | } |
| 390 | |
| 391 | // Propagate an error. |
| 392 | Failf("empty struct on wire %#v has field mismatch with type %q", encoded, obj.Type().Name()) |
| 393 | } |
| 394 | |
| 395 | // Lookup the object type. |
| 396 | rte := ds.types.Lookup(typeID(encoded.TypeID), obj.Type()) |
| 397 | ods.typ = typeID(encoded.TypeID) |
| 398 | |
| 399 | // Invoke the loader. |
| 400 | od := objectDecoder{ |
| 401 | ds: ds, |
| 402 | ods: ods, |
| 403 | rte: rte, |
| 404 | encoded: encoded, |
| 405 | } |
| 406 | ds.stats.start(ods.typ) |
| 407 | defer ds.stats.done() |
| 408 | if sl, ok := obj.Addr().Interface().(SaverLoader); ok { |
| 409 | // Note: may be a registered empty struct which does not |
| 410 | // implement the saver/loader interfaces. |
| 411 | sl.StateLoad(ds.ctx, Source{internal: od}) |
| 412 | } |
| 413 | } |
| 414 | |
| 415 | // decodeMap decodes a map value. |
| 416 | func (ds *decodeState) decodeMap(ods *objectDecodeState, obj reflect.Value, encoded *wire.Map) { |