...

Source file src/google.golang.org/protobuf/reflect/protoreflect/value_unsafe_go120.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  	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  }
   100  

View as plain text