properties.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  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. "os"
  44. "reflect"
  45. "sort"
  46. "strconv"
  47. "strings"
  48. "sync"
  49. )
  50. const debug bool = false
  51. // Constants that identify the encoding of a value on the wire.
  52. const (
  53. WireVarint = 0
  54. WireFixed64 = 1
  55. WireBytes = 2
  56. WireStartGroup = 3
  57. WireEndGroup = 4
  58. WireFixed32 = 5
  59. )
  60. // tagMap is an optimization over map[int]int for typical protocol buffer
  61. // use-cases. Encoded protocol buffers are often in tag order with small tag
  62. // numbers.
  63. type tagMap struct {
  64. fastTags []int
  65. slowTags map[int]int
  66. }
  67. // tagMapFastLimit is the upper bound on the tag number that will be stored in
  68. // the tagMap slice rather than its map.
  69. const tagMapFastLimit = 1024
  70. func (p *tagMap) get(t int) (int, bool) {
  71. if t > 0 && t < tagMapFastLimit {
  72. if t >= len(p.fastTags) {
  73. return 0, false
  74. }
  75. fi := p.fastTags[t]
  76. return fi, fi >= 0
  77. }
  78. fi, ok := p.slowTags[t]
  79. return fi, ok
  80. }
  81. func (p *tagMap) put(t int, fi int) {
  82. if t > 0 && t < tagMapFastLimit {
  83. for len(p.fastTags) < t+1 {
  84. p.fastTags = append(p.fastTags, -1)
  85. }
  86. p.fastTags[t] = fi
  87. return
  88. }
  89. if p.slowTags == nil {
  90. p.slowTags = make(map[int]int)
  91. }
  92. p.slowTags[t] = fi
  93. }
  94. // StructProperties represents properties for all the fields of a struct.
  95. // decoderTags and decoderOrigNames should only be used by the decoder.
  96. type StructProperties struct {
  97. Prop []*Properties // properties for each field
  98. reqCount int // required count
  99. decoderTags tagMap // map from proto tag to struct field number
  100. decoderOrigNames map[string]int // map from original name to struct field number
  101. order []int // list of struct field numbers in tag order
  102. // OneofTypes contains information about the oneof fields in this message.
  103. // It is keyed by the original name of a field.
  104. OneofTypes map[string]*OneofProperties
  105. }
  106. // OneofProperties represents information about a specific field in a oneof.
  107. type OneofProperties struct {
  108. Type reflect.Type // pointer to generated struct type for this oneof field
  109. Field int // struct field number of the containing oneof in the message
  110. Prop *Properties
  111. }
  112. // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
  113. // See encode.go, (*Buffer).enc_struct.
  114. func (sp *StructProperties) Len() int { return len(sp.order) }
  115. func (sp *StructProperties) Less(i, j int) bool {
  116. return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag
  117. }
  118. func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
  119. // Properties represents the protocol-specific behavior of a single struct field.
  120. type Properties struct {
  121. Name string // name of the field, for error messages
  122. OrigName string // original name before protocol compiler (always set)
  123. JSONName string // name to use for JSON; determined by protoc
  124. Wire string
  125. WireType int
  126. Tag int
  127. Required bool
  128. Optional bool
  129. Repeated bool
  130. Packed bool // relevant for repeated primitives only
  131. Enum string // set for enum types only
  132. proto3 bool // whether this is known to be a proto3 field; set for []byte only
  133. oneof bool // whether this is a oneof field
  134. Default string // default value
  135. HasDefault bool // whether an explicit default was provided
  136. CustomType string
  137. CastType string
  138. StdTime bool
  139. StdDuration 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. mkeyprop *Properties // set for map types only
  145. mvalprop *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. fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", 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. fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", 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. }
  255. }
  256. }
  257. var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
  258. // setFieldProps initializes the field properties for submessages and maps.
  259. func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
  260. isMap := typ.Kind() == reflect.Map
  261. if len(p.CustomType) > 0 && !isMap {
  262. p.ctype = typ
  263. p.setTag(lockGetProp)
  264. return
  265. }
  266. if p.StdTime && !isMap {
  267. p.setTag(lockGetProp)
  268. return
  269. }
  270. if p.StdDuration && !isMap {
  271. p.setTag(lockGetProp)
  272. return
  273. }
  274. switch t1 := typ; t1.Kind() {
  275. case reflect.Struct:
  276. p.stype = typ
  277. case reflect.Ptr:
  278. if t1.Elem().Kind() == reflect.Struct {
  279. p.stype = t1.Elem()
  280. }
  281. case reflect.Slice:
  282. switch t2 := t1.Elem(); t2.Kind() {
  283. case reflect.Ptr:
  284. switch t3 := t2.Elem(); t3.Kind() {
  285. case reflect.Struct:
  286. p.stype = t3
  287. }
  288. case reflect.Struct:
  289. p.stype = t2
  290. }
  291. case reflect.Map:
  292. p.mtype = t1
  293. p.mkeyprop = &Properties{}
  294. p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
  295. p.mvalprop = &Properties{}
  296. vtype := p.mtype.Elem()
  297. if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
  298. // The value type is not a message (*T) or bytes ([]byte),
  299. // so we need encoders for the pointer to this type.
  300. vtype = reflect.PtrTo(vtype)
  301. }
  302. p.mvalprop.CustomType = p.CustomType
  303. p.mvalprop.StdDuration = p.StdDuration
  304. p.mvalprop.StdTime = p.StdTime
  305. p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
  306. }
  307. p.setTag(lockGetProp)
  308. }
  309. func (p *Properties) setTag(lockGetProp bool) {
  310. if p.stype != nil {
  311. if lockGetProp {
  312. p.sprop = GetProperties(p.stype)
  313. } else {
  314. p.sprop = getPropertiesLocked(p.stype)
  315. }
  316. }
  317. }
  318. var (
  319. marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
  320. )
  321. // Init populates the properties from a protocol buffer struct tag.
  322. func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
  323. p.init(typ, name, tag, f, true)
  324. }
  325. func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {
  326. // "bytes,49,opt,def=hello!"
  327. p.Name = name
  328. p.OrigName = name
  329. if tag == "" {
  330. return
  331. }
  332. p.Parse(tag)
  333. p.setFieldProps(typ, f, lockGetProp)
  334. }
  335. var (
  336. propertiesMu sync.RWMutex
  337. propertiesMap = make(map[reflect.Type]*StructProperties)
  338. )
  339. // GetProperties returns the list of properties for the type represented by t.
  340. // t must represent a generated struct type of a protocol message.
  341. func GetProperties(t reflect.Type) *StructProperties {
  342. if t.Kind() != reflect.Struct {
  343. panic("proto: type must have kind struct")
  344. }
  345. // Most calls to GetProperties in a long-running program will be
  346. // retrieving details for types we have seen before.
  347. propertiesMu.RLock()
  348. sprop, ok := propertiesMap[t]
  349. propertiesMu.RUnlock()
  350. if ok {
  351. if collectStats {
  352. stats.Chit++
  353. }
  354. return sprop
  355. }
  356. propertiesMu.Lock()
  357. sprop = getPropertiesLocked(t)
  358. propertiesMu.Unlock()
  359. return sprop
  360. }
  361. // getPropertiesLocked requires that propertiesMu is held.
  362. func getPropertiesLocked(t reflect.Type) *StructProperties {
  363. if prop, ok := propertiesMap[t]; ok {
  364. if collectStats {
  365. stats.Chit++
  366. }
  367. return prop
  368. }
  369. if collectStats {
  370. stats.Cmiss++
  371. }
  372. prop := new(StructProperties)
  373. // in case of recursive protos, fill this in now.
  374. propertiesMap[t] = prop
  375. // build properties
  376. prop.Prop = make([]*Properties, t.NumField())
  377. prop.order = make([]int, t.NumField())
  378. isOneofMessage := false
  379. for i := 0; i < t.NumField(); i++ {
  380. f := t.Field(i)
  381. p := new(Properties)
  382. name := f.Name
  383. p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
  384. oneof := f.Tag.Get("protobuf_oneof") // special case
  385. if oneof != "" {
  386. isOneofMessage = true
  387. // Oneof fields don't use the traditional protobuf tag.
  388. p.OrigName = oneof
  389. }
  390. prop.Prop[i] = p
  391. prop.order[i] = i
  392. if debug {
  393. print(i, " ", f.Name, " ", t.String(), " ")
  394. if p.Tag > 0 {
  395. print(p.String())
  396. }
  397. print("\n")
  398. }
  399. }
  400. // Re-order prop.order.
  401. sort.Sort(prop)
  402. type oneofMessage interface {
  403. XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
  404. }
  405. if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); isOneofMessage && ok {
  406. var oots []interface{}
  407. _, _, _, oots = om.XXX_OneofFuncs()
  408. // Interpret oneof metadata.
  409. prop.OneofTypes = make(map[string]*OneofProperties)
  410. for _, oot := range oots {
  411. oop := &OneofProperties{
  412. Type: reflect.ValueOf(oot).Type(), // *T
  413. Prop: new(Properties),
  414. }
  415. sft := oop.Type.Elem().Field(0)
  416. oop.Prop.Name = sft.Name
  417. oop.Prop.Parse(sft.Tag.Get("protobuf"))
  418. // There will be exactly one interface field that
  419. // this new value is assignable to.
  420. for i := 0; i < t.NumField(); i++ {
  421. f := t.Field(i)
  422. if f.Type.Kind() != reflect.Interface {
  423. continue
  424. }
  425. if !oop.Type.AssignableTo(f.Type) {
  426. continue
  427. }
  428. oop.Field = i
  429. break
  430. }
  431. prop.OneofTypes[oop.Prop.OrigName] = oop
  432. }
  433. }
  434. // build required counts
  435. // build tags
  436. reqCount := 0
  437. prop.decoderOrigNames = make(map[string]int)
  438. for i, p := range prop.Prop {
  439. if strings.HasPrefix(p.Name, "XXX_") {
  440. // Internal fields should not appear in tags/origNames maps.
  441. // They are handled specially when encoding and decoding.
  442. continue
  443. }
  444. if p.Required {
  445. reqCount++
  446. }
  447. prop.decoderTags.put(p.Tag, i)
  448. prop.decoderOrigNames[p.OrigName] = i
  449. }
  450. prop.reqCount = reqCount
  451. return prop
  452. }
  453. // A global registry of enum types.
  454. // The generated code will register the generated maps by calling RegisterEnum.
  455. var enumValueMaps = make(map[string]map[string]int32)
  456. var enumStringMaps = make(map[string]map[int32]string)
  457. // RegisterEnum is called from the generated code to install the enum descriptor
  458. // maps into the global table to aid parsing text format protocol buffers.
  459. func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {
  460. if _, ok := enumValueMaps[typeName]; ok {
  461. panic("proto: duplicate enum registered: " + typeName)
  462. }
  463. enumValueMaps[typeName] = valueMap
  464. if _, ok := enumStringMaps[typeName]; ok {
  465. panic("proto: duplicate enum registered: " + typeName)
  466. }
  467. enumStringMaps[typeName] = unusedNameMap
  468. }
  469. // EnumValueMap returns the mapping from names to integers of the
  470. // enum type enumType, or a nil if not found.
  471. func EnumValueMap(enumType string) map[string]int32 {
  472. return enumValueMaps[enumType]
  473. }
  474. // A registry of all linked message types.
  475. // The string is a fully-qualified proto name ("pkg.Message").
  476. var (
  477. protoTypedNils = make(map[string]Message) // a map from proto names to typed nil pointers
  478. protoMapTypes = make(map[string]reflect.Type) // a map from proto names to map types
  479. revProtoTypes = make(map[reflect.Type]string)
  480. )
  481. // RegisterType is called from generated code and maps from the fully qualified
  482. // proto name to the type (pointer to struct) of the protocol buffer.
  483. func RegisterType(x Message, name string) {
  484. if _, ok := protoTypedNils[name]; ok {
  485. // TODO: Some day, make this a panic.
  486. log.Printf("proto: duplicate proto type registered: %s", name)
  487. return
  488. }
  489. t := reflect.TypeOf(x)
  490. if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 {
  491. // Generated code always calls RegisterType with nil x.
  492. // This check is just for extra safety.
  493. protoTypedNils[name] = x
  494. } else {
  495. protoTypedNils[name] = reflect.Zero(t).Interface().(Message)
  496. }
  497. revProtoTypes[t] = name
  498. }
  499. // RegisterMapType is called from generated code and maps from the fully qualified
  500. // proto name to the native map type of the proto map definition.
  501. func RegisterMapType(x interface{}, name string) {
  502. if reflect.TypeOf(x).Kind() != reflect.Map {
  503. panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name))
  504. }
  505. if _, ok := protoMapTypes[name]; ok {
  506. log.Printf("proto: duplicate proto type registered: %s", name)
  507. return
  508. }
  509. t := reflect.TypeOf(x)
  510. protoMapTypes[name] = t
  511. revProtoTypes[t] = name
  512. }
  513. // MessageName returns the fully-qualified proto name for the given message type.
  514. func MessageName(x Message) string {
  515. type xname interface {
  516. XXX_MessageName() string
  517. }
  518. if m, ok := x.(xname); ok {
  519. return m.XXX_MessageName()
  520. }
  521. return revProtoTypes[reflect.TypeOf(x)]
  522. }
  523. // MessageType returns the message type (pointer to struct) for a named message.
  524. // The type is not guaranteed to implement proto.Message if the name refers to a
  525. // map entry.
  526. func MessageType(name string) reflect.Type {
  527. if t, ok := protoTypedNils[name]; ok {
  528. return reflect.TypeOf(t)
  529. }
  530. return protoMapTypes[name]
  531. }
  532. // A registry of all linked proto files.
  533. var (
  534. protoFiles = make(map[string][]byte) // file name => fileDescriptor
  535. )
  536. // RegisterFile is called from generated code and maps from the
  537. // full file name of a .proto file to its compressed FileDescriptorProto.
  538. func RegisterFile(filename string, fileDescriptor []byte) {
  539. protoFiles[filename] = fileDescriptor
  540. }
  541. // FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
  542. func FileDescriptor(filename string) []byte { return protoFiles[filename] }