github.com/Psiphon-Inc/goarista@v0.0.0-20160825065156-d002785f4c67/areflect/force.go (about) 1 // Copyright (C) 2014 Arista Networks, Inc. 2 // Use of this source code is governed by the Apache License 2.0 3 // that can be found in the COPYING file. 4 5 // Package areflect provides utilities to help with reflection. 6 package areflect 7 8 import ( 9 "reflect" 10 "unsafe" 11 ) 12 13 // ForceExport returns a new reflect.Value that is identical to the one passed 14 // in argument except that it's considered as an exported symbol even if in 15 // reality it isn't. 16 // 17 // The `reflect' package intentionally makes it impossible to access the value 18 // of an unexported attribute. The implementation of reflect.DeepEqual() cheats 19 // as it bypasses this check. Unfortunately, we can't use the same cheat, which 20 // prevents us from re-implementing DeepEqual properly or implementing some other 21 // reflection-based tools. So this is our cheat on top of theirs. It makes 22 // the given reflect.Value appear as if it was exported. 23 func ForceExport(v reflect.Value) reflect.Value { 24 const flagRO uintptr = 1 << 5 // from reflect/value.go 25 ptr := unsafe.Pointer(&v) 26 rv := (*struct { 27 typ unsafe.Pointer // a *reflect.rtype (reflect.Type) 28 ptr unsafe.Pointer // The value wrapped by this reflect.Value 29 flag uintptr 30 })(ptr) 31 rv.flag &= ^flagRO // Unset the flag so this value appears to be exported. 32 return v 33 }