github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/google.golang.org/protobuf/reflect/protoreflect/value_unsafe.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build !purego && !appengine 6 // +build !purego,!appengine 7 8 package protoreflect 9 10 import ( 11 "unsafe" 12 13 "google.golang.org/protobuf/internal/pragma" 14 ) 15 16 type ( 17 stringHeader struct { 18 Data unsafe.Pointer 19 Len int 20 } 21 sliceHeader struct { 22 Data unsafe.Pointer 23 Len int 24 Cap int 25 } 26 ifaceHeader struct { 27 Type unsafe.Pointer 28 Data unsafe.Pointer 29 } 30 ) 31 32 var ( 33 nilType = typeOf(nil) 34 boolType = typeOf(*new(bool)) 35 int32Type = typeOf(*new(int32)) 36 int64Type = typeOf(*new(int64)) 37 uint32Type = typeOf(*new(uint32)) 38 uint64Type = typeOf(*new(uint64)) 39 float32Type = typeOf(*new(float32)) 40 float64Type = typeOf(*new(float64)) 41 stringType = typeOf(*new(string)) 42 bytesType = typeOf(*new([]byte)) 43 enumType = typeOf(*new(EnumNumber)) 44 ) 45 46 // typeOf returns a pointer to the Go type information. 47 // The pointer is comparable and equal if and only if the types are identical. 48 func typeOf(t interface{}) unsafe.Pointer { 49 return (*ifaceHeader)(unsafe.Pointer(&t)).Type 50 } 51 52 // value is a union where only one type can be represented at a time. 53 // The struct is 24B large on 64-bit systems and requires the minimum storage 54 // necessary to represent each possible type. 55 // 56 // The Go GC needs to be able to scan variables containing pointers. 57 // As such, pointers and non-pointers cannot be intermixed. 58 type value struct { 59 pragma.DoNotCompare // 0B 60 61 // typ stores the type of the value as a pointer to the Go type. 62 typ unsafe.Pointer // 8B 63 64 // ptr stores the data pointer for a String, Bytes, or interface value. 65 ptr unsafe.Pointer // 8B 66 67 // num stores a Bool, Int32, Int64, Uint32, Uint64, Float32, Float64, or 68 // Enum value as a raw uint64. 69 // 70 // It is also used to store the length of a String or Bytes value; 71 // the capacity is ignored. 72 num uint64 // 8B 73 } 74 75 func valueOfString(v string) Value { 76 p := (*stringHeader)(unsafe.Pointer(&v)) 77 return Value{typ: stringType, ptr: p.Data, num: uint64(len(v))} 78 } 79 func valueOfBytes(v []byte) Value { 80 p := (*sliceHeader)(unsafe.Pointer(&v)) 81 return Value{typ: bytesType, ptr: p.Data, num: uint64(len(v))} 82 } 83 func valueOfIface(v interface{}) Value { 84 p := (*ifaceHeader)(unsafe.Pointer(&v)) 85 return Value{typ: p.Type, ptr: p.Data} 86 } 87 88 func (v Value) getString() (x string) { 89 *(*stringHeader)(unsafe.Pointer(&x)) = stringHeader{Data: v.ptr, Len: int(v.num)} 90 return x 91 } 92 func (v Value) getBytes() (x []byte) { 93 *(*sliceHeader)(unsafe.Pointer(&x)) = sliceHeader{Data: v.ptr, Len: int(v.num), Cap: int(v.num)} 94 return x 95 } 96 func (v Value) getIface() (x interface{}) { 97 *(*ifaceHeader)(unsafe.Pointer(&x)) = ifaceHeader{Type: v.typ, Data: v.ptr} 98 return x 99 }