...

Source file src/google.golang.org/protobuf/reflect/protoreflect/value_unsafe_go121.go

Documentation: google.golang.org/protobuf/reflect/protoreflect

     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 && go1.21
     6  // +build !purego,!appengine,go1.21
     7  
     8  package protoreflect
     9  
    10  import (
    11  	"unsafe"
    12  
    13  	"google.golang.org/protobuf/internal/pragma"
    14  )
    15  
    16  type (
    17  	ifaceHeader struct {
    18  		_    [0]interface{} // if interfaces have greater alignment than unsafe.Pointer, this will enforce it.
    19  		Type unsafe.Pointer
    20  		Data unsafe.Pointer
    21  	}
    22  )
    23  
    24  var (
    25  	nilType     = typeOf(nil)
    26  	boolType    = typeOf(*new(bool))
    27  	int32Type   = typeOf(*new(int32))
    28  	int64Type   = typeOf(*new(int64))
    29  	uint32Type  = typeOf(*new(uint32))
    30  	uint64Type  = typeOf(*new(uint64))
    31  	float32Type = typeOf(*new(float32))
    32  	float64Type = typeOf(*new(float64))
    33  	stringType  = typeOf(*new(string))
    34  	bytesType   = typeOf(*new([]byte))
    35  	enumType    = typeOf(*new(EnumNumber))
    36  )
    37  
    38  // typeOf returns a pointer to the Go type information.
    39  // The pointer is comparable and equal if and only if the types are identical.
    40  func typeOf(t interface{}) unsafe.Pointer {
    41  	return (*ifaceHeader)(unsafe.Pointer(&t)).Type
    42  }
    43  
    44  // value is a union where only one type can be represented at a time.
    45  // The struct is 24B large on 64-bit systems and requires the minimum storage
    46  // necessary to represent each possible type.
    47  //
    48  // The Go GC needs to be able to scan variables containing pointers.
    49  // As such, pointers and non-pointers cannot be intermixed.
    50  type value struct {
    51  	pragma.DoNotCompare // 0B
    52  
    53  	// typ stores the type of the value as a pointer to the Go type.
    54  	typ unsafe.Pointer // 8B
    55  
    56  	// ptr stores the data pointer for a String, Bytes, or interface value.
    57  	ptr unsafe.Pointer // 8B
    58  
    59  	// num stores a Bool, Int32, Int64, Uint32, Uint64, Float32, Float64, or
    60  	// Enum value as a raw uint64.
    61  	//
    62  	// It is also used to store the length of a String or Bytes value;
    63  	// the capacity is ignored.
    64  	num uint64 // 8B
    65  }
    66  
    67  func valueOfString(v string) Value {
    68  	return Value{typ: stringType, ptr: unsafe.Pointer(unsafe.StringData(v)), num: uint64(len(v))}
    69  }
    70  func valueOfBytes(v []byte) Value {
    71  	return Value{typ: bytesType, ptr: unsafe.Pointer(unsafe.SliceData(v)), num: uint64(len(v))}
    72  }
    73  func valueOfIface(v interface{}) Value {
    74  	p := (*ifaceHeader)(unsafe.Pointer(&v))
    75  	return Value{typ: p.Type, ptr: p.Data}
    76  }
    77  
    78  func (v Value) getString() string {
    79  	return unsafe.String((*byte)(v.ptr), v.num)
    80  }
    81  func (v Value) getBytes() []byte {
    82  	return unsafe.Slice((*byte)(v.ptr), v.num)
    83  }
    84  func (v Value) getIface() (x interface{}) {
    85  	*(*ifaceHeader)(unsafe.Pointer(&x)) = ifaceHeader{Type: v.typ, Data: v.ptr}
    86  	return x
    87  }
    88  

View as plain text