func rewriteValue(rewrite rewriteFunc, src, dst reflect.Value) bool {
	if rewrite(src, dst) {
		return true
	}

	// Recursive step
	var g rewriteGroup
	t := src.Type()
	switch src.Kind() {

	case reflect.Array:
		if isTerminalKind(t) {
			return false
		}
		for i := 0; i < src.Len(); i++ {
			src__, dst__ := src.Index(i), dst.Index(i)
			g.Add(1)
			go func() {
				defer g.Done()
				if rewriteValue(rewrite, src__, dst__) {
					g.Lock()
					g.Change = true
					g.Unlock()
				} else {
					dst__.Set(src__)
				}
			}()
		}
		g.Wait()
		return g.Change

	case reflect.Slice:
		if src.IsNil() || isTerminalKind(t) {
			return false
		}
		dst.Set(reflect.MakeSlice(t, src.Len(), src.Len()))
		for i := 0; i < src.Len(); i++ {
			src__, dst__ := src.Index(i), dst.Index(i)
			g.Add(1)
			go func() {
				defer g.Done()
				if rewriteValue(rewrite, src__, dst__) {
					g.Lock()
					g.Change = true
					g.Unlock()
				} else {
					dst__.Set(src__)
				}
			}()
		}
		g.Wait()
		return g.Change

	case reflect.Map:
		// For now, we do not rewrite map key values
		if src.IsNil() || isTerminalKind(t) {
			return false
		}
		dst.Set(reflect.MakeMap(t))
		for _, mk := range src.MapKeys() {
			src__ := src.MapIndex(mk)
			dst__ := reflect.New(t.Elem()).Elem()
			g.Add(1)
			go func() {
				defer g.Done()
				if rewriteValue(rewrite, src__, dst__) {
					dst.SetMapIndex(mk, dst__)
					g.Lock()
					g.Change = true
					g.Unlock()
				} else {
					dst.SetMapIndex(mk, src__)
				}
			}()
		}
		g.Wait()
		return g.Change

	case reflect.Ptr:
		if src.IsNil() || isTerminalKind(t) {
			return false
		}
		pz := reflect.New(t.Elem())
		if rewriteValue(rewrite, src.Elem(), pz.Elem()) {
			dst.Set(pz)
			return true
		}
		return false

	case reflect.Interface:
		if !src.IsNil() {
			if src.Elem().Kind() == reflect.Ptr && src.Elem().IsNil() {
				// Rewrite src to be a <nil,nil> interface value, instead of <*int,nil>
				dst.Set(reflect.Zero(t))
				return true
			}
		}
		// If value is nil of type *T, collapse to absolute nil
		if src.IsNil() || isTerminalKind(src.Elem().Type()) {
			return false
		}

		// Recursive interface value unflattening would happen here;
		// We don't use it, however, since there is no source of
		// type-information for the actual passed values.
		pz := reflect.New(src.Elem().Type())
		if rewriteValue(rewrite, src.Elem(), pz.Elem()) {
			dst.Set(pz.Elem())
			return true
		}
		return false

	case reflect.Struct:
		if isTerminalKind(t) {
			return false
		}
		for i := 0; i < src.NumField(); i++ {
			if t.Field(i).PkgPath == "" {
				// If field is public
				src__, dst__ := src.Field(i), dst.Field(i)
				g.Add(1)
				go func() {
					defer g.Done()
					if rewriteValue(rewrite, src__, dst__) {
						g.Lock()
						g.Change = true
						g.Unlock()
					} else {
						dst__.Set(src__)
					}
				}()
			}
		}
		g.Wait()
		return g.Change

	case reflect.Chan:
		panic("rewrite chan, not supported yet")

	case reflect.Func:
		panic("rewrite func")

	case reflect.UnsafePointer:
		panic("rewrite unsafe pointer")
	}

	// All remaining types are primitive and therefore terminal
	return false
}
// dst must be addressable.
dst must be addressable.
// dst must be addressable .
func rewriteValue(rewrite rewriteFunc, src, dst reflect.Value) bool {
	if rewrite(src, dst) {
		return true
	}
	var g rewriteGroup
	t := src.Type()
	switch src.Kind() {
	case reflect.Array:
		if isTerminalKind(t) {
			return false
		}
		for i := 0; i < src.Len(); i++ {
			src__, dst__ := src.Index(i), dst.Index(i)
			g.Add(1)
			go func() {
				defer g.Done()
				if rewriteValue(rewrite, src__, dst__) {
					g.Lock()
					g.Change = true
					g.Unlock()
				} else {
					dst__.Set(src__)
				}
			}()
		}
		g.Wait()
		return g.Change
	case reflect.Slice:
		if src.IsNil() || isTerminalKind(t) {
			return false
		}
		dst.Set(reflect.MakeSlice(t, src.Len(), src.Len()))
		for i := 0; i < src.Len(); i++ {
			src__, dst__ := src.Index(i), dst.Index(i)
			g.Add(1)
			go func() {
				defer g.Done()
				if rewriteValue(rewrite, src__, dst__) {
					g.Lock()
					g.Change = true
					g.Unlock()
				} else {
					dst__.Set(src__)
				}
			}()
		}
		g.Wait()
		return g.Change
	case reflect.Map:
		if src.IsNil() || isTerminalKind(t) {
			return false
		}
		dst.Set(reflect.MakeMap(t))
		for _, mk := range src.MapKeys() {
			src__ := src.MapIndex(mk)
			dst__ := reflect.New(t.Elem()).Elem()
			g.Add(1)
			go func() {
				defer g.Done()
				if rewriteValue(rewrite, src__, dst__) {
					dst.SetMapIndex(mk, dst__)
					g.Lock()
					g.Change = true
					g.Unlock()
				} else {
					dst.SetMapIndex(mk, src__)
				}
			}()
		}
		g.Wait()
		return g.Change
	case reflect.Ptr:
		if src.IsNil() || isTerminalKind(t) {
			return false
		}
		pz := reflect.New(t.Elem())
		if rewriteValue(rewrite, src.Elem(), pz.Elem()) {
			dst.Set(pz)
			return true
		}
		return false
	case reflect.Interface:
		if !src.IsNil() {
			if src.Elem().Kind() == reflect.Ptr && src.Elem().IsNil() {
				dst.Set(reflect.Zero(t))
				return true
			}
		}
		if src.IsNil() || isTerminalKind(src.Elem().Type()) {
			return false
		}
		pz := reflect.New(src.Elem().Type())
		if rewriteValue(rewrite, src.Elem(), pz.Elem()) {
			dst.Set(pz.Elem())
			return true
		}
		return false
	case reflect.Struct:
		if isTerminalKind(t) {
			return false
		}
		for i := 0; i < src.NumField(); i++ {
			if t.Field(i).PkgPath == "" {
				src__, dst__ := src.Field(i), dst.Field(i)
				g.Add(1)
				go func() {
					defer g.Done()
					if rewriteValue(rewrite, src__, dst__) {
						g.Lock()
						g.Change = true
						g.Unlock()
					} else {
						dst__.Set(src__)
					}
				}()
			}
		}
		g.Wait()
		return g.Change
	case reflect.Chan:
		panic("rewrite chan, not supported yet")
	case reflect.Func:
		panic("rewrite func")
	case reflect.UnsafePointer:
		panic("rewrite unsafe pointer")
	}
	return false
}
func rewriteValue ( rewrite rewriteFunc , src , dst reflect . Value ) bool { if rewrite ( src , dst ) { return true } var g rewriteGroup t := src . Type ( ) switch src . Kind ( ) { case reflect . Array : if isTerminalKind ( t ) { return false } for i := 0 ; i < src . Len ( ) ; i ++ { src__ , dst__ := src . Index ( i ) , dst . Index ( i ) g . Add ( 1 ) go func ( ) { defer g . Done ( ) if rewriteValue ( rewrite , src__ , dst__ ) { g . Lock ( ) g . Change = true g . Unlock ( ) } else { dst__ . Set ( src__ ) } } ( ) } g . Wait ( ) return g . Change case reflect . Slice : if src . IsNil ( ) || isTerminalKind ( t ) { return false } dst . Set ( reflect . MakeSlice ( t , src . Len ( ) , src . Len ( ) ) ) for i := 0 ; i < src . Len ( ) ; i ++ { src__ , dst__ := src . Index ( i ) , dst . Index ( i ) g . Add ( 1 ) go func ( ) { defer g . Done ( ) if rewriteValue ( rewrite , src__ , dst__ ) { g . Lock ( ) g . Change = true g . Unlock ( ) } else { dst__ . Set ( src__ ) } } ( ) } g . Wait ( ) return g . Change case reflect . Map : if src . IsNil ( ) || isTerminalKind ( t ) { return false } dst . Set ( reflect . MakeMap ( t ) ) for _ , mk := range src . MapKeys ( ) { src__ := src . MapIndex ( mk ) dst__ := reflect . New ( t . Elem ( ) ) . Elem ( ) g . Add ( 1 ) go func ( ) { defer g . Done ( ) if rewriteValue ( rewrite , src__ , dst__ ) { dst . SetMapIndex ( mk , dst__ ) g . Lock ( ) g . Change = true g . Unlock ( ) } else { dst . SetMapIndex ( mk , src__ ) } } ( ) } g . Wait ( ) return g . Change case reflect . Ptr : if src . IsNil ( ) || isTerminalKind ( t ) { return false } pz := reflect . New ( t . Elem ( ) ) if rewriteValue ( rewrite , src . Elem ( ) , pz . Elem ( ) ) { dst . Set ( pz ) return true } return false case reflect . Interface : if ! src . IsNil ( ) { if src . Elem ( ) . Kind ( ) == reflect . Ptr && src . Elem ( ) . IsNil ( ) { dst . Set ( reflect . Zero ( t ) ) return true } } if src . IsNil ( ) || isTerminalKind ( src . Elem ( ) . Type ( ) ) { return false } pz := reflect . New ( src . Elem ( ) . Type ( ) ) if rewriteValue ( rewrite , src . Elem ( ) , pz . Elem ( ) ) { dst . Set ( pz . Elem ( ) ) return true } return false case reflect . Struct : if isTerminalKind ( t ) { return false } for i := 0 ; i < src . NumField ( ) ; i ++ { if t . Field ( i ) . PkgPath == " " { src__ , dst__ := src . Field ( i ) , dst . Field ( i ) g . Add ( 1 ) go func ( ) { defer g . Done ( ) if rewriteValue ( rewrite , src__ , dst__ ) { g . Lock ( ) g . Change = true g . Unlock ( ) } else { dst__ . Set ( src__ ) } } ( ) } } g . Wait ( ) return g . Change case reflect . Chan : panic ( " " ) case reflect . Func : panic ( " " ) case reflect . UnsafePointer : panic ( " " ) } return false }
dst must be addressable.
dst must be addressable .
// Recursive step // For now, we do not rewrite map key values // Rewrite src to be a <nil,nil> interface value, instead of <*int,nil> // If value is nil of type *T, collapse to absolute nil // Recursive interface value unflattening would happen here; // We don't use it, however, since there is no source of // type-information for the actual passed values. // If field is public // All remaining types are primitive and therefore terminal