proto.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  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. // Package protoreflect provides interfaces to dynamically manipulate messages.
  5. //
  6. // This package includes type descriptors which describe the structure of types
  7. // defined in proto source files and value interfaces which provide the
  8. // ability to examine and manipulate the contents of messages.
  9. //
  10. // # Protocol Buffer Descriptors
  11. //
  12. // Protobuf descriptors (e.g., [EnumDescriptor] or [MessageDescriptor])
  13. // are immutable objects that represent protobuf type information.
  14. // They are wrappers around the messages declared in descriptor.proto.
  15. // Protobuf descriptors alone lack any information regarding Go types.
  16. //
  17. // Enums and messages generated by this module implement [Enum] and [ProtoMessage],
  18. // where the Descriptor and ProtoReflect.Descriptor accessors respectively
  19. // return the protobuf descriptor for the values.
  20. //
  21. // The protobuf descriptor interfaces are not meant to be implemented by
  22. // user code since they might need to be extended in the future to support
  23. // additions to the protobuf language.
  24. // The [google.golang.org/protobuf/reflect/protodesc] package converts between
  25. // google.protobuf.DescriptorProto messages and protobuf descriptors.
  26. //
  27. // # Go Type Descriptors
  28. //
  29. // A type descriptor (e.g., [EnumType] or [MessageType]) is a constructor for
  30. // a concrete Go type that represents the associated protobuf descriptor.
  31. // There is commonly a one-to-one relationship between protobuf descriptors and
  32. // Go type descriptors, but it can potentially be a one-to-many relationship.
  33. //
  34. // Enums and messages generated by this module implement [Enum] and [ProtoMessage],
  35. // where the Type and ProtoReflect.Type accessors respectively
  36. // return the protobuf descriptor for the values.
  37. //
  38. // The [google.golang.org/protobuf/types/dynamicpb] package can be used to
  39. // create Go type descriptors from protobuf descriptors.
  40. //
  41. // # Value Interfaces
  42. //
  43. // The [Enum] and [Message] interfaces provide a reflective view over an
  44. // enum or message instance. For enums, it provides the ability to retrieve
  45. // the enum value number for any concrete enum type. For messages, it provides
  46. // the ability to access or manipulate fields of the message.
  47. //
  48. // To convert a [google.golang.org/protobuf/proto.Message] to a [protoreflect.Message], use the
  49. // former's ProtoReflect method. Since the ProtoReflect method is new to the
  50. // v2 message interface, it may not be present on older message implementations.
  51. // The [github.com/golang/protobuf/proto.MessageReflect] function can be used
  52. // to obtain a reflective view on older messages.
  53. //
  54. // # Relationships
  55. //
  56. // The following diagrams demonstrate the relationships between
  57. // various types declared in this package.
  58. //
  59. // ┌───────────────────────────────────┐
  60. // V │
  61. // ┌────────────── New(n) ─────────────┐ │
  62. // │ │ │
  63. // │ ┌──── Descriptor() ──┐ │ ┌── Number() ──┐ │
  64. // │ │ V V │ V │
  65. // ╔════════════╗ ╔════════════════╗ ╔════════╗ ╔════════════╗
  66. // ║ EnumType ║ ║ EnumDescriptor ║ ║ Enum ║ ║ EnumNumber ║
  67. // ╚════════════╝ ╚════════════════╝ ╚════════╝ ╚════════════╝
  68. // Λ Λ │ │
  69. // │ └─── Descriptor() ──┘ │
  70. // │ │
  71. // └────────────────── Type() ───────┘
  72. //
  73. // • An [EnumType] describes a concrete Go enum type.
  74. // It has an EnumDescriptor and can construct an Enum instance.
  75. //
  76. // • An [EnumDescriptor] describes an abstract protobuf enum type.
  77. //
  78. // • An [Enum] is a concrete enum instance. Generated enums implement Enum.
  79. //
  80. // ┌──────────────── New() ─────────────────┐
  81. // │ │
  82. // │ ┌─── Descriptor() ─────┐ │ ┌── Interface() ───┐
  83. // │ │ V V │ V
  84. // ╔═════════════╗ ╔═══════════════════╗ ╔═════════╗ ╔══════════════╗
  85. // ║ MessageType ║ ║ MessageDescriptor ║ ║ Message ║ ║ ProtoMessage ║
  86. // ╚═════════════╝ ╚═══════════════════╝ ╚═════════╝ ╚══════════════╝
  87. // Λ Λ │ │ Λ │
  88. // │ └──── Descriptor() ────┘ │ └─ ProtoReflect() ─┘
  89. // │ │
  90. // └─────────────────── Type() ─────────┘
  91. //
  92. // • A [MessageType] describes a concrete Go message type.
  93. // It has a [MessageDescriptor] and can construct a [Message] instance.
  94. // Just as how Go's [reflect.Type] is a reflective description of a Go type,
  95. // a [MessageType] is a reflective description of a Go type for a protobuf message.
  96. //
  97. // • A [MessageDescriptor] describes an abstract protobuf message type.
  98. // It has no understanding of Go types. In order to construct a [MessageType]
  99. // from just a [MessageDescriptor], you can consider looking up the message type
  100. // in the global registry using the FindMessageByName method on
  101. // [google.golang.org/protobuf/reflect/protoregistry.GlobalTypes]
  102. // or constructing a dynamic [MessageType] using
  103. // [google.golang.org/protobuf/types/dynamicpb.NewMessageType].
  104. //
  105. // • A [Message] is a reflective view over a concrete message instance.
  106. // Generated messages implement [ProtoMessage], which can convert to a [Message].
  107. // Just as how Go's [reflect.Value] is a reflective view over a Go value,
  108. // a [Message] is a reflective view over a concrete protobuf message instance.
  109. // Using Go reflection as an analogy, the [ProtoMessage.ProtoReflect] method is similar to
  110. // calling [reflect.ValueOf], and the [Message.Interface] method is similar to
  111. // calling [reflect.Value.Interface].
  112. //
  113. // ┌── TypeDescriptor() ──┐ ┌───── Descriptor() ─────┐
  114. // │ V │ V
  115. // ╔═══════════════╗ ╔═════════════════════════╗ ╔═════════════════════╗
  116. // ║ ExtensionType ║ ║ ExtensionTypeDescriptor ║ ║ ExtensionDescriptor ║
  117. // ╚═══════════════╝ ╚═════════════════════════╝ ╚═════════════════════╝
  118. // Λ │ │ Λ │ Λ
  119. // └─────── Type() ───────┘ │ └─── may implement ────┘ │
  120. // │ │
  121. // └────── implements ────────┘
  122. //
  123. // • An [ExtensionType] describes a concrete Go implementation of an extension.
  124. // It has an [ExtensionTypeDescriptor] and can convert to/from
  125. // an abstract [Value] and a Go value.
  126. //
  127. // • An [ExtensionTypeDescriptor] is an [ExtensionDescriptor]
  128. // which also has an [ExtensionType].
  129. //
  130. // • An [ExtensionDescriptor] describes an abstract protobuf extension field and
  131. // may not always be an [ExtensionTypeDescriptor].
  132. package protoreflect
  133. import (
  134. "fmt"
  135. "strings"
  136. "google.golang.org/protobuf/encoding/protowire"
  137. "google.golang.org/protobuf/internal/pragma"
  138. )
  139. type doNotImplement pragma.DoNotImplement
  140. // ProtoMessage is the top-level interface that all proto messages implement.
  141. // This is declared in the protoreflect package to avoid a cyclic dependency;
  142. // use the [google.golang.org/protobuf/proto.Message] type instead, which aliases this type.
  143. type ProtoMessage interface{ ProtoReflect() Message }
  144. // Syntax is the language version of the proto file.
  145. type Syntax syntax
  146. type syntax int8 // keep exact type opaque as the int type may change
  147. const (
  148. Proto2 Syntax = 2
  149. Proto3 Syntax = 3
  150. Editions Syntax = 4
  151. )
  152. // IsValid reports whether the syntax is valid.
  153. func (s Syntax) IsValid() bool {
  154. switch s {
  155. case Proto2, Proto3:
  156. return true
  157. default:
  158. return false
  159. }
  160. }
  161. // String returns s as a proto source identifier (e.g., "proto2").
  162. func (s Syntax) String() string {
  163. switch s {
  164. case Proto2:
  165. return "proto2"
  166. case Proto3:
  167. return "proto3"
  168. default:
  169. return fmt.Sprintf("<unknown:%d>", s)
  170. }
  171. }
  172. // GoString returns s as a Go source identifier (e.g., "Proto2").
  173. func (s Syntax) GoString() string {
  174. switch s {
  175. case Proto2:
  176. return "Proto2"
  177. case Proto3:
  178. return "Proto3"
  179. default:
  180. return fmt.Sprintf("Syntax(%d)", s)
  181. }
  182. }
  183. // Cardinality determines whether a field is optional, required, or repeated.
  184. type Cardinality cardinality
  185. type cardinality int8 // keep exact type opaque as the int type may change
  186. // Constants as defined by the google.protobuf.Cardinality enumeration.
  187. const (
  188. Optional Cardinality = 1 // appears zero or one times
  189. Required Cardinality = 2 // appears exactly one time; invalid with Proto3
  190. Repeated Cardinality = 3 // appears zero or more times
  191. )
  192. // IsValid reports whether the cardinality is valid.
  193. func (c Cardinality) IsValid() bool {
  194. switch c {
  195. case Optional, Required, Repeated:
  196. return true
  197. default:
  198. return false
  199. }
  200. }
  201. // String returns c as a proto source identifier (e.g., "optional").
  202. func (c Cardinality) String() string {
  203. switch c {
  204. case Optional:
  205. return "optional"
  206. case Required:
  207. return "required"
  208. case Repeated:
  209. return "repeated"
  210. default:
  211. return fmt.Sprintf("<unknown:%d>", c)
  212. }
  213. }
  214. // GoString returns c as a Go source identifier (e.g., "Optional").
  215. func (c Cardinality) GoString() 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("Cardinality(%d)", c)
  225. }
  226. }
  227. // Kind indicates the basic proto kind of a field.
  228. type Kind kind
  229. type kind int8 // keep exact type opaque as the int type may change
  230. // Constants as defined by the google.protobuf.Field.Kind enumeration.
  231. const (
  232. BoolKind Kind = 8
  233. EnumKind Kind = 14
  234. Int32Kind Kind = 5
  235. Sint32Kind Kind = 17
  236. Uint32Kind Kind = 13
  237. Int64Kind Kind = 3
  238. Sint64Kind Kind = 18
  239. Uint64Kind Kind = 4
  240. Sfixed32Kind Kind = 15
  241. Fixed32Kind Kind = 7
  242. FloatKind Kind = 2
  243. Sfixed64Kind Kind = 16
  244. Fixed64Kind Kind = 6
  245. DoubleKind Kind = 1
  246. StringKind Kind = 9
  247. BytesKind Kind = 12
  248. MessageKind Kind = 11
  249. GroupKind Kind = 10
  250. )
  251. // IsValid reports whether the kind is valid.
  252. func (k Kind) IsValid() bool {
  253. switch k {
  254. case BoolKind, EnumKind,
  255. Int32Kind, Sint32Kind, Uint32Kind,
  256. Int64Kind, Sint64Kind, Uint64Kind,
  257. Sfixed32Kind, Fixed32Kind, FloatKind,
  258. Sfixed64Kind, Fixed64Kind, DoubleKind,
  259. StringKind, BytesKind, MessageKind, GroupKind:
  260. return true
  261. default:
  262. return false
  263. }
  264. }
  265. // String returns k as a proto source identifier (e.g., "bool").
  266. func (k Kind) String() string {
  267. switch k {
  268. case BoolKind:
  269. return "bool"
  270. case EnumKind:
  271. return "enum"
  272. case Int32Kind:
  273. return "int32"
  274. case Sint32Kind:
  275. return "sint32"
  276. case Uint32Kind:
  277. return "uint32"
  278. case Int64Kind:
  279. return "int64"
  280. case Sint64Kind:
  281. return "sint64"
  282. case Uint64Kind:
  283. return "uint64"
  284. case Sfixed32Kind:
  285. return "sfixed32"
  286. case Fixed32Kind:
  287. return "fixed32"
  288. case FloatKind:
  289. return "float"
  290. case Sfixed64Kind:
  291. return "sfixed64"
  292. case Fixed64Kind:
  293. return "fixed64"
  294. case DoubleKind:
  295. return "double"
  296. case StringKind:
  297. return "string"
  298. case BytesKind:
  299. return "bytes"
  300. case MessageKind:
  301. return "message"
  302. case GroupKind:
  303. return "group"
  304. default:
  305. return fmt.Sprintf("<unknown:%d>", k)
  306. }
  307. }
  308. // GoString returns k as a Go source identifier (e.g., "BoolKind").
  309. func (k Kind) GoString() string {
  310. switch k {
  311. case BoolKind:
  312. return "BoolKind"
  313. case EnumKind:
  314. return "EnumKind"
  315. case Int32Kind:
  316. return "Int32Kind"
  317. case Sint32Kind:
  318. return "Sint32Kind"
  319. case Uint32Kind:
  320. return "Uint32Kind"
  321. case Int64Kind:
  322. return "Int64Kind"
  323. case Sint64Kind:
  324. return "Sint64Kind"
  325. case Uint64Kind:
  326. return "Uint64Kind"
  327. case Sfixed32Kind:
  328. return "Sfixed32Kind"
  329. case Fixed32Kind:
  330. return "Fixed32Kind"
  331. case FloatKind:
  332. return "FloatKind"
  333. case Sfixed64Kind:
  334. return "Sfixed64Kind"
  335. case Fixed64Kind:
  336. return "Fixed64Kind"
  337. case DoubleKind:
  338. return "DoubleKind"
  339. case StringKind:
  340. return "StringKind"
  341. case BytesKind:
  342. return "BytesKind"
  343. case MessageKind:
  344. return "MessageKind"
  345. case GroupKind:
  346. return "GroupKind"
  347. default:
  348. return fmt.Sprintf("Kind(%d)", k)
  349. }
  350. }
  351. // FieldNumber is the field number in a message.
  352. type FieldNumber = protowire.Number
  353. // FieldNumbers represent a list of field numbers.
  354. type FieldNumbers interface {
  355. // Len reports the number of fields in the list.
  356. Len() int
  357. // Get returns the ith field number. It panics if out of bounds.
  358. Get(i int) FieldNumber
  359. // Has reports whether n is within the list of fields.
  360. Has(n FieldNumber) bool
  361. doNotImplement
  362. }
  363. // FieldRanges represent a list of field number ranges.
  364. type FieldRanges interface {
  365. // Len reports the number of ranges in the list.
  366. Len() int
  367. // Get returns the ith range. It panics if out of bounds.
  368. Get(i int) [2]FieldNumber // start inclusive; end exclusive
  369. // Has reports whether n is within any of the ranges.
  370. Has(n FieldNumber) bool
  371. doNotImplement
  372. }
  373. // EnumNumber is the numeric value for an enum.
  374. type EnumNumber int32
  375. // EnumRanges represent a list of enum number ranges.
  376. type EnumRanges interface {
  377. // Len reports the number of ranges in the list.
  378. Len() int
  379. // Get returns the ith range. It panics if out of bounds.
  380. Get(i int) [2]EnumNumber // start inclusive; end inclusive
  381. // Has reports whether n is within any of the ranges.
  382. Has(n EnumNumber) bool
  383. doNotImplement
  384. }
  385. // Name is the short name for a proto declaration. This is not the name
  386. // as used in Go source code, which might not be identical to the proto name.
  387. type Name string // e.g., "Kind"
  388. // IsValid reports whether s is a syntactically valid name.
  389. // An empty name is invalid.
  390. func (s Name) IsValid() bool {
  391. return consumeIdent(string(s)) == len(s)
  392. }
  393. // Names represent a list of names.
  394. type Names interface {
  395. // Len reports the number of names in the list.
  396. Len() int
  397. // Get returns the ith name. It panics if out of bounds.
  398. Get(i int) Name
  399. // Has reports whether s matches any names in the list.
  400. Has(s Name) bool
  401. doNotImplement
  402. }
  403. // FullName is a qualified name that uniquely identifies a proto declaration.
  404. // A qualified name is the concatenation of the proto package along with the
  405. // fully-declared name (i.e., name of parent preceding the name of the child),
  406. // with a '.' delimiter placed between each [Name].
  407. //
  408. // This should not have any leading or trailing dots.
  409. type FullName string // e.g., "google.protobuf.Field.Kind"
  410. // IsValid reports whether s is a syntactically valid full name.
  411. // An empty full name is invalid.
  412. func (s FullName) IsValid() bool {
  413. i := consumeIdent(string(s))
  414. if i < 0 {
  415. return false
  416. }
  417. for len(s) > i {
  418. if s[i] != '.' {
  419. return false
  420. }
  421. i++
  422. n := consumeIdent(string(s[i:]))
  423. if n < 0 {
  424. return false
  425. }
  426. i += n
  427. }
  428. return true
  429. }
  430. func consumeIdent(s string) (i int) {
  431. if len(s) == 0 || !isLetter(s[i]) {
  432. return -1
  433. }
  434. i++
  435. for len(s) > i && isLetterDigit(s[i]) {
  436. i++
  437. }
  438. return i
  439. }
  440. func isLetter(c byte) bool {
  441. return c == '_' || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')
  442. }
  443. func isLetterDigit(c byte) bool {
  444. return isLetter(c) || ('0' <= c && c <= '9')
  445. }
  446. // Name returns the short name, which is the last identifier segment.
  447. // A single segment FullName is the [Name] itself.
  448. func (n FullName) Name() Name {
  449. if i := strings.LastIndexByte(string(n), '.'); i >= 0 {
  450. return Name(n[i+1:])
  451. }
  452. return Name(n)
  453. }
  454. // Parent returns the full name with the trailing identifier removed.
  455. // A single segment FullName has no parent.
  456. func (n FullName) Parent() FullName {
  457. if i := strings.LastIndexByte(string(n), '.'); i >= 0 {
  458. return n[:i]
  459. }
  460. return ""
  461. }
  462. // Append returns the qualified name appended with the provided short name.
  463. //
  464. // Invariant: n == n.Parent().Append(n.Name()) // assuming n is valid
  465. func (n FullName) Append(s Name) FullName {
  466. if n == "" {
  467. return FullName(s)
  468. }
  469. return n + "." + FullName(s)
  470. }