proto.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513
  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, Editions:
  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. case Editions:
  169. return "editions"
  170. default:
  171. return fmt.Sprintf("<unknown:%d>", s)
  172. }
  173. }
  174. // GoString returns s as a Go source identifier (e.g., "Proto2").
  175. func (s Syntax) GoString() string {
  176. switch s {
  177. case Proto2:
  178. return "Proto2"
  179. case Proto3:
  180. return "Proto3"
  181. default:
  182. return fmt.Sprintf("Syntax(%d)", s)
  183. }
  184. }
  185. // Cardinality determines whether a field is optional, required, or repeated.
  186. type Cardinality cardinality
  187. type cardinality int8 // keep exact type opaque as the int type may change
  188. // Constants as defined by the google.protobuf.Cardinality enumeration.
  189. const (
  190. Optional Cardinality = 1 // appears zero or one times
  191. Required Cardinality = 2 // appears exactly one time; invalid with Proto3
  192. Repeated Cardinality = 3 // appears zero or more times
  193. )
  194. // IsValid reports whether the cardinality is valid.
  195. func (c Cardinality) IsValid() bool {
  196. switch c {
  197. case Optional, Required, Repeated:
  198. return true
  199. default:
  200. return false
  201. }
  202. }
  203. // String returns c as a proto source identifier (e.g., "optional").
  204. func (c Cardinality) String() string {
  205. switch c {
  206. case Optional:
  207. return "optional"
  208. case Required:
  209. return "required"
  210. case Repeated:
  211. return "repeated"
  212. default:
  213. return fmt.Sprintf("<unknown:%d>", c)
  214. }
  215. }
  216. // GoString returns c as a Go source identifier (e.g., "Optional").
  217. func (c Cardinality) GoString() string {
  218. switch c {
  219. case Optional:
  220. return "Optional"
  221. case Required:
  222. return "Required"
  223. case Repeated:
  224. return "Repeated"
  225. default:
  226. return fmt.Sprintf("Cardinality(%d)", c)
  227. }
  228. }
  229. // Kind indicates the basic proto kind of a field.
  230. type Kind kind
  231. type kind int8 // keep exact type opaque as the int type may change
  232. // Constants as defined by the google.protobuf.Field.Kind enumeration.
  233. const (
  234. BoolKind Kind = 8
  235. EnumKind Kind = 14
  236. Int32Kind Kind = 5
  237. Sint32Kind Kind = 17
  238. Uint32Kind Kind = 13
  239. Int64Kind Kind = 3
  240. Sint64Kind Kind = 18
  241. Uint64Kind Kind = 4
  242. Sfixed32Kind Kind = 15
  243. Fixed32Kind Kind = 7
  244. FloatKind Kind = 2
  245. Sfixed64Kind Kind = 16
  246. Fixed64Kind Kind = 6
  247. DoubleKind Kind = 1
  248. StringKind Kind = 9
  249. BytesKind Kind = 12
  250. MessageKind Kind = 11
  251. GroupKind Kind = 10
  252. )
  253. // IsValid reports whether the kind is valid.
  254. func (k Kind) IsValid() bool {
  255. switch k {
  256. case BoolKind, EnumKind,
  257. Int32Kind, Sint32Kind, Uint32Kind,
  258. Int64Kind, Sint64Kind, Uint64Kind,
  259. Sfixed32Kind, Fixed32Kind, FloatKind,
  260. Sfixed64Kind, Fixed64Kind, DoubleKind,
  261. StringKind, BytesKind, MessageKind, GroupKind:
  262. return true
  263. default:
  264. return false
  265. }
  266. }
  267. // String returns k as a proto source identifier (e.g., "bool").
  268. func (k Kind) String() string {
  269. switch k {
  270. case BoolKind:
  271. return "bool"
  272. case EnumKind:
  273. return "enum"
  274. case Int32Kind:
  275. return "int32"
  276. case Sint32Kind:
  277. return "sint32"
  278. case Uint32Kind:
  279. return "uint32"
  280. case Int64Kind:
  281. return "int64"
  282. case Sint64Kind:
  283. return "sint64"
  284. case Uint64Kind:
  285. return "uint64"
  286. case Sfixed32Kind:
  287. return "sfixed32"
  288. case Fixed32Kind:
  289. return "fixed32"
  290. case FloatKind:
  291. return "float"
  292. case Sfixed64Kind:
  293. return "sfixed64"
  294. case Fixed64Kind:
  295. return "fixed64"
  296. case DoubleKind:
  297. return "double"
  298. case StringKind:
  299. return "string"
  300. case BytesKind:
  301. return "bytes"
  302. case MessageKind:
  303. return "message"
  304. case GroupKind:
  305. return "group"
  306. default:
  307. return fmt.Sprintf("<unknown:%d>", k)
  308. }
  309. }
  310. // GoString returns k as a Go source identifier (e.g., "BoolKind").
  311. func (k Kind) GoString() string {
  312. switch k {
  313. case BoolKind:
  314. return "BoolKind"
  315. case EnumKind:
  316. return "EnumKind"
  317. case Int32Kind:
  318. return "Int32Kind"
  319. case Sint32Kind:
  320. return "Sint32Kind"
  321. case Uint32Kind:
  322. return "Uint32Kind"
  323. case Int64Kind:
  324. return "Int64Kind"
  325. case Sint64Kind:
  326. return "Sint64Kind"
  327. case Uint64Kind:
  328. return "Uint64Kind"
  329. case Sfixed32Kind:
  330. return "Sfixed32Kind"
  331. case Fixed32Kind:
  332. return "Fixed32Kind"
  333. case FloatKind:
  334. return "FloatKind"
  335. case Sfixed64Kind:
  336. return "Sfixed64Kind"
  337. case Fixed64Kind:
  338. return "Fixed64Kind"
  339. case DoubleKind:
  340. return "DoubleKind"
  341. case StringKind:
  342. return "StringKind"
  343. case BytesKind:
  344. return "BytesKind"
  345. case MessageKind:
  346. return "MessageKind"
  347. case GroupKind:
  348. return "GroupKind"
  349. default:
  350. return fmt.Sprintf("Kind(%d)", k)
  351. }
  352. }
  353. // FieldNumber is the field number in a message.
  354. type FieldNumber = protowire.Number
  355. // FieldNumbers represent a list of field numbers.
  356. type FieldNumbers interface {
  357. // Len reports the number of fields in the list.
  358. Len() int
  359. // Get returns the ith field number. It panics if out of bounds.
  360. Get(i int) FieldNumber
  361. // Has reports whether n is within the list of fields.
  362. Has(n FieldNumber) bool
  363. doNotImplement
  364. }
  365. // FieldRanges represent a list of field number ranges.
  366. type FieldRanges interface {
  367. // Len reports the number of ranges in the list.
  368. Len() int
  369. // Get returns the ith range. It panics if out of bounds.
  370. Get(i int) [2]FieldNumber // start inclusive; end exclusive
  371. // Has reports whether n is within any of the ranges.
  372. Has(n FieldNumber) bool
  373. doNotImplement
  374. }
  375. // EnumNumber is the numeric value for an enum.
  376. type EnumNumber int32
  377. // EnumRanges represent a list of enum number ranges.
  378. type EnumRanges interface {
  379. // Len reports the number of ranges in the list.
  380. Len() int
  381. // Get returns the ith range. It panics if out of bounds.
  382. Get(i int) [2]EnumNumber // start inclusive; end inclusive
  383. // Has reports whether n is within any of the ranges.
  384. Has(n EnumNumber) bool
  385. doNotImplement
  386. }
  387. // Name is the short name for a proto declaration. This is not the name
  388. // as used in Go source code, which might not be identical to the proto name.
  389. type Name string // e.g., "Kind"
  390. // IsValid reports whether s is a syntactically valid name.
  391. // An empty name is invalid.
  392. func (s Name) IsValid() bool {
  393. return consumeIdent(string(s)) == len(s)
  394. }
  395. // Names represent a list of names.
  396. type Names interface {
  397. // Len reports the number of names in the list.
  398. Len() int
  399. // Get returns the ith name. It panics if out of bounds.
  400. Get(i int) Name
  401. // Has reports whether s matches any names in the list.
  402. Has(s Name) bool
  403. doNotImplement
  404. }
  405. // FullName is a qualified name that uniquely identifies a proto declaration.
  406. // A qualified name is the concatenation of the proto package along with the
  407. // fully-declared name (i.e., name of parent preceding the name of the child),
  408. // with a '.' delimiter placed between each [Name].
  409. //
  410. // This should not have any leading or trailing dots.
  411. type FullName string // e.g., "google.protobuf.Field.Kind"
  412. // IsValid reports whether s is a syntactically valid full name.
  413. // An empty full name is invalid.
  414. func (s FullName) IsValid() bool {
  415. i := consumeIdent(string(s))
  416. if i < 0 {
  417. return false
  418. }
  419. for len(s) > i {
  420. if s[i] != '.' {
  421. return false
  422. }
  423. i++
  424. n := consumeIdent(string(s[i:]))
  425. if n < 0 {
  426. return false
  427. }
  428. i += n
  429. }
  430. return true
  431. }
  432. func consumeIdent(s string) (i int) {
  433. if len(s) == 0 || !isLetter(s[i]) {
  434. return -1
  435. }
  436. i++
  437. for len(s) > i && isLetterDigit(s[i]) {
  438. i++
  439. }
  440. return i
  441. }
  442. func isLetter(c byte) bool {
  443. return c == '_' || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')
  444. }
  445. func isLetterDigit(c byte) bool {
  446. return isLetter(c) || ('0' <= c && c <= '9')
  447. }
  448. // Name returns the short name, which is the last identifier segment.
  449. // A single segment FullName is the [Name] itself.
  450. func (n FullName) Name() Name {
  451. if i := strings.LastIndexByte(string(n), '.'); i >= 0 {
  452. return Name(n[i+1:])
  453. }
  454. return Name(n)
  455. }
  456. // Parent returns the full name with the trailing identifier removed.
  457. // A single segment FullName has no parent.
  458. func (n FullName) Parent() FullName {
  459. if i := strings.LastIndexByte(string(n), '.'); i >= 0 {
  460. return n[:i]
  461. }
  462. return ""
  463. }
  464. // Append returns the qualified name appended with the provided short name.
  465. //
  466. // Invariant: n == n.Parent().Append(n.Name()) // assuming n is valid
  467. func (n FullName) Append(s Name) FullName {
  468. if n == "" {
  469. return FullName(s)
  470. }
  471. return n + "." + FullName(s)
  472. }