proto.go 16 KB

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