go-bot

Форк
0
508 строк · 16.6 Кб
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
// Package protoreflect provides interfaces to dynamically manipulate messages.
6
//
7
// This package includes type descriptors which describe the structure of types
8
// defined in proto source files and value interfaces which provide the
9
// ability to examine and manipulate the contents of messages.
10
//
11
// # Protocol Buffer Descriptors
12
//
13
// Protobuf descriptors (e.g., EnumDescriptor or MessageDescriptor)
14
// are immutable objects that represent protobuf type information.
15
// They are wrappers around the messages declared in descriptor.proto.
16
// Protobuf descriptors alone lack any information regarding Go types.
17
//
18
// Enums and messages generated by this module implement Enum and ProtoMessage,
19
// where the Descriptor and ProtoReflect.Descriptor accessors respectively
20
// return the protobuf descriptor for the values.
21
//
22
// The protobuf descriptor interfaces are not meant to be implemented by
23
// user code since they might need to be extended in the future to support
24
// additions to the protobuf language.
25
// The "google.golang.org/protobuf/reflect/protodesc" package converts between
26
// google.protobuf.DescriptorProto messages and protobuf descriptors.
27
//
28
// # Go Type Descriptors
29
//
30
// A type descriptor (e.g., EnumType or MessageType) is a constructor for
31
// a concrete Go type that represents the associated protobuf descriptor.
32
// There is commonly a one-to-one relationship between protobuf descriptors and
33
// Go type descriptors, but it can potentially be a one-to-many relationship.
34
//
35
// Enums and messages generated by this module implement Enum and ProtoMessage,
36
// where the Type and ProtoReflect.Type accessors respectively
37
// return the protobuf descriptor for the values.
38
//
39
// The "google.golang.org/protobuf/types/dynamicpb" package can be used to
40
// create Go type descriptors from protobuf descriptors.
41
//
42
// # Value Interfaces
43
//
44
// The Enum and Message interfaces provide a reflective view over an
45
// enum or message instance. For enums, it provides the ability to retrieve
46
// the enum value number for any concrete enum type. For messages, it provides
47
// the ability to access or manipulate fields of the message.
48
//
49
// To convert a proto.Message to a protoreflect.Message, use the
50
// former's ProtoReflect method. Since the ProtoReflect method is new to the
51
// v2 message interface, it may not be present on older message implementations.
52
// The "github.com/golang/protobuf/proto".MessageReflect function can be used
53
// to obtain a reflective view on older messages.
54
//
55
// # Relationships
56
//
57
// The following diagrams demonstrate the relationships between
58
// various types declared in this package.
59
//
60
//	                       ┌───────────────────────────────────┐
61
//	                       V                                   │
62
//	   ┌────────────── New(n) ─────────────┐                   │
63
//	   │                                   │                   │
64
//	   │      ┌──── Descriptor() ──┐       │  ┌── Number() ──┐ │
65
//	   │      │                    V       V  │              V │
66
//	╔════════════╗  ╔════════════════╗  ╔════════╗  ╔════════════╗
67
//	║  EnumType  ║  ║ EnumDescriptor ║  ║  Enum  ║  ║ EnumNumber ║
68
//	╚════════════╝  ╚════════════════╝  ╚════════╝  ╚════════════╝
69
//	      Λ           Λ                   │ │
70
//	      │           └─── Descriptor() ──┘ │
71
//	      │                                 │
72
//	      └────────────────── Type() ───────┘
73
//
74
// • An EnumType describes a concrete Go enum type.
75
// It has an EnumDescriptor and can construct an Enum instance.
76
//
77
// • An EnumDescriptor describes an abstract protobuf enum type.
78
//
79
// • An Enum is a concrete enum instance. Generated enums implement Enum.
80
//
81
//	  ┌──────────────── New() ─────────────────┐
82
//	  │                                        │
83
//	  │         ┌─── Descriptor() ─────┐       │   ┌── Interface() ───┐
84
//	  │         │                      V       V   │                  V
85
//	╔═════════════╗  ╔═══════════════════╗  ╔═════════╗  ╔══════════════╗
86
//	║ MessageType ║  ║ MessageDescriptor ║  ║ Message ║  ║ ProtoMessage ║
87
//	╚═════════════╝  ╚═══════════════════╝  ╚═════════╝  ╚══════════════╝
88
//	       Λ           Λ                      │ │  Λ                  │
89
//	       │           └──── Descriptor() ────┘ │  └─ ProtoReflect() ─┘
90
//	       │                                    │
91
//	       └─────────────────── Type() ─────────┘
92
//
93
// • A MessageType describes a concrete Go message type.
94
// It has a MessageDescriptor and can construct a Message instance.
95
// Just as how Go's reflect.Type is a reflective description of a Go type,
96
// a MessageType is a reflective description of a Go type for a protobuf message.
97
//
98
// • A MessageDescriptor describes an abstract protobuf message type.
99
// It has no understanding of Go types. In order to construct a MessageType
100
// from just a MessageDescriptor, you can consider looking up the message type
101
// in the global registry using protoregistry.GlobalTypes.FindMessageByName
102
// or constructing a dynamic MessageType using dynamicpb.NewMessageType.
103
//
104
// • A Message is a reflective view over a concrete message instance.
105
// Generated messages implement ProtoMessage, which can convert to a Message.
106
// Just as how Go's reflect.Value is a reflective view over a Go value,
107
// a Message is a reflective view over a concrete protobuf message instance.
108
// Using Go reflection as an analogy, the ProtoReflect method is similar to
109
// calling reflect.ValueOf, and the Message.Interface method is similar to
110
// calling reflect.Value.Interface.
111
//
112
//	      ┌── TypeDescriptor() ──┐    ┌───── Descriptor() ─────┐
113
//	      │                      V    │                        V
114
//	╔═══════════════╗  ╔═════════════════════════╗  ╔═════════════════════╗
115
//	║ ExtensionType ║  ║ ExtensionTypeDescriptor ║  ║ ExtensionDescriptor ║
116
//	╚═══════════════╝  ╚═════════════════════════╝  ╚═════════════════════╝
117
//	      Λ                      │   │ Λ                      │ Λ
118
//	      └─────── Type() ───────┘   │ └─── may implement ────┘ │
119
//	                                 │                          │
120
//	                                 └────── implements ────────┘
121
//
122
// • An ExtensionType describes a concrete Go implementation of an extension.
123
// It has an ExtensionTypeDescriptor and can convert to/from
124
// abstract Values and Go values.
125
//
126
// • An ExtensionTypeDescriptor is an ExtensionDescriptor
127
// which also has an ExtensionType.
128
//
129
// • An ExtensionDescriptor describes an abstract protobuf extension field and
130
// may not always be an ExtensionTypeDescriptor.
131
package protoreflect
132

133
import (
134
	"fmt"
135
	"strings"
136

137
	"google.golang.org/protobuf/encoding/protowire"
138
	"google.golang.org/protobuf/internal/pragma"
139
)
140

141
type doNotImplement pragma.DoNotImplement
142

143
// ProtoMessage is the top-level interface that all proto messages implement.
144
// This is declared in the protoreflect package to avoid a cyclic dependency;
145
// use the proto.Message type instead, which aliases this type.
146
type ProtoMessage interface{ ProtoReflect() Message }
147

148
// Syntax is the language version of the proto file.
149
type Syntax syntax
150

151
type syntax int8 // keep exact type opaque as the int type may change
152

153
const (
154
	Proto2 Syntax = 2
155
	Proto3 Syntax = 3
156
)
157

158
// IsValid reports whether the syntax is valid.
159
func (s Syntax) IsValid() bool {
160
	switch s {
161
	case Proto2, Proto3:
162
		return true
163
	default:
164
		return false
165
	}
166
}
167

168
// String returns s as a proto source identifier (e.g., "proto2").
169
func (s Syntax) String() string {
170
	switch s {
171
	case Proto2:
172
		return "proto2"
173
	case Proto3:
174
		return "proto3"
175
	default:
176
		return fmt.Sprintf("<unknown:%d>", s)
177
	}
178
}
179

180
// GoString returns s as a Go source identifier (e.g., "Proto2").
181
func (s Syntax) GoString() string {
182
	switch s {
183
	case Proto2:
184
		return "Proto2"
185
	case Proto3:
186
		return "Proto3"
187
	default:
188
		return fmt.Sprintf("Syntax(%d)", s)
189
	}
190
}
191

192
// Cardinality determines whether a field is optional, required, or repeated.
193
type Cardinality cardinality
194

195
type cardinality int8 // keep exact type opaque as the int type may change
196

197
// Constants as defined by the google.protobuf.Cardinality enumeration.
198
const (
199
	Optional Cardinality = 1 // appears zero or one times
200
	Required Cardinality = 2 // appears exactly one time; invalid with Proto3
201
	Repeated Cardinality = 3 // appears zero or more times
202
)
203

204
// IsValid reports whether the cardinality is valid.
205
func (c Cardinality) IsValid() bool {
206
	switch c {
207
	case Optional, Required, Repeated:
208
		return true
209
	default:
210
		return false
211
	}
212
}
213

214
// String returns c as a proto source identifier (e.g., "optional").
215
func (c Cardinality) String() string {
216
	switch c {
217
	case Optional:
218
		return "optional"
219
	case Required:
220
		return "required"
221
	case Repeated:
222
		return "repeated"
223
	default:
224
		return fmt.Sprintf("<unknown:%d>", c)
225
	}
226
}
227

228
// GoString returns c as a Go source identifier (e.g., "Optional").
229
func (c Cardinality) GoString() string {
230
	switch c {
231
	case Optional:
232
		return "Optional"
233
	case Required:
234
		return "Required"
235
	case Repeated:
236
		return "Repeated"
237
	default:
238
		return fmt.Sprintf("Cardinality(%d)", c)
239
	}
240
}
241

242
// Kind indicates the basic proto kind of a field.
243
type Kind kind
244

245
type kind int8 // keep exact type opaque as the int type may change
246

247
// Constants as defined by the google.protobuf.Field.Kind enumeration.
248
const (
249
	BoolKind     Kind = 8
250
	EnumKind     Kind = 14
251
	Int32Kind    Kind = 5
252
	Sint32Kind   Kind = 17
253
	Uint32Kind   Kind = 13
254
	Int64Kind    Kind = 3
255
	Sint64Kind   Kind = 18
256
	Uint64Kind   Kind = 4
257
	Sfixed32Kind Kind = 15
258
	Fixed32Kind  Kind = 7
259
	FloatKind    Kind = 2
260
	Sfixed64Kind Kind = 16
261
	Fixed64Kind  Kind = 6
262
	DoubleKind   Kind = 1
263
	StringKind   Kind = 9
264
	BytesKind    Kind = 12
265
	MessageKind  Kind = 11
266
	GroupKind    Kind = 10
267
)
268

269
// IsValid reports whether the kind is valid.
270
func (k Kind) IsValid() bool {
271
	switch k {
272
	case BoolKind, EnumKind,
273
		Int32Kind, Sint32Kind, Uint32Kind,
274
		Int64Kind, Sint64Kind, Uint64Kind,
275
		Sfixed32Kind, Fixed32Kind, FloatKind,
276
		Sfixed64Kind, Fixed64Kind, DoubleKind,
277
		StringKind, BytesKind, MessageKind, GroupKind:
278
		return true
279
	default:
280
		return false
281
	}
282
}
283

284
// String returns k as a proto source identifier (e.g., "bool").
285
func (k Kind) String() string {
286
	switch k {
287
	case BoolKind:
288
		return "bool"
289
	case EnumKind:
290
		return "enum"
291
	case Int32Kind:
292
		return "int32"
293
	case Sint32Kind:
294
		return "sint32"
295
	case Uint32Kind:
296
		return "uint32"
297
	case Int64Kind:
298
		return "int64"
299
	case Sint64Kind:
300
		return "sint64"
301
	case Uint64Kind:
302
		return "uint64"
303
	case Sfixed32Kind:
304
		return "sfixed32"
305
	case Fixed32Kind:
306
		return "fixed32"
307
	case FloatKind:
308
		return "float"
309
	case Sfixed64Kind:
310
		return "sfixed64"
311
	case Fixed64Kind:
312
		return "fixed64"
313
	case DoubleKind:
314
		return "double"
315
	case StringKind:
316
		return "string"
317
	case BytesKind:
318
		return "bytes"
319
	case MessageKind:
320
		return "message"
321
	case GroupKind:
322
		return "group"
323
	default:
324
		return fmt.Sprintf("<unknown:%d>", k)
325
	}
326
}
327

328
// GoString returns k as a Go source identifier (e.g., "BoolKind").
329
func (k Kind) GoString() string {
330
	switch k {
331
	case BoolKind:
332
		return "BoolKind"
333
	case EnumKind:
334
		return "EnumKind"
335
	case Int32Kind:
336
		return "Int32Kind"
337
	case Sint32Kind:
338
		return "Sint32Kind"
339
	case Uint32Kind:
340
		return "Uint32Kind"
341
	case Int64Kind:
342
		return "Int64Kind"
343
	case Sint64Kind:
344
		return "Sint64Kind"
345
	case Uint64Kind:
346
		return "Uint64Kind"
347
	case Sfixed32Kind:
348
		return "Sfixed32Kind"
349
	case Fixed32Kind:
350
		return "Fixed32Kind"
351
	case FloatKind:
352
		return "FloatKind"
353
	case Sfixed64Kind:
354
		return "Sfixed64Kind"
355
	case Fixed64Kind:
356
		return "Fixed64Kind"
357
	case DoubleKind:
358
		return "DoubleKind"
359
	case StringKind:
360
		return "StringKind"
361
	case BytesKind:
362
		return "BytesKind"
363
	case MessageKind:
364
		return "MessageKind"
365
	case GroupKind:
366
		return "GroupKind"
367
	default:
368
		return fmt.Sprintf("Kind(%d)", k)
369
	}
370
}
371

372
// FieldNumber is the field number in a message.
373
type FieldNumber = protowire.Number
374

375
// FieldNumbers represent a list of field numbers.
376
type FieldNumbers interface {
377
	// Len reports the number of fields in the list.
378
	Len() int
379
	// Get returns the ith field number. It panics if out of bounds.
380
	Get(i int) FieldNumber
381
	// Has reports whether n is within the list of fields.
382
	Has(n FieldNumber) bool
383

384
	doNotImplement
385
}
386

387
// FieldRanges represent a list of field number ranges.
388
type FieldRanges interface {
389
	// Len reports the number of ranges in the list.
390
	Len() int
391
	// Get returns the ith range. It panics if out of bounds.
392
	Get(i int) [2]FieldNumber // start inclusive; end exclusive
393
	// Has reports whether n is within any of the ranges.
394
	Has(n FieldNumber) bool
395

396
	doNotImplement
397
}
398

399
// EnumNumber is the numeric value for an enum.
400
type EnumNumber int32
401

402
// EnumRanges represent a list of enum number ranges.
403
type EnumRanges interface {
404
	// Len reports the number of ranges in the list.
405
	Len() int
406
	// Get returns the ith range. It panics if out of bounds.
407
	Get(i int) [2]EnumNumber // start inclusive; end inclusive
408
	// Has reports whether n is within any of the ranges.
409
	Has(n EnumNumber) bool
410

411
	doNotImplement
412
}
413

414
// Name is the short name for a proto declaration. This is not the name
415
// as used in Go source code, which might not be identical to the proto name.
416
type Name string // e.g., "Kind"
417

418
// IsValid reports whether s is a syntactically valid name.
419
// An empty name is invalid.
420
func (s Name) IsValid() bool {
421
	return consumeIdent(string(s)) == len(s)
422
}
423

424
// Names represent a list of names.
425
type Names interface {
426
	// Len reports the number of names in the list.
427
	Len() int
428
	// Get returns the ith name. It panics if out of bounds.
429
	Get(i int) Name
430
	// Has reports whether s matches any names in the list.
431
	Has(s Name) bool
432

433
	doNotImplement
434
}
435

436
// FullName is a qualified name that uniquely identifies a proto declaration.
437
// A qualified name is the concatenation of the proto package along with the
438
// fully-declared name (i.e., name of parent preceding the name of the child),
439
// with a '.' delimiter placed between each Name.
440
//
441
// This should not have any leading or trailing dots.
442
type FullName string // e.g., "google.protobuf.Field.Kind"
443

444
// IsValid reports whether s is a syntactically valid full name.
445
// An empty full name is invalid.
446
func (s FullName) IsValid() bool {
447
	i := consumeIdent(string(s))
448
	if i < 0 {
449
		return false
450
	}
451
	for len(s) > i {
452
		if s[i] != '.' {
453
			return false
454
		}
455
		i++
456
		n := consumeIdent(string(s[i:]))
457
		if n < 0 {
458
			return false
459
		}
460
		i += n
461
	}
462
	return true
463
}
464

465
func consumeIdent(s string) (i int) {
466
	if len(s) == 0 || !isLetter(s[i]) {
467
		return -1
468
	}
469
	i++
470
	for len(s) > i && isLetterDigit(s[i]) {
471
		i++
472
	}
473
	return i
474
}
475
func isLetter(c byte) bool {
476
	return c == '_' || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')
477
}
478
func isLetterDigit(c byte) bool {
479
	return isLetter(c) || ('0' <= c && c <= '9')
480
}
481

482
// Name returns the short name, which is the last identifier segment.
483
// A single segment FullName is the Name itself.
484
func (n FullName) Name() Name {
485
	if i := strings.LastIndexByte(string(n), '.'); i >= 0 {
486
		return Name(n[i+1:])
487
	}
488
	return Name(n)
489
}
490

491
// Parent returns the full name with the trailing identifier removed.
492
// A single segment FullName has no parent.
493
func (n FullName) Parent() FullName {
494
	if i := strings.LastIndexByte(string(n), '.'); i >= 0 {
495
		return n[:i]
496
	}
497
	return ""
498
}
499

500
// Append returns the qualified name appended with the provided short name.
501
//
502
// Invariant: n == n.Parent().Append(n.Name()) // assuming n is valid
503
func (n FullName) Append(s Name) FullName {
504
	if n == "" {
505
		return FullName(s)
506
	}
507
	return n + "." + FullName(s)
508
}
509

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

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

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

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