85 wiretag uint64 // tag in wire format |
85 wiretag uint64 // tag in wire format |
86 tagsize int // size of tag in wire format |
86 tagsize int // size of tag in wire format |
87 sizer sizer |
87 sizer sizer |
88 marshaler marshaler |
88 marshaler marshaler |
89 isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only) |
89 isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only) |
|
90 deref bool // dereference the pointer before operating on it; implies isptr |
90 } |
91 } |
91 |
92 |
92 var ( |
93 var ( |
93 marshalInfoMap = map[reflect.Type]*marshalInfo{} |
94 marshalInfoMap = map[reflect.Type]*marshalInfo{} |
94 marshalInfoLock sync.Mutex |
95 marshalInfoLock sync.Mutex |
318 return |
319 return |
319 } |
320 } |
320 |
321 |
321 // get oneof implementers |
322 // get oneof implementers |
322 var oneofImplementers []interface{} |
323 var oneofImplementers []interface{} |
323 if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { |
324 switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { |
|
325 case oneofFuncsIface: |
324 _, _, _, oneofImplementers = m.XXX_OneofFuncs() |
326 _, _, _, oneofImplementers = m.XXX_OneofFuncs() |
|
327 case oneofWrappersIface: |
|
328 oneofImplementers = m.XXX_OneofWrappers() |
325 } |
329 } |
326 |
330 |
327 n := t.NumField() |
331 n := t.NumField() |
328 |
332 |
329 // deal with XXX fields first |
333 // deal with XXX fields first |
405 tag, err := strconv.Atoi(tags[1]) |
409 tag, err := strconv.Atoi(tags[1]) |
406 if err != nil { |
410 if err != nil { |
407 panic("tag is not an integer") |
411 panic("tag is not an integer") |
408 } |
412 } |
409 wt := wiretype(tags[0]) |
413 wt := wiretype(tags[0]) |
|
414 if t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct { |
|
415 t = t.Elem() |
|
416 } |
410 sizer, marshaler := typeMarshaler(t, tags, false, false) |
417 sizer, marshaler := typeMarshaler(t, tags, false, false) |
|
418 var deref bool |
|
419 if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { |
|
420 t = reflect.PtrTo(t) |
|
421 deref = true |
|
422 } |
411 e = &marshalElemInfo{ |
423 e = &marshalElemInfo{ |
412 wiretag: uint64(tag)<<3 | wt, |
424 wiretag: uint64(tag)<<3 | wt, |
413 tagsize: SizeVarint(uint64(tag) << 3), |
425 tagsize: SizeVarint(uint64(tag) << 3), |
414 sizer: sizer, |
426 sizer: sizer, |
415 marshaler: marshaler, |
427 marshaler: marshaler, |
416 isptr: t.Kind() == reflect.Ptr, |
428 isptr: t.Kind() == reflect.Ptr, |
|
429 deref: deref, |
417 } |
430 } |
418 |
431 |
419 // update cache |
432 // update cache |
420 u.Lock() |
433 u.Lock() |
421 if u.extElems == nil { |
434 if u.extElems == nil { |
446 fi.setMarshaler(f, tags) |
459 fi.setMarshaler(f, tags) |
447 } |
460 } |
448 |
461 |
449 func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) { |
462 func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) { |
450 fi.field = toField(f) |
463 fi.field = toField(f) |
451 fi.wiretag = 1<<31 - 1 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire. |
464 fi.wiretag = math.MaxInt32 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire. |
452 fi.isPointer = true |
465 fi.isPointer = true |
453 fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f) |
466 fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f) |
454 fi.oneofElems = make(map[reflect.Type]*marshalElemInfo) |
467 fi.oneofElems = make(map[reflect.Type]*marshalElemInfo) |
455 |
468 |
456 ityp := f.Type // interface type |
469 ityp := f.Type // interface type |
472 tagsize: SizeVarint(uint64(tag) << 3), |
485 tagsize: SizeVarint(uint64(tag) << 3), |
473 sizer: sizer, |
486 sizer: sizer, |
474 marshaler: marshaler, |
487 marshaler: marshaler, |
475 } |
488 } |
476 } |
489 } |
477 } |
|
478 |
|
479 type oneofMessage interface { |
|
480 XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) |
|
481 } |
490 } |
482 |
491 |
483 // wiretype returns the wire encoding of the type. |
492 // wiretype returns the wire encoding of the type. |
484 func wiretype(encoding string) uint64 { |
493 func wiretype(encoding string) uint64 { |
485 switch encoding { |
494 switch encoding { |
2308 m := ptr.asPointerTo(t).Elem() // the map |
2317 m := ptr.asPointerTo(t).Elem() // the map |
2309 n := 0 |
2318 n := 0 |
2310 for _, k := range m.MapKeys() { |
2319 for _, k := range m.MapKeys() { |
2311 ki := k.Interface() |
2320 ki := k.Interface() |
2312 vi := m.MapIndex(k).Interface() |
2321 vi := m.MapIndex(k).Interface() |
2313 kaddr := toAddrPointer(&ki, false) // pointer to key |
2322 kaddr := toAddrPointer(&ki, false, false) // pointer to key |
2314 vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value |
2323 vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value |
2315 siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) |
2324 siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) |
2316 n += siz + SizeVarint(uint64(siz)) + tagsize |
2325 n += siz + SizeVarint(uint64(siz)) + tagsize |
2317 } |
2326 } |
2318 return n |
2327 return n |
2319 }, |
2328 }, |
2327 |
2336 |
2328 var nerr nonFatal |
2337 var nerr nonFatal |
2329 for _, k := range keys { |
2338 for _, k := range keys { |
2330 ki := k.Interface() |
2339 ki := k.Interface() |
2331 vi := m.MapIndex(k).Interface() |
2340 vi := m.MapIndex(k).Interface() |
2332 kaddr := toAddrPointer(&ki, false) // pointer to key |
2341 kaddr := toAddrPointer(&ki, false, false) // pointer to key |
2333 vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value |
2342 vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value |
2334 b = appendVarint(b, tag) |
2343 b = appendVarint(b, tag) |
2335 siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) |
2344 siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) |
2336 b = appendVarint(b, uint64(siz)) |
2345 b = appendVarint(b, uint64(siz)) |
2337 b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic) |
2346 b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic) |
2338 if !nerr.Merge(err) { |
2347 if !nerr.Merge(err) { |
2397 // We don't skip extensions that have an encoded form set, |
2406 // We don't skip extensions that have an encoded form set, |
2398 // because the extension value may have been mutated after |
2407 // because the extension value may have been mutated after |
2399 // the last time this function was called. |
2408 // the last time this function was called. |
2400 ei := u.getExtElemInfo(e.desc) |
2409 ei := u.getExtElemInfo(e.desc) |
2401 v := e.value |
2410 v := e.value |
2402 p := toAddrPointer(&v, ei.isptr) |
2411 p := toAddrPointer(&v, ei.isptr, ei.deref) |
2403 n += ei.sizer(p, ei.tagsize) |
2412 n += ei.sizer(p, ei.tagsize) |
2404 } |
2413 } |
2405 mu.Unlock() |
2414 mu.Unlock() |
2406 return n |
2415 return n |
2407 } |
2416 } |
2432 // because the extension value may have been mutated after |
2441 // because the extension value may have been mutated after |
2433 // the last time this function was called. |
2442 // the last time this function was called. |
2434 |
2443 |
2435 ei := u.getExtElemInfo(e.desc) |
2444 ei := u.getExtElemInfo(e.desc) |
2436 v := e.value |
2445 v := e.value |
2437 p := toAddrPointer(&v, ei.isptr) |
2446 p := toAddrPointer(&v, ei.isptr, ei.deref) |
2438 b, err = ei.marshaler(b, p, ei.wiretag, deterministic) |
2447 b, err = ei.marshaler(b, p, ei.wiretag, deterministic) |
2439 if !nerr.Merge(err) { |
2448 if !nerr.Merge(err) { |
2440 return b, err |
2449 return b, err |
2441 } |
2450 } |
2442 } |
2451 } |
2463 // because the extension value may have been mutated after |
2472 // because the extension value may have been mutated after |
2464 // the last time this function was called. |
2473 // the last time this function was called. |
2465 |
2474 |
2466 ei := u.getExtElemInfo(e.desc) |
2475 ei := u.getExtElemInfo(e.desc) |
2467 v := e.value |
2476 v := e.value |
2468 p := toAddrPointer(&v, ei.isptr) |
2477 p := toAddrPointer(&v, ei.isptr, ei.deref) |
2469 b, err = ei.marshaler(b, p, ei.wiretag, deterministic) |
2478 b, err = ei.marshaler(b, p, ei.wiretag, deterministic) |
2470 if !nerr.Merge(err) { |
2479 if !nerr.Merge(err) { |
2471 return b, err |
2480 return b, err |
2472 } |
2481 } |
2473 } |
2482 } |
2508 // because the extension value may have been mutated after |
2517 // because the extension value may have been mutated after |
2509 // the last time this function was called. |
2518 // the last time this function was called. |
2510 |
2519 |
2511 ei := u.getExtElemInfo(e.desc) |
2520 ei := u.getExtElemInfo(e.desc) |
2512 v := e.value |
2521 v := e.value |
2513 p := toAddrPointer(&v, ei.isptr) |
2522 p := toAddrPointer(&v, ei.isptr, ei.deref) |
2514 n += ei.sizer(p, 1) // message, tag = 3 (size=1) |
2523 n += ei.sizer(p, 1) // message, tag = 3 (size=1) |
2515 } |
2524 } |
2516 mu.Unlock() |
2525 mu.Unlock() |
2517 return n |
2526 return n |
2518 } |
2527 } |
2551 // because the extension value may have been mutated after |
2560 // because the extension value may have been mutated after |
2552 // the last time this function was called. |
2561 // the last time this function was called. |
2553 |
2562 |
2554 ei := u.getExtElemInfo(e.desc) |
2563 ei := u.getExtElemInfo(e.desc) |
2555 v := e.value |
2564 v := e.value |
2556 p := toAddrPointer(&v, ei.isptr) |
2565 p := toAddrPointer(&v, ei.isptr, ei.deref) |
2557 b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) |
2566 b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) |
2558 if !nerr.Merge(err) { |
2567 if !nerr.Merge(err) { |
2559 return b, err |
2568 return b, err |
2560 } |
2569 } |
2561 b = append(b, 1<<3|WireEndGroup) |
2570 b = append(b, 1<<3|WireEndGroup) |
2589 // because the extension value may have been mutated after |
2598 // because the extension value may have been mutated after |
2590 // the last time this function was called. |
2599 // the last time this function was called. |
2591 |
2600 |
2592 ei := u.getExtElemInfo(e.desc) |
2601 ei := u.getExtElemInfo(e.desc) |
2593 v := e.value |
2602 v := e.value |
2594 p := toAddrPointer(&v, ei.isptr) |
2603 p := toAddrPointer(&v, ei.isptr, ei.deref) |
2595 b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) |
2604 b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) |
2596 b = append(b, 1<<3|WireEndGroup) |
2605 b = append(b, 1<<3|WireEndGroup) |
2597 if !nerr.Merge(err) { |
2606 if !nerr.Merge(err) { |
2598 return b, err |
2607 return b, err |
2599 } |
2608 } |
2619 // because the extension value may have been mutated after |
2628 // because the extension value may have been mutated after |
2620 // the last time this function was called. |
2629 // the last time this function was called. |
2621 |
2630 |
2622 ei := u.getExtElemInfo(e.desc) |
2631 ei := u.getExtElemInfo(e.desc) |
2623 v := e.value |
2632 v := e.value |
2624 p := toAddrPointer(&v, ei.isptr) |
2633 p := toAddrPointer(&v, ei.isptr, ei.deref) |
2625 n += ei.sizer(p, ei.tagsize) |
2634 n += ei.sizer(p, ei.tagsize) |
2626 } |
2635 } |
2627 return n |
2636 return n |
2628 } |
2637 } |
2629 |
2638 |
2654 // because the extension value may have been mutated after |
2663 // because the extension value may have been mutated after |
2655 // the last time this function was called. |
2664 // the last time this function was called. |
2656 |
2665 |
2657 ei := u.getExtElemInfo(e.desc) |
2666 ei := u.getExtElemInfo(e.desc) |
2658 v := e.value |
2667 v := e.value |
2659 p := toAddrPointer(&v, ei.isptr) |
2668 p := toAddrPointer(&v, ei.isptr, ei.deref) |
2660 b, err = ei.marshaler(b, p, ei.wiretag, deterministic) |
2669 b, err = ei.marshaler(b, p, ei.wiretag, deterministic) |
2661 if !nerr.Merge(err) { |
2670 if !nerr.Merge(err) { |
2662 return b, err |
2671 return b, err |
2663 } |
2672 } |
2664 } |
2673 } |