properties.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. // Protocol Buffers for Go with Gadgets
  2. //
  3. // Copyright (c) 2013, The GoGo Authors. All rights reserved.
  4. // http://github.com/gogo/protobuf
  5. //
  6. // Go support for Protocol Buffers - Google's data interchange format
  7. //
  8. // Copyright 2010 The Go Authors. All rights reserved.
  9. // https://github.com/golang/protobuf
  10. //
  11. // Redistribution and use in source and binary forms, with or without
  12. // modification, are permitted provided that the following conditions are
  13. // met:
  14. //
  15. // * Redistributions of source code must retain the above copyright
  16. // notice, this list of conditions and the following disclaimer.
  17. // * Redistributions in binary form must reproduce the above
  18. // copyright notice, this list of conditions and the following disclaimer
  19. // in the documentation and/or other materials provided with the
  20. // distribution.
  21. // * Neither the name of Google Inc. nor the names of its
  22. // contributors may be used to endorse or promote products derived from
  23. // this software without specific prior written permission.
  24. //
  25. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  26. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  28. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  29. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  30. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  31. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  32. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  33. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  34. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  35. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36. package proto
  37. /*
  38. * Routines for encoding data into the wire format for protocol buffers.
  39. */
  40. import (
  41. "fmt"
  42. "log"
  43. "reflect"
  44. "sort"
  45. "strconv"
  46. "strings"
  47. "sync"
  48. )
  49. const debug bool = false
  50. // Constants that identify the encoding of a value on the wire.
  51. const (
  52. WireVarint = 0
  53. WireFixed64 = 1
  54. WireBytes = 2
  55. WireStartGroup = 3
  56. WireEndGroup = 4
  57. WireFixed32 = 5
  58. )
  59. // tagMap is an optimization over map[int]int for typical protocol buffer
  60. // use-cases. Encoded protocol buffers are often in tag order with small tag
  61. // numbers.
  62. type tagMap struct {
  63. fastTags []int
  64. slowTags map[int]int
  65. }
  66. // tagMapFastLimit is the upper bound on the tag number that will be stored in
  67. // the tagMap slice rather than its map.
  68. const tagMapFastLimit = 1024
  69. func (p *tagMap) get(t int) (int, bool) {
  70. if t > 0 && t < tagMapFastLimit {
  71. if t >= len(p.fastTags) {
  72. return 0, false
  73. }
  74. fi := p.fastTags[t]
  75. return fi, fi >= 0
  76. }
  77. fi, ok := p.slowTags[t]
  78. return fi, ok
  79. }
  80. func (p *tagMap) put(t int, fi int) {
  81. if t > 0 && t < tagMapFastLimit {
  82. for len(p.fastTags) < t+1 {
  83. p.fastTags = append(p.fastTags, -1)
  84. }
  85. p.fastTags[t] = fi
  86. return
  87. }
  88. if p.slowTags == nil {
  89. p.slowTags = make(map[int]int)
  90. }
  91. p.slowTags[t] = fi
  92. }
  93. // StructProperties represents properties for all the fields of a struct.
  94. // decoderTags and decoderOrigNames should only be used by the decoder.
  95. type StructProperties struct {
  96. Prop []*Properties // properties for each field
  97. reqCount int // required count
  98. decoderTags tagMap // map from proto tag to struct field number
  99. decoderOrigNames map[string]int // map from original name to struct field number
  100. order []int // list of struct field numbers in tag order
  101. // OneofTypes contains information about the oneof fields in this message.
  102. // It is keyed by the original name of a field.
  103. OneofTypes map[string]*OneofProperties
  104. }
  105. // OneofProperties represents information about a specific field in a oneof.
  106. type OneofProperties struct {
  107. Type reflect.Type // pointer to generated struct type for this oneof field
  108. Field int // struct field number of the containing oneof in the message
  109. Prop *Properties
  110. }
  111. // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
  112. // See encode.go, (*Buffer).enc_struct.
  113. func (sp *StructProperties) Len() int { return len(sp.order) }
  114. func (sp *StructProperties) Less(i, j int) bool {
  115. return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag
  116. }
  117. func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
  118. // Properties represents the protocol-specific behavior of a single struct field.
  119. type Properties struct {
  120. Name string // name of the field, for error messages
  121. OrigName string // original name before protocol compiler (always set)
  122. JSONName string // name to use for JSON; determined by protoc
  123. Wire string
  124. WireType int
  125. Tag int
  126. Required bool
  127. Optional bool
  128. Repeated bool
  129. Packed bool // relevant for repeated primitives only
  130. Enum string // set for enum types only
  131. proto3 bool // whether this is known to be a proto3 field
  132. oneof bool // whether this is a oneof field
  133. Default string // default value
  134. HasDefault bool // whether an explicit default was provided
  135. CustomType string
  136. CastType string
  137. StdTime bool
  138. StdDuration bool
  139. WktPointer bool
  140. stype reflect.Type // set for struct types only
  141. ctype reflect.Type // set for custom types only
  142. sprop *StructProperties // set for struct types only
  143. mtype reflect.Type // set for map types only
  144. MapKeyProp *Properties // set for map types only
  145. MapValProp *Properties // set for map types only
  146. }
  147. // String formats the properties in the protobuf struct field tag style.
  148. func (p *Properties) String() string {
  149. s := p.Wire
  150. s += ","
  151. s += strconv.Itoa(p.Tag)
  152. if p.Required {
  153. s += ",req"
  154. }
  155. if p.Optional {
  156. s += ",opt"
  157. }
  158. if p.Repeated {
  159. s += ",rep"
  160. }
  161. if p.Packed {
  162. s += ",packed"
  163. }
  164. s += ",name=" + p.OrigName
  165. if p.JSONName != p.OrigName {
  166. s += ",json=" + p.JSONName
  167. }
  168. if p.proto3 {
  169. s += ",proto3"
  170. }
  171. if p.oneof {
  172. s += ",oneof"
  173. }
  174. if len(p.Enum) > 0 {
  175. s += ",enum=" + p.Enum
  176. }
  177. if p.HasDefault {
  178. s += ",def=" + p.Default
  179. }
  180. return s
  181. }
  182. // Parse populates p by parsing a string in the protobuf struct field tag style.
  183. func (p *Properties) Parse(s string) {
  184. // "bytes,49,opt,name=foo,def=hello!"
  185. fields := strings.Split(s, ",") // breaks def=, but handled below.
  186. if len(fields) < 2 {
  187. log.Printf("proto: tag has too few fields: %q", s)
  188. return
  189. }
  190. p.Wire = fields[0]
  191. switch p.Wire {
  192. case "varint":
  193. p.WireType = WireVarint
  194. case "fixed32":
  195. p.WireType = WireFixed32
  196. case "fixed64":
  197. p.WireType = WireFixed64
  198. case "zigzag32":
  199. p.WireType = WireVarint
  200. case "zigzag64":
  201. p.WireType = WireVarint
  202. case "bytes", "group":
  203. p.WireType = WireBytes
  204. // no numeric converter for non-numeric types
  205. default:
  206. log.Printf("proto: tag has unknown wire type: %q", s)
  207. return
  208. }
  209. var err error
  210. p.Tag, err = strconv.Atoi(fields[1])
  211. if err != nil {
  212. return
  213. }
  214. outer:
  215. for i := 2; i < len(fields); i++ {
  216. f := fields[i]
  217. switch {
  218. case f == "req":
  219. p.Required = true
  220. case f == "opt":
  221. p.Optional = true
  222. case f == "rep":
  223. p.Repeated = true
  224. case f == "packed":
  225. p.Packed = true
  226. case strings.HasPrefix(f, "name="):
  227. p.OrigName = f[5:]
  228. case strings.HasPrefix(f, "json="):
  229. p.JSONName = f[5:]
  230. case strings.HasPrefix(f, "enum="):
  231. p.Enum = f[5:]
  232. case f == "proto3":
  233. p.proto3 = true
  234. case f == "oneof":
  235. p.oneof = true
  236. case strings.HasPrefix(f, "def="):
  237. p.HasDefault = true
  238. p.Default = f[4:] // rest of string
  239. if i+1 < len(fields) {
  240. // Commas aren't escaped, and def is always last.
  241. p.Default += "," + strings.Join(fields[i+1:], ",")
  242. break outer
  243. }
  244. case strings.HasPrefix(f, "embedded="):
  245. p.OrigName = strings.Split(f, "=")[1]
  246. case strings.HasPrefix(f, "customtype="):
  247. p.CustomType = strings.Split(f, "=")[1]
  248. case strings.HasPrefix(f, "casttype="):
  249. p.CastType = strings.Split(f, "=")[1]
  250. case f == "stdtime":
  251. p.StdTime = true
  252. case f == "stdduration":
  253. p.StdDuration = true
  254. case f == "wktptr":
  255. p.WktPointer = true
  256. }
  257. }
  258. }
  259. var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
  260. // setFieldProps initializes the field properties for submessages and maps.
  261. func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
  262. isMap := typ.Kind() == reflect.Map
  263. if len(p.CustomType) > 0 && !isMap {
  264. p.ctype = typ
  265. p.setTag(lockGetProp)
  266. return
  267. }
  268. if p.StdTime && !isMap {
  269. p.setTag(lockGetProp)
  270. return
  271. }
  272. if p.StdDuration && !isMap {
  273. p.setTag(lockGetProp)
  274. return
  275. }
  276. if p.WktPointer && !isMap {
  277. p.setTag(lockGetProp)
  278. return
  279. }
  280. switch t1 := typ; t1.Kind() {
  281. case reflect.Struct:
  282. p.stype = typ
  283. case reflect.Ptr:
  284. if t1.Elem().Kind() == reflect.Struct {
  285. p.stype = t1.Elem()
  286. }
  287. case reflect.Slice:
  288. switch t2 := t1.Elem(); t2.Kind() {
  289. case reflect.Ptr:
  290. switch t3 := t2.Elem(); t3.Kind() {
  291. case reflect.Struct:
  292. p.stype = t3
  293. }
  294. case reflect.Struct:
  295. p.stype = t2
  296. }
  297. case reflect.Map:
  298. p.mtype = t1
  299. p.MapKeyProp = &Properties{}
  300. p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
  301. p.MapValProp = &Properties{}
  302. vtype := p.mtype.Elem()
  303. if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
  304. // The value type is not a message (*T) or bytes ([]byte),
  305. // so we need encoders for the pointer to this type.
  306. vtype = reflect.PtrTo(vtype)
  307. }
  308. p.MapValProp.CustomType = p.CustomType
  309. p.MapValProp.StdDuration = p.StdDuration
  310. p.MapValProp.StdTime = p.StdTime
  311. p.MapValProp.WktPointer = p.WktPointer
  312. p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
  313. }
  314. p.setTag(lockGetProp)
  315. }
  316. func (p *Properties) setTag(lockGetProp bool) {
  317. if p.stype != nil {
  318. if lockGetProp {
  319. p.sprop = GetProperties(p.stype)
  320. } else {
  321. p.sprop = getPropertiesLocked(p.stype)
  322. }
  323. }
  324. }
  325. var (
  326. marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
  327. )
  328. // Init populates the properties from a protocol buffer struct tag.
  329. func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
  330. p.init(typ, name, tag, f, true)
  331. }
  332. func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
  333. // "bytes,49,opt,def=hello!"
  334. p.Name = name
  335. p.OrigName = name
  336. if tag == "" {
  337. return
  338. }
  339. p.Parse(tag)
  340. p.setFieldProps(typ, f, lockGetProp)
  341. }
  342. var (
  343. propertiesMu sync.RWMutex
  344. propertiesMap = make(map[reflect.Type]*StructProperties)
  345. )
  346. // GetProperties returns the list of properties for the type represented by t.
  347. // t must represent a generated struct type of a protocol message.
  348. func GetProperties(t reflect.Type) *StructProperties {
  349. if t.Kind() != reflect.Struct {
  350. panic("proto: type must have kind struct")
  351. }
  352. // Most calls to GetProperties in a long-running program will be
  353. // retrieving details for types we have seen before.
  354. propertiesMu.RLock()
  355. sprop, ok := propertiesMap[t]
  356. propertiesMu.RUnlock()
  357. if ok {
  358. return sprop
  359. }
  360. propertiesMu.Lock()
  361. sprop = getPropertiesLocked(t)
  362. propertiesMu.Unlock()
  363. return sprop
  364. }
  365. type (
  366. oneofFuncsIface interface {
  367. XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
  368. }
  369. oneofWrappersIface interface {
  370. XXX_OneofWrappers() []interface{}
  371. }
  372. )
  373. // getPropertiesLocked requires that propertiesMu is held.
  374. func getPropertiesLocked(t reflect.Type) *StructProperties {
  375. if prop, ok := propertiesMap[t]; ok {
  376. return prop
  377. }
  378. prop := new(StructProperties)
  379. // in case of recursive protos, fill this in now.
  380. propertiesMap[t] = prop
  381. // build properties
  382. prop.Prop = make([]*Properties, t.NumField())
  383. prop.order = make([]int, t.NumField())
  384. isOneofMessage := false
  385. for i := 0; i < t.NumField(); i++ {
  386. f := t.Field(i)
  387. p := new(Properties)
  388. name := f.Name
  389. p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
  390. oneof := f.Tag.Get("protobuf_oneof") // special case
  391. if oneof != "" {
  392. isOneofMessage = true
  393. // Oneof fields don't use the traditional protobuf tag.
  394. p.OrigName = oneof
  395. }
  396. prop.Prop[i] = p
  397. prop.order[i] = i
  398. if debug {
  399. print(i, " ", f.Name, " ", t.String(), " ")
  400. if p.Tag > 0 {
  401. print(p.String())
  402. }
  403. print("\n")
  404. }
  405. }
  406. // Re-order prop.order.
  407. sort.Sort(prop)
  408. if isOneofMessage {
  409. var oots []interface{}
  410. switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {
  411. case oneofFuncsIface:
  412. _, _, _, oots = m.XXX_OneofFuncs()
  413. case oneofWrappersIface:
  414. oots = m.XXX_OneofWrappers()
  415. }
  416. if len(oots) > 0 {
  417. // Interpret oneof metadata.
  418. prop.OneofTypes = make(map[string]*OneofProperties)
  419. for _, oot := range oots {
  420. oop := &OneofProperties{
  421. Type: reflect.ValueOf(oot).Type(), // *T
  422. Prop: new(Properties),
  423. }
  424. sft := oop.Type.Elem().Field(0)
  425. oop.Prop.Name = sft.Name
  426. oop.Prop.Parse(sft.Tag.Get("protobuf"))
  427. // There will be exactly one interface field that
  428. // this new value is assignable to.
  429. for i := 0; i < t.NumField(); i++ {
  430. f := t.Field(i)
  431. if f.Type.Kind() != reflect.Interface {
  432. continue
  433. }
  434. if !oop.Type.AssignableTo(f.Type) {
  435. continue
  436. }
  437. oop.Field = i
  438. break
  439. }
  440. prop.OneofTypes[oop.Prop.OrigName] = oop
  441. }
  442. }
  443. }
  444. // build required counts
  445. // build tags
  446. reqCount := 0
  447. prop.decoderOrigNames = make(map[string]int)
  448. for i, p := range prop.Prop {
  449. if strings.HasPrefix(p.Name, "XXX_") {
  450. // Internal fields should not appear in tags/origNames maps.
  451. // They are handled specially when encoding and decoding.
  452. continue
  453. }
  454. if p.Required {
  455. reqCount++
  456. }
  457. prop.decoderTags.put(p.Tag, i)
  458. prop.decoderOrigNames[p.OrigName] = i
  459. }
  460. prop.reqCount = reqCount
  461. return prop
  462. }
  463. // A global registry of enum types.
  464. // The generated code will register the generated maps by calling RegisterEnum.
  465. var enumValueMaps = make(map[string]map[string]int32)
  466. var enumStringMaps = make(map[string]map[int32]string)
  467. // RegisterEnum is called from the generated code to install the enum descriptor
  468. // maps into the global table to aid parsing text format protocol buffers.
  469. func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
  470. if _, ok := enumValueMaps[typeName]; ok {
  471. panic("proto: duplicate enum registered: " + typeName)
  472. }
  473. enumValueMaps[typeName] = valueMap
  474. if _, ok := enumStringMaps[typeName]; ok {
  475. panic("proto: duplicate enum registered: " + typeName)
  476. }
  477. enumStringMaps[typeName] = unusedNameMap
  478. }
  479. // EnumValueMap returns the mapping from names to integers of the
  480. // enum type enumType, or a nil if not found.
  481. func EnumValueMap(enumType string) map[string]int32 {
  482. return enumValueMaps[enumType]
  483. }
  484. // A registry of all linked message types.
  485. // The string is a fully-qualified proto name ("pkg.Message").
  486. var (
  487. protoTypedNils = make(map[string]Message) // a map from proto names to typed nil pointers
  488. protoMapTypes = make(map[string]reflect.Type) // a map from proto names to map types
  489. revProtoTypes = make(map[reflect.Type]string)
  490. )
  491. // RegisterType is called from generated code and maps from the fully qualified
  492. // proto name to the type (pointer to struct) of the protocol buffer.
  493. func RegisterType(x Message, name string) {
  494. if _, ok := protoTypedNils[name]; ok {
  495. // TODO: Some day, make this a panic.
  496. log.Printf("proto: duplicate proto type registered: %s", name)
  497. return
  498. }
  499. t := reflect.TypeOf(x)
  500. if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 {
  501. // Generated code always calls RegisterType with nil x.
  502. // This check is just for extra safety.
  503. protoTypedNils[name] = x
  504. } else {
  505. protoTypedNils[name] = reflect.Zero(t).Interface().(Message)
  506. }
  507. revProtoTypes[t] = name
  508. }
  509. // RegisterMapType is called from generated code and maps from the fully qualified
  510. // proto name to the native map type of the proto map definition.
  511. func RegisterMapType(x interface{}, name string) {
  512. if reflect.TypeOf(x).Kind() != reflect.Map {
  513. panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name))
  514. }
  515. if _, ok := protoMapTypes[name]; ok {
  516. log.Printf("proto: duplicate proto type registered: %s", name)
  517. return
  518. }
  519. t := reflect.TypeOf(x)
  520. protoMapTypes[name] = t
  521. revProtoTypes[t] = name
  522. }
  523. // MessageName returns the fully-qualified proto name for the given message type.
  524. func MessageName(x Message) string {
  525. type xname interface {
  526. XXX_MessageName() string
  527. }
  528. if m, ok := x.(xname); ok {
  529. return m.XXX_MessageName()
  530. }
  531. return revProtoTypes[reflect.TypeOf(x)]
  532. }
  533. // MessageType returns the message type (pointer to struct) for a named message.
  534. // The type is not guaranteed to implement proto.Message if the name refers to a
  535. // map entry.
  536. func MessageType(name string) reflect.Type {
  537. if t, ok := protoTypedNils[name]; ok {
  538. return reflect.TypeOf(t)
  539. }
  540. return protoMapTypes[name]
  541. }
  542. // A registry of all linked proto files.
  543. var (
  544. protoFiles = make(map[string][]byte) // file name => fileDescriptor
  545. )
  546. // RegisterFile is called from generated code and maps from the
  547. // full file name of a .proto file to its compressed FileDescriptorProto.
  548. func RegisterFile(filename string, fileDescriptor []byte) {
  549. protoFiles[filename] = fileDescriptor
  550. }
  551. // FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
  552. func FileDescriptor(filename string) []byte { return protoFiles[filename] }