go-bot

Форк
0
92 строки · 2.9 Кб
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
}
93

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.