proto.go 14 KB

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