github.com/thiagoyeds/go-cloud@v0.26.0/docstore/driver/codec.go (about) 1 // Copyright 2019 The Go Cloud Development Kit Authors 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 // https://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 // TODO(jba): support struct tags. 16 // TODO(jba): for efficiency, enable encoding of only a subset of field paths. 17 18 package driver 19 20 import ( 21 "encoding" 22 "fmt" 23 "reflect" 24 "strconv" 25 26 "gocloud.dev/docstore/internal/fields" 27 "gocloud.dev/internal/gcerr" 28 "google.golang.org/protobuf/proto" 29 ) 30 31 var ( 32 binaryMarshalerType = reflect.TypeOf((*encoding.BinaryMarshaler)(nil)).Elem() 33 binaryUnmarshalerType = reflect.TypeOf((*encoding.BinaryUnmarshaler)(nil)).Elem() 34 textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() 35 textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() 36 protoMessageType = reflect.TypeOf((*proto.Message)(nil)).Elem() 37 ) 38 39 // An Encoder encodes Go values in some other form (e.g. JSON, protocol buffers). 40 // The encoding protocol is designed to avoid losing type information by passing 41 // values using interface{}. An Encoder is responsible for storing the value 42 // it is encoding. 43 // 44 // Because all drivers must support the same set of values, the encoding methods 45 // (with the exception of EncodeStruct) do not return errors. EncodeStruct is special 46 // because it is an escape hatch for arbitrary structs, not all of which may be 47 // encodable. 48 type Encoder interface { 49 // These methods all encode and store a single Go value. 50 EncodeNil() 51 EncodeBool(bool) 52 EncodeString(string) 53 EncodeInt(int64) 54 EncodeUint(uint64) 55 EncodeFloat(float64) 56 EncodeBytes([]byte) 57 58 // EncodeList is called when a slice or array is encountered (except for a 59 // []byte, which is handled by EncodeBytes). Its argument is the length of the 60 // slice or array. The encoding algorithm will call the returned Encoder that 61 // many times to encode the successive values of the list. After each such call, 62 // ListIndex will be called with the index of the element just encoded. 63 // 64 // For example, []string{"a", "b"} will result in these calls: 65 // enc2 := enc.EncodeList(2) 66 // enc2.EncodeString("a") 67 // enc2.ListIndex(0) 68 // enc2.EncodeString("b") 69 // enc2.ListIndex(1) 70 EncodeList(n int) Encoder 71 ListIndex(i int) 72 73 // EncodeMap is called when a map is encountered. Its argument is the number of 74 // fields in the map. The encoding algorithm will call the returned Encoder that 75 // many times to encode the successive values of the map. After each such call, 76 // MapKey will be called with the key of the element just encoded. 77 // 78 // For example, map[string}int{"A": 1, "B": 2} will result in these calls: 79 // enc2 := enc.EncodeMap(2) 80 // enc2.EncodeInt(1) 81 // enc2.MapKey("A") 82 // enc2.EncodeInt(2) 83 // enc2.MapKey("B") 84 // 85 // EncodeMap is also called for structs. The map then consists of the exported 86 // fields of the struct. For struct{A, B int}{1, 2}, if EncodeStruct returns 87 // false, the same sequence of calls as above will occur. 88 EncodeMap(n int) Encoder 89 MapKey(string) 90 91 // If the encoder wants to encode a value in a special way it should do so here 92 // and return true along with any error from the encoding. Otherwise, it should 93 // return false. 94 EncodeSpecial(v reflect.Value) (bool, error) 95 } 96 97 // Encode encodes the value using the given Encoder. It traverses the value, 98 // iterating over arrays, slices, maps and the exported fields of structs. If it 99 // encounters a non-nil pointer, it encodes the value that it points to. 100 // Encode treats a few interfaces specially: 101 // 102 // If the value implements encoding.BinaryMarshaler, Encode invokes MarshalBinary 103 // on it and encodes the resulting byte slice. 104 // 105 // If the value implements encoding.TextMarshaler, Encode invokes MarshalText on it 106 // and encodes the resulting string. 107 // 108 // If the value implements proto.Message, Encode invokes proto.Marshal on it and encodes 109 // the resulting byte slice. Here proto is the package "google.golang.org/protobuf/proto". 110 // 111 // Not every map key type can be encoded. Only strings, integers (signed or 112 // unsigned), and types that implement encoding.TextMarshaler are permitted as map 113 // keys. These restrictions match exactly those of the encoding/json package. 114 func Encode(v reflect.Value, e Encoder) error { 115 return wrap(encode(v, e), gcerr.InvalidArgument) 116 } 117 118 func encode(v reflect.Value, enc Encoder) error { 119 if !v.IsValid() { 120 enc.EncodeNil() 121 return nil 122 } 123 done, err := enc.EncodeSpecial(v) 124 if done { 125 return err 126 } 127 if v.Type().Implements(binaryMarshalerType) { 128 bytes, err := v.Interface().(encoding.BinaryMarshaler).MarshalBinary() 129 if err != nil { 130 return err 131 } 132 enc.EncodeBytes(bytes) 133 return nil 134 } 135 if v.Type().Implements(protoMessageType) { 136 if v.IsNil() { 137 enc.EncodeNil() 138 } else { 139 bytes, err := proto.Marshal(v.Interface().(proto.Message)) 140 if err != nil { 141 return err 142 } 143 enc.EncodeBytes(bytes) 144 } 145 return nil 146 } 147 if reflect.PtrTo(v.Type()).Implements(protoMessageType) { 148 bytes, err := proto.Marshal(v.Addr().Interface().(proto.Message)) 149 if err != nil { 150 return err 151 } 152 enc.EncodeBytes(bytes) 153 return nil 154 } 155 if v.Type().Implements(textMarshalerType) { 156 bytes, err := v.Interface().(encoding.TextMarshaler).MarshalText() 157 if err != nil { 158 return err 159 } 160 enc.EncodeString(string(bytes)) 161 return nil 162 } 163 switch v.Kind() { 164 case reflect.Bool: 165 enc.EncodeBool(v.Bool()) 166 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 167 enc.EncodeInt(v.Int()) 168 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 169 enc.EncodeUint(v.Uint()) 170 case reflect.Float32, reflect.Float64: 171 enc.EncodeFloat(v.Float()) 172 case reflect.String: 173 enc.EncodeString(v.String()) 174 case reflect.Slice: 175 if v.IsNil() { 176 enc.EncodeNil() 177 return nil 178 } 179 fallthrough 180 case reflect.Array: 181 return encodeList(v, enc) 182 case reflect.Map: 183 return encodeMap(v, enc) 184 case reflect.Ptr: 185 if v.IsNil() { 186 enc.EncodeNil() 187 return nil 188 } 189 return encode(v.Elem(), enc) 190 case reflect.Interface: 191 if v.IsNil() { 192 enc.EncodeNil() 193 return nil 194 } 195 return encode(v.Elem(), enc) 196 197 case reflect.Struct: 198 fields, err := fieldCache.Fields(v.Type()) 199 if err != nil { 200 return err 201 } 202 return encodeStructWithFields(v, fields, enc) 203 204 default: 205 return gcerr.Newf(gcerr.InvalidArgument, nil, "cannot encode type %s", v.Type()) 206 } 207 return nil 208 } 209 210 // Encode an array or non-nil slice. 211 func encodeList(v reflect.Value, enc Encoder) error { 212 // Byte slices encode specially. 213 if v.Type().Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 { 214 enc.EncodeBytes(v.Bytes()) 215 return nil 216 } 217 n := v.Len() 218 enc2 := enc.EncodeList(n) 219 for i := 0; i < n; i++ { 220 if err := encode(v.Index(i), enc2); err != nil { 221 return err 222 } 223 enc2.ListIndex(i) 224 } 225 return nil 226 } 227 228 // Encode a map. 229 func encodeMap(v reflect.Value, enc Encoder) error { 230 if v.IsNil() { 231 enc.EncodeNil() 232 return nil 233 } 234 keys := v.MapKeys() 235 enc2 := enc.EncodeMap(len(keys)) 236 for _, k := range keys { 237 sk, err := stringifyMapKey(k) 238 if err != nil { 239 return err 240 } 241 if err := encode(v.MapIndex(k), enc2); err != nil { 242 return err 243 } 244 enc2.MapKey(sk) 245 } 246 return nil 247 } 248 249 // k is the key of a map. Encode it as a string. 250 // Only strings, integers (signed or unsigned), and types that implement 251 // encoding.TextMarshaler are supported. 252 func stringifyMapKey(k reflect.Value) (string, error) { 253 // This is basically reflectWithString.resolve, from encoding/json/encode.go. 254 if k.Kind() == reflect.String { 255 return k.String(), nil 256 } 257 if tm, ok := k.Interface().(encoding.TextMarshaler); ok { 258 b, err := tm.MarshalText() 259 if err != nil { 260 return "", err 261 } 262 return string(b), nil 263 } 264 switch k.Kind() { 265 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 266 return strconv.FormatInt(k.Int(), 10), nil 267 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 268 return strconv.FormatUint(k.Uint(), 10), nil 269 default: 270 return "", gcerr.Newf(gcerr.InvalidArgument, nil, "cannot encode key %v of type %s", k, k.Type()) 271 } 272 } 273 274 func encodeStructWithFields(v reflect.Value, fields fields.List, e Encoder) error { 275 e2 := e.EncodeMap(len(fields)) 276 for _, f := range fields { 277 fv, ok := fieldByIndex(v, f.Index) 278 if !ok { 279 // if !ok, then f is a field in an embedded pointer to struct, and that embedded pointer 280 // is nil in v. In other words, the field exists in the struct type, but not this particular 281 // struct value. So we just ignore it. 282 continue 283 } 284 if f.ParsedTag.(tagOptions).omitEmpty && IsEmptyValue(fv) { 285 continue 286 } 287 if err := encode(fv, e2); err != nil { 288 return err 289 } 290 e2.MapKey(f.Name) 291 } 292 return nil 293 } 294 295 // fieldByIndex retrieves the field of v at the given index if present. 296 // v must be a struct. index must refer to a valid field of v's type. 297 // The second return value is false if there is a nil embedded pointer 298 // along the path denoted by index. 299 // 300 // From encoding/json/encode.go. 301 func fieldByIndex(v reflect.Value, index []int) (reflect.Value, bool) { 302 for _, i := range index { 303 if v.Kind() == reflect.Ptr { 304 if v.IsNil() { 305 return reflect.Value{}, false 306 } 307 v = v.Elem() 308 } 309 v = v.Field(i) 310 } 311 return v, true 312 } 313 314 //////////////////////////////////////////////////////////////// 315 316 // TODO(jba): consider a fast path: if we are decoding into a struct, assume the same struct 317 // was used to encode. Then we can build a map from field names to functions, where each 318 // function avoids all the tests of Decode and contains just the code for setting the field. 319 320 // TODO(jba): provide a way to override the check on missing fields. 321 322 // A Decoder decodes data that was produced by Encode back into Go values. 323 // Each Decoder instance is responsible for decoding one value. 324 type Decoder interface { 325 // The AsXXX methods each report whether the value being decoded can be represented as 326 // a particular Go type. If so, the method should return the value as that type, and true; 327 // otherwise it should return the zero value and false. 328 AsString() (string, bool) 329 AsInt() (int64, bool) 330 AsUint() (uint64, bool) 331 AsFloat() (float64, bool) 332 AsBytes() ([]byte, bool) 333 AsBool() (bool, bool) 334 AsNull() bool 335 336 // ListLen should return the length of the value being decoded and true, if the 337 // value can be decoded into a slice or array. Otherwise, ListLen should return 338 // (0, false). 339 ListLen() (int, bool) 340 341 // If ListLen returned true, then DecodeList will be called. It should iterate 342 // over the value being decoded in sequence from index 0, invoking the callback 343 // for each element with the element's index and a Decoder for the element. 344 // If the callback returns false, DecodeList should return immediately. 345 DecodeList(func(int, Decoder) bool) 346 347 // MapLen should return the number of fields of the value being decoded and true, 348 // if the value can be decoded into a map or struct. Otherwise, it should return 349 // (0, false). 350 MapLen() (int, bool) 351 352 // DecodeMap iterates over the fields of the value being decoded, invoke the 353 // callback on each with field name, a Decoder for the field value, and a bool 354 // to indicate whether or not to use exact match for the field names. It will 355 // be called when MapLen returns true or decoding a struct. If the callback 356 // returns false, DecodeMap should return immediately. 357 DecodeMap(func(string, Decoder, bool) bool) 358 359 // AsInterface should decode the value into the Go value that best represents it. 360 AsInterface() (interface{}, error) 361 362 // If the decoder wants to decode a value in a special way it should do so here 363 // and return true, the decoded value, and any error from the decoding. 364 // Otherwise, it should return false. 365 AsSpecial(reflect.Value) (bool, interface{}, error) 366 367 // String should return a human-readable representation of the Decoder, for error messages. 368 String() string 369 } 370 371 // Decode decodes the value held in the Decoder d into v. 372 // Decode creates slices, maps and pointer elements as needed. 373 // It treats values that implement encoding.BinaryUnmarshaler, 374 // encoding.TextUnmarshaler and proto.Message specially; see Encode. 375 func Decode(v reflect.Value, d Decoder) error { 376 return wrap(decode(v, d), gcerr.InvalidArgument) 377 } 378 379 func decode(v reflect.Value, d Decoder) error { 380 if !v.CanSet() { 381 return fmt.Errorf("while decoding: cannot set %+v", v) 382 } 383 // A Null value sets anything nullable to nil. 384 // If the value isn't nullable, we keep going. 385 // TODO(jba): should we treat decoding a null into a non-nullable as an error, or 386 // ignore it like encoding/json does? 387 if d.AsNull() { 388 switch v.Kind() { 389 case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: 390 v.Set(reflect.Zero(v.Type())) 391 return nil 392 } 393 } 394 395 if done, val, err := d.AsSpecial(v); done { 396 if err != nil { 397 return err 398 } 399 if reflect.TypeOf(val).AssignableTo(v.Type()) { 400 v.Set(reflect.ValueOf(val)) 401 return nil 402 } 403 return decodingError(v, d) 404 } 405 406 // Handle implemented interfaces first. 407 if reflect.PtrTo(v.Type()).Implements(binaryUnmarshalerType) { 408 if b, ok := d.AsBytes(); ok { 409 return v.Addr().Interface().(encoding.BinaryUnmarshaler).UnmarshalBinary(b) 410 } 411 return decodingError(v, d) 412 } 413 if reflect.PtrTo(v.Type()).Implements(protoMessageType) { 414 if b, ok := d.AsBytes(); ok { 415 return proto.Unmarshal(b, v.Addr().Interface().(proto.Message)) 416 } 417 return decodingError(v, d) 418 } 419 if reflect.PtrTo(v.Type()).Implements(textUnmarshalerType) { 420 if s, ok := d.AsString(); ok { 421 return v.Addr().Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(s)) 422 } 423 return decodingError(v, d) 424 } 425 426 switch v.Kind() { 427 case reflect.Bool: 428 if b, ok := d.AsBool(); ok { 429 v.SetBool(b) 430 return nil 431 } 432 433 case reflect.String: 434 if s, ok := d.AsString(); ok { 435 v.SetString(s) 436 return nil 437 } 438 439 case reflect.Float32, reflect.Float64: 440 if f, ok := d.AsFloat(); ok { 441 v.SetFloat(f) 442 return nil 443 } 444 445 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 446 i, ok := d.AsInt() 447 if !ok { 448 // Accept a floating-point number with integral value. 449 f, ok := d.AsFloat() 450 if !ok { 451 return decodingError(v, d) 452 } 453 i = int64(f) 454 if float64(i) != f { 455 return gcerr.Newf(gcerr.InvalidArgument, nil, "float %f does not fit into %s", f, v.Type()) 456 } 457 } 458 if v.OverflowInt(i) { 459 return overflowError(i, v.Type()) 460 } 461 v.SetInt(i) 462 return nil 463 464 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 465 u, ok := d.AsUint() 466 if !ok { 467 // Accept a floating-point number with integral value. 468 f, ok := d.AsFloat() 469 if !ok { 470 return decodingError(v, d) 471 } 472 u = uint64(f) 473 if float64(u) != f { 474 return gcerr.Newf(gcerr.InvalidArgument, nil, "float %f does not fit into %s", f, v.Type()) 475 } 476 } 477 if v.OverflowUint(u) { 478 return overflowError(u, v.Type()) 479 } 480 v.SetUint(u) 481 return nil 482 483 case reflect.Slice, reflect.Array: 484 return decodeList(v, d) 485 486 case reflect.Map: 487 return decodeMap(v, d) 488 489 case reflect.Ptr: 490 // If the pointer is nil, set it to a zero value. 491 if v.IsNil() { 492 v.Set(reflect.New(v.Type().Elem())) 493 } 494 return decode(v.Elem(), d) 495 496 case reflect.Struct: 497 return decodeStruct(v, d) 498 499 case reflect.Interface: 500 if v.NumMethod() == 0 { // empty interface 501 // If v holds a pointer, set the pointer. 502 if !v.IsNil() && v.Elem().Kind() == reflect.Ptr { 503 return decode(v.Elem(), d) 504 } 505 // Otherwise, create a fresh value. 506 x, err := d.AsInterface() 507 if err != nil { 508 return err 509 } 510 v.Set(reflect.ValueOf(x)) 511 return nil 512 } 513 // Any other kind of interface is an error??? 514 } 515 516 return decodingError(v, d) 517 } 518 519 func decodeList(v reflect.Value, d Decoder) error { 520 // If we're decoding into a byte slice or array, and the decoded value 521 // supports that, then do the decoding. 522 if v.Type().Elem().Kind() == reflect.Uint8 { 523 if b, ok := d.AsBytes(); ok { 524 if v.Kind() == reflect.Slice { 525 v.SetBytes(b) 526 return nil 527 } 528 // It's an array; copy the data in. 529 err := prepareLength(v, len(b)) 530 if err != nil { 531 return err 532 } 533 reflect.Copy(v, reflect.ValueOf(b)) 534 return nil 535 } 536 // Fall through to decode the []byte as an ordinary slice. 537 } 538 dlen, ok := d.ListLen() 539 if !ok { 540 return decodingError(v, d) 541 } 542 err := prepareLength(v, dlen) 543 if err != nil { 544 return err 545 } 546 d.DecodeList(func(i int, vd Decoder) bool { 547 if err != nil || i >= dlen { 548 return false 549 } 550 err = decode(v.Index(i), vd) 551 return err == nil 552 }) 553 return err 554 } 555 556 // v must be a slice or array. We want it to be of length wantLen. Prepare it as 557 // necessary (details described in the code below), and return its resulting length. 558 // If an array is too short, return an error. This behavior differs from 559 // encoding/json, which just populates a short array with whatever it can and drops 560 // the rest. That can lose data. 561 func prepareLength(v reflect.Value, wantLen int) error { 562 vLen := v.Len() 563 if v.Kind() == reflect.Slice { 564 // Construct a slice of the right size, avoiding allocation if possible. 565 switch { 566 case vLen < wantLen: // v too short 567 if v.Cap() >= wantLen { // extend its length if there's room 568 v.SetLen(wantLen) 569 } else { // else make a new one 570 v.Set(reflect.MakeSlice(v.Type(), wantLen, wantLen)) 571 } 572 case vLen > wantLen: // v too long; truncate it 573 v.SetLen(wantLen) 574 } 575 } else { // array 576 switch { 577 case vLen < wantLen: // v too short 578 return gcerr.Newf(gcerr.InvalidArgument, nil, "array length %d is too short for incoming list of length %d", 579 vLen, wantLen) 580 case vLen > wantLen: // v too long; set extra elements to zero 581 z := reflect.Zero(v.Type().Elem()) 582 for i := wantLen; i < vLen; i++ { 583 v.Index(i).Set(z) 584 } 585 } 586 } 587 return nil 588 } 589 590 // Since a map value is not settable via reflection, this function always creates a 591 // new element for each corresponding map key. Existing values of v are overwritten. 592 // This happens even if the map value is something like a pointer to a struct, where 593 // we could in theory populate the existing struct value instead of discarding it. 594 // This behavior matches encoding/json. 595 func decodeMap(v reflect.Value, d Decoder) error { 596 mapLen, ok := d.MapLen() 597 if !ok { 598 return decodingError(v, d) 599 } 600 t := v.Type() 601 if v.IsNil() { 602 v.Set(reflect.MakeMapWithSize(t, mapLen)) 603 } 604 et := t.Elem() 605 var err error 606 kt := v.Type().Key() 607 d.DecodeMap(func(key string, vd Decoder, _ bool) bool { 608 if err != nil { 609 return false 610 } 611 el := reflect.New(et).Elem() 612 err = decode(el, vd) 613 if err != nil { 614 return false 615 } 616 vk, e := unstringifyMapKey(key, kt) 617 if e != nil { 618 err = e 619 return false 620 } 621 v.SetMapIndex(vk, el) 622 return err == nil 623 }) 624 return err 625 } 626 627 // Given a map key encoded as a string, and the type of the map key, convert the key 628 // into the type. 629 // For example, if we are decoding the key "3" for a map[int]interface{}, then key is "3" 630 // and keyType is reflect.Int. 631 func unstringifyMapKey(key string, keyType reflect.Type) (reflect.Value, error) { 632 // This code is mostly from the middle of decodeState.object in encoding/json/decode.go. 633 // Except for literalStore, which I don't understand. 634 // TODO(jba): understand literalStore. 635 switch { 636 case keyType.Kind() == reflect.String: 637 return reflect.ValueOf(key).Convert(keyType), nil 638 case reflect.PtrTo(keyType).Implements(textUnmarshalerType): 639 tu := reflect.New(keyType) 640 if err := tu.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(key)); err != nil { 641 return reflect.Value{}, err 642 } 643 return tu.Elem(), nil 644 case keyType.Kind() == reflect.Interface && keyType.NumMethod() == 0: 645 // TODO: remove this case? encoding/json doesn't support it. 646 return reflect.ValueOf(key), nil 647 default: 648 switch keyType.Kind() { 649 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 650 n, err := strconv.ParseInt(key, 10, 64) 651 if err != nil { 652 return reflect.Value{}, err 653 } 654 if reflect.Zero(keyType).OverflowInt(n) { 655 return reflect.Value{}, overflowError(n, keyType) 656 } 657 return reflect.ValueOf(n).Convert(keyType), nil 658 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 659 n, err := strconv.ParseUint(key, 10, 64) 660 if err != nil { 661 return reflect.Value{}, err 662 } 663 if reflect.Zero(keyType).OverflowUint(n) { 664 return reflect.Value{}, overflowError(n, keyType) 665 } 666 return reflect.ValueOf(n).Convert(keyType), nil 667 default: 668 return reflect.Value{}, gcerr.Newf(gcerr.InvalidArgument, nil, "invalid key type %s", keyType) 669 } 670 } 671 } 672 673 func decodeStruct(v reflect.Value, d Decoder) error { 674 fs, err := fieldCache.Fields(v.Type()) 675 if err != nil { 676 return err 677 } 678 d.DecodeMap(func(key string, d2 Decoder, exactMatch bool) bool { 679 if err != nil { 680 return false 681 } 682 var f *fields.Field 683 if exactMatch { 684 f = fs.MatchExact(key) 685 } else { 686 f = fs.MatchFold(key) 687 } 688 if f == nil { 689 err = gcerr.Newf(gcerr.InvalidArgument, nil, "no field matching %q in %s", key, v.Type()) 690 return false 691 } 692 fv, ok := fieldByIndexCreate(v, f.Index) 693 if !ok { 694 err = gcerr.Newf(gcerr.InvalidArgument, nil, 695 "setting field %q in %s: cannot create embedded pointer field of unexported type", 696 key, v.Type()) 697 return false 698 } 699 err = decode(fv, d2) 700 return err == nil 701 }) 702 return err 703 } 704 705 // fieldByIndexCreate retrieves the the field of v at the given index if present, 706 // creating embedded struct pointers where necessary. 707 // v must be a struct. index must refer to a valid field of v's type. 708 // The second return value is false If there is a nil embedded pointer of unexported 709 // type along the path denoted by index. (We cannot create such pointers.) 710 func fieldByIndexCreate(v reflect.Value, index []int) (reflect.Value, bool) { 711 for _, i := range index { 712 if v.Kind() == reflect.Ptr { 713 if v.IsNil() { 714 if !v.CanSet() { 715 return reflect.Value{}, false 716 } 717 v.Set(reflect.New(v.Type().Elem())) 718 } 719 v = v.Elem() 720 } 721 v = v.Field(i) 722 } 723 return v, true 724 } 725 726 func decodingError(v reflect.Value, d Decoder) error { 727 return gcerr.New(gcerr.InvalidArgument, nil, 2, fmt.Sprintf("cannot set type %s to %v", v.Type(), d)) 728 } 729 730 func overflowError(x interface{}, t reflect.Type) error { 731 return gcerr.New(gcerr.InvalidArgument, nil, 2, fmt.Sprintf("value %v overflows type %s", x, t)) 732 } 733 734 func wrap(err error, code gcerr.ErrorCode) error { 735 if _, ok := err.(*gcerr.Error); !ok && err != nil { 736 err = gcerr.New(code, err, 2, err.Error()) 737 } 738 return err 739 } 740 741 var fieldCache = fields.NewCache(parseTag, nil, nil) 742 743 // IsEmptyValue returns whether or not v is a zero value of its type. 744 // Copied from encoding/json, go 1.12. 745 func IsEmptyValue(v reflect.Value) bool { 746 switch k := v.Kind(); k { 747 case reflect.Array, reflect.Map, reflect.Slice, reflect.String: 748 return v.Len() == 0 749 case reflect.Bool: 750 return !v.Bool() 751 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 752 return v.Int() == 0 753 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 754 return v.Uint() == 0 755 case reflect.Float32, reflect.Float64: 756 return v.Float() == 0 757 case reflect.Interface, reflect.Ptr: 758 return v.IsNil() 759 } 760 return false 761 } 762 763 // Options for struct tags. 764 type tagOptions struct { 765 omitEmpty bool // do not encode value if empty 766 } 767 768 // parseTag interprets docstore struct field tags. 769 func parseTag(t reflect.StructTag) (name string, keep bool, other interface{}, err error) { 770 var opts []string 771 name, keep, opts = fields.ParseStandardTag("docstore", t) 772 tagOpts := tagOptions{} 773 for _, opt := range opts { 774 switch opt { 775 case "omitempty": 776 tagOpts.omitEmpty = true 777 default: 778 return "", false, nil, gcerr.Newf(gcerr.InvalidArgument, nil, "unknown tag option: %q", opt) 779 } 780 } 781 return name, keep, tagOpts, nil 782 }