github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/google.golang.org/protobuf/proto/extension.go (about)

     1  // Copyright 2019 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  package proto
     6  
     7  import (
     8  	"google.golang.org/protobuf/reflect/protoreflect"
     9  )
    10  
    11  // HasExtension reports whether an extension field is populated.
    12  // It returns false if m is invalid or if xt does not extend m.
    13  func HasExtension(m Message, xt protoreflect.ExtensionType) bool {
    14  	// Treat nil message interface as an empty message; no populated fields.
    15  	if m == nil {
    16  		return false
    17  	}
    18  
    19  	// As a special-case, we reports invalid or mismatching descriptors
    20  	// as always not being populated (since they aren't).
    21  	if xt == nil || m.ProtoReflect().Descriptor() != xt.TypeDescriptor().ContainingMessage() {
    22  		return false
    23  	}
    24  
    25  	return m.ProtoReflect().Has(xt.TypeDescriptor())
    26  }
    27  
    28  // ClearExtension clears an extension field such that subsequent
    29  // HasExtension calls return false.
    30  // It panics if m is invalid or if xt does not extend m.
    31  func ClearExtension(m Message, xt protoreflect.ExtensionType) {
    32  	m.ProtoReflect().Clear(xt.TypeDescriptor())
    33  }
    34  
    35  // GetExtension retrieves the value for an extension field.
    36  // If the field is unpopulated, it returns the default value for
    37  // scalars and an immutable, empty value for lists or messages.
    38  // It panics if xt does not extend m.
    39  func GetExtension(m Message, xt protoreflect.ExtensionType) interface{} {
    40  	// Treat nil message interface as an empty message; return the default.
    41  	if m == nil {
    42  		return xt.InterfaceOf(xt.Zero())
    43  	}
    44  
    45  	return xt.InterfaceOf(m.ProtoReflect().Get(xt.TypeDescriptor()))
    46  }
    47  
    48  // SetExtension stores the value of an extension field.
    49  // It panics if m is invalid, xt does not extend m, or if type of v
    50  // is invalid for the specified extension field.
    51  func SetExtension(m Message, xt protoreflect.ExtensionType, v interface{}) {
    52  	xd := xt.TypeDescriptor()
    53  	pv := xt.ValueOf(v)
    54  
    55  	// Specially treat an invalid list, map, or message as clear.
    56  	isValid := true
    57  	switch {
    58  	case xd.IsList():
    59  		isValid = pv.List().IsValid()
    60  	case xd.IsMap():
    61  		isValid = pv.Map().IsValid()
    62  	case xd.Message() != nil:
    63  		isValid = pv.Message().IsValid()
    64  	}
    65  	if !isValid {
    66  		m.ProtoReflect().Clear(xd)
    67  		return
    68  	}
    69  
    70  	m.ProtoReflect().Set(xd, pv)
    71  }
    72  
    73  // RangeExtensions iterates over every populated extension field in m in an
    74  // undefined order, calling f for each extension type and value encountered.
    75  // It returns immediately if f returns false.
    76  // While iterating, mutating operations may only be performed
    77  // on the current extension field.
    78  func RangeExtensions(m Message, f func(protoreflect.ExtensionType, interface{}) bool) {
    79  	// Treat nil message interface as an empty message; nothing to range over.
    80  	if m == nil {
    81  		return
    82  	}
    83  
    84  	m.ProtoReflect().Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
    85  		if fd.IsExtension() {
    86  			xt := fd.(protoreflect.ExtensionTypeDescriptor).Type()
    87  			vi := xt.InterfaceOf(v)
    88  			return f(xt, vi)
    89  		}
    90  		return true
    91  	})
    92  }