PageRenderTime 26ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/proto/properties.go

https://code.google.com/p/goprotobuf/
Go | 548 lines | 419 code | 46 blank | 83 comment | 73 complexity | ef721744f0bc0db14ce4e369fe4571dc MD5 | raw file
Possible License(s): BSD-3-Clause
  1. // Go support for Protocol Buffers - Google's data interchange format
  2. //
  3. // Copyright 2010 Google Inc. All rights reserved.
  4. // http://code.google.com/p/goprotobuf/
  5. //
  6. // Redistribution and use in source and binary forms, with or without
  7. // modification, are permitted provided that the following conditions are
  8. // met:
  9. //
  10. // * Redistributions of source code must retain the above copyright
  11. // notice, this list of conditions and the following disclaimer.
  12. // * Redistributions in binary form must reproduce the above
  13. // copyright notice, this list of conditions and the following disclaimer
  14. // in the documentation and/or other materials provided with the
  15. // distribution.
  16. // * Neither the name of Google Inc. nor the names of its
  17. // contributors may be used to endorse or promote products derived from
  18. // this software without specific prior written permission.
  19. //
  20. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. package proto
  32. /*
  33. * Routines for encoding data into the wire format for protocol buffers.
  34. */
  35. import (
  36. "fmt"
  37. "os"
  38. "reflect"
  39. "sort"
  40. "strconv"
  41. "strings"
  42. "sync"
  43. )
  44. const debug bool = false
  45. // Constants that identify the encoding of a value on the wire.
  46. const (
  47. WireVarint = 0
  48. WireFixed64 = 1
  49. WireBytes = 2
  50. WireStartGroup = 3
  51. WireEndGroup = 4
  52. WireFixed32 = 5
  53. )
  54. const startSize = 10 // initial slice/string sizes
  55. // Encoders are defined in encoder.go
  56. // An encoder outputs the full representation of a field, including its
  57. // tag and encoder type.
  58. type encoder func(p *Buffer, prop *Properties, base uintptr) error
  59. // A valueEncoder encodes a single integer in a particular encoding.
  60. type valueEncoder func(o *Buffer, x uint64) error
  61. // Decoders are defined in decode.go
  62. // A decoder creates a value from its wire representation.
  63. // Unrecognized subelements are saved in unrec.
  64. type decoder func(p *Buffer, prop *Properties, base uintptr) error
  65. // A valueDecoder decodes a single integer in a particular encoding.
  66. type valueDecoder func(o *Buffer) (x uint64, err error)
  67. // StructProperties represents properties for all the fields of a struct.
  68. type StructProperties struct {
  69. Prop []*Properties // properties for each field
  70. reqCount int // required count
  71. tags map[int]int // map from proto tag to struct field number
  72. origNames map[string]int // map from original name to struct field number
  73. order []int // list of struct field numbers in tag order
  74. }
  75. // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
  76. // See encoder.go, (*Buffer).enc_struct.
  77. func (sp *StructProperties) Len() int { return len(sp.order) }
  78. func (sp *StructProperties) Less(i, j int) bool {
  79. return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag
  80. }
  81. func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }
  82. // Properties represents the protocol-specific behavior of a single struct field.
  83. type Properties struct {
  84. Name string // name of the field, for error messages
  85. OrigName string // original name before protocol compiler (always set)
  86. Wire string
  87. WireType int
  88. Tag int
  89. Required bool
  90. Optional bool
  91. Repeated bool
  92. Packed bool // relevant for repeated primitives only
  93. Enum string // set for enum types only
  94. Default string // default value
  95. def_uint64 uint64
  96. enc encoder
  97. valEnc valueEncoder // set for bool and numeric types only
  98. offset uintptr
  99. tagcode []byte // encoding of EncodeVarint((Tag<<3)|WireType)
  100. tagbuf [8]byte
  101. stype reflect.Type
  102. isMarshaler bool
  103. isUnmarshaler bool
  104. dec decoder
  105. valDec valueDecoder // set for bool and numeric types only
  106. // If this is a packable field, this will be the decoder for the packed version of the field.
  107. packedDec decoder
  108. }
  109. // String formats the properties in the protobuf struct field tag style.
  110. func (p *Properties) String() string {
  111. s := p.Wire
  112. s = ","
  113. s += strconv.Itoa(p.Tag)
  114. if p.Required {
  115. s += ",req"
  116. }
  117. if p.Optional {
  118. s += ",opt"
  119. }
  120. if p.Repeated {
  121. s += ",rep"
  122. }
  123. if p.Packed {
  124. s += ",packed"
  125. }
  126. if p.OrigName != p.Name {
  127. s += ",name=" + p.OrigName
  128. }
  129. if len(p.Enum) > 0 {
  130. s += ",enum=" + p.Enum
  131. }
  132. if len(p.Default) > 0 {
  133. s += ",def=" + p.Default
  134. }
  135. return s
  136. }
  137. // Parse populates p by parsing a string in the protobuf struct field tag style.
  138. func (p *Properties) Parse(s string) {
  139. // "bytes,49,opt,name=foo,def=hello!"
  140. fields := strings.Split(s, ",") // breaks def=, but handled below.
  141. if len(fields) < 2 {
  142. fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s)
  143. return
  144. }
  145. p.Wire = fields[0]
  146. switch p.Wire {
  147. case "varint":
  148. p.WireType = WireVarint
  149. p.valEnc = (*Buffer).EncodeVarint
  150. p.valDec = (*Buffer).DecodeVarint
  151. case "fixed32":
  152. p.WireType = WireFixed32
  153. p.valEnc = (*Buffer).EncodeFixed32
  154. p.valDec = (*Buffer).DecodeFixed32
  155. case "fixed64":
  156. p.WireType = WireFixed64
  157. p.valEnc = (*Buffer).EncodeFixed64
  158. p.valDec = (*Buffer).DecodeFixed64
  159. case "zigzag32":
  160. p.WireType = WireVarint
  161. p.valEnc = (*Buffer).EncodeZigzag32
  162. p.valDec = (*Buffer).DecodeZigzag32
  163. case "zigzag64":
  164. p.WireType = WireVarint
  165. p.valEnc = (*Buffer).EncodeZigzag64
  166. p.valDec = (*Buffer).DecodeZigzag64
  167. case "bytes", "group":
  168. p.WireType = WireBytes
  169. // no numeric converter for non-numeric types
  170. default:
  171. fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s)
  172. return
  173. }
  174. var err error
  175. p.Tag, err = strconv.Atoi(fields[1])
  176. if err != nil {
  177. return
  178. }
  179. for i := 2; i < len(fields); i++ {
  180. f := fields[i]
  181. switch {
  182. case f == "req":
  183. p.Required = true
  184. case f == "opt":
  185. p.Optional = true
  186. case f == "rep":
  187. p.Repeated = true
  188. case f == "packed":
  189. p.Packed = true
  190. case strings.HasPrefix(f, "name="):
  191. p.OrigName = f[5:len(f)]
  192. case strings.HasPrefix(f, "enum="):
  193. p.Enum = f[5:len(f)]
  194. case strings.HasPrefix(f, "def="):
  195. p.Default = f[4:len(f)] // rest of string
  196. if i+1 < len(fields) {
  197. // Commas aren't escaped, and def is always last.
  198. p.Default += "," + strings.Join(fields[i+1:len(fields)], ",")
  199. break
  200. }
  201. }
  202. }
  203. }
  204. func logNoSliceEnc(t1, t2 reflect.Type) {
  205. fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2)
  206. }
  207. // Initialize the fields for encoding and decoding.
  208. func (p *Properties) setEncAndDec(typ reflect.Type) {
  209. p.enc = nil
  210. p.dec = nil
  211. switch t1 := typ; t1.Kind() {
  212. default:
  213. fmt.Fprintf(os.Stderr, "proto: no coders for %T\n", t1)
  214. break
  215. case reflect.Ptr:
  216. switch t2 := t1.Elem(); t2.Kind() {
  217. default:
  218. fmt.Fprintf(os.Stderr, "proto: no encoder function for %T -> %T\n", t1, t2)
  219. break
  220. case reflect.Bool:
  221. p.enc = (*Buffer).enc_bool
  222. p.dec = (*Buffer).dec_bool
  223. case reflect.Int32, reflect.Uint32:
  224. p.enc = (*Buffer).enc_int32
  225. p.dec = (*Buffer).dec_int32
  226. case reflect.Int64, reflect.Uint64:
  227. p.enc = (*Buffer).enc_int64
  228. p.dec = (*Buffer).dec_int64
  229. case reflect.Float32:
  230. p.enc = (*Buffer).enc_int32 // can just treat them as bits
  231. p.dec = (*Buffer).dec_int32
  232. case reflect.Float64:
  233. p.enc = (*Buffer).enc_int64 // can just treat them as bits
  234. p.dec = (*Buffer).dec_int64
  235. case reflect.String:
  236. p.enc = (*Buffer).enc_string
  237. p.dec = (*Buffer).dec_string
  238. case reflect.Struct:
  239. p.stype = t1
  240. p.isMarshaler = isMarshaler(t1)
  241. p.isUnmarshaler = isUnmarshaler(t1)
  242. if p.Wire == "bytes" {
  243. p.enc = (*Buffer).enc_struct_message
  244. p.dec = (*Buffer).dec_struct_message
  245. } else {
  246. p.enc = (*Buffer).enc_struct_group
  247. p.dec = (*Buffer).dec_struct_group
  248. }
  249. }
  250. case reflect.Slice:
  251. switch t2 := t1.Elem(); t2.Kind() {
  252. default:
  253. logNoSliceEnc(t1, t2)
  254. break
  255. case reflect.Bool:
  256. if p.Packed {
  257. p.enc = (*Buffer).enc_slice_packed_bool
  258. } else {
  259. p.enc = (*Buffer).enc_slice_bool
  260. }
  261. p.dec = (*Buffer).dec_slice_bool
  262. p.packedDec = (*Buffer).dec_slice_packed_bool
  263. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  264. switch t2.Bits() {
  265. case 32:
  266. if p.Packed {
  267. p.enc = (*Buffer).enc_slice_packed_int32
  268. } else {
  269. p.enc = (*Buffer).enc_slice_int32
  270. }
  271. p.dec = (*Buffer).dec_slice_int32
  272. p.packedDec = (*Buffer).dec_slice_packed_int32
  273. case 64:
  274. if p.Packed {
  275. p.enc = (*Buffer).enc_slice_packed_int64
  276. } else {
  277. p.enc = (*Buffer).enc_slice_int64
  278. }
  279. p.dec = (*Buffer).dec_slice_int64
  280. p.packedDec = (*Buffer).dec_slice_packed_int64
  281. case 8:
  282. if t2.Kind() == reflect.Uint8 {
  283. p.enc = (*Buffer).enc_slice_byte
  284. p.dec = (*Buffer).dec_slice_byte
  285. }
  286. default:
  287. logNoSliceEnc(t1, t2)
  288. break
  289. }
  290. case reflect.Float32, reflect.Float64:
  291. switch t2.Bits() {
  292. case 32:
  293. // can just treat them as bits
  294. if p.Packed {
  295. p.enc = (*Buffer).enc_slice_packed_int32
  296. } else {
  297. p.enc = (*Buffer).enc_slice_int32
  298. }
  299. p.dec = (*Buffer).dec_slice_int32
  300. p.packedDec = (*Buffer).dec_slice_packed_int32
  301. case 64:
  302. // can just treat them as bits
  303. if p.Packed {
  304. p.enc = (*Buffer).enc_slice_packed_int64
  305. } else {
  306. p.enc = (*Buffer).enc_slice_int64
  307. }
  308. p.dec = (*Buffer).dec_slice_int64
  309. p.packedDec = (*Buffer).dec_slice_packed_int64
  310. default:
  311. logNoSliceEnc(t1, t2)
  312. break
  313. }
  314. case reflect.String:
  315. p.enc = (*Buffer).enc_slice_string
  316. p.dec = (*Buffer).dec_slice_string
  317. case reflect.Ptr:
  318. switch t3 := t2.Elem(); t3.Kind() {
  319. default:
  320. fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3)
  321. break
  322. case reflect.Struct:
  323. p.stype = t2
  324. p.isMarshaler = isMarshaler(t2)
  325. p.isUnmarshaler = isUnmarshaler(t2)
  326. p.enc = (*Buffer).enc_slice_struct_group
  327. p.dec = (*Buffer).dec_slice_struct_group
  328. if p.Wire == "bytes" {
  329. p.enc = (*Buffer).enc_slice_struct_message
  330. p.dec = (*Buffer).dec_slice_struct_message
  331. }
  332. }
  333. case reflect.Slice:
  334. switch t2.Elem().Kind() {
  335. default:
  336. fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem())
  337. break
  338. case reflect.Uint8:
  339. p.enc = (*Buffer).enc_slice_slice_byte
  340. p.dec = (*Buffer).dec_slice_slice_byte
  341. }
  342. }
  343. }
  344. // precalculate tag code
  345. wire := p.WireType
  346. if p.Packed {
  347. wire = WireBytes
  348. }
  349. x := uint32(p.Tag)<<3 | uint32(wire)
  350. i := 0
  351. for i = 0; x > 127; i++ {
  352. p.tagbuf[i] = 0x80 | uint8(x&0x7F)
  353. x >>= 7
  354. }
  355. p.tagbuf[i] = uint8(x)
  356. p.tagcode = p.tagbuf[0 : i+1]
  357. }
  358. var (
  359. marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
  360. unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
  361. )
  362. // isMarshaler reports whether type t implements Marshaler.
  363. func isMarshaler(t reflect.Type) bool {
  364. // We're checking for (likely) pointer-receiver methods
  365. // so if t is not a pointer, something is very wrong.
  366. // The calls above only invoke isMarshaler on pointer types.
  367. if t.Kind() != reflect.Ptr {
  368. panic("proto: misuse of isMarshaler")
  369. }
  370. return t.Implements(marshalerType)
  371. }
  372. // isUnmarshaler reports whether type t implements Unmarshaler.
  373. func isUnmarshaler(t reflect.Type) bool {
  374. // We're checking for (likely) pointer-receiver methods
  375. // so if t is not a pointer, something is very wrong.
  376. // The calls above only invoke isUnmarshaler on pointer types.
  377. if t.Kind() != reflect.Ptr {
  378. panic("proto: misuse of isUnmarshaler")
  379. }
  380. return t.Implements(unmarshalerType)
  381. }
  382. // Init populates the properties from a protocol buffer struct tag.
  383. func (p *Properties) Init(typ reflect.Type, name, tag string, offset uintptr) {
  384. // "bytes,49,opt,def=hello!"
  385. p.Name = name
  386. p.OrigName = name
  387. p.offset = offset
  388. if tag == "" {
  389. return
  390. }
  391. p.Parse(tag)
  392. p.setEncAndDec(typ)
  393. }
  394. var (
  395. mutex sync.Mutex
  396. propertiesMap = make(map[reflect.Type]*StructProperties)
  397. )
  398. // GetProperties returns the list of properties for the type represented by t.
  399. func GetProperties(t reflect.Type) *StructProperties {
  400. mutex.Lock()
  401. if prop, ok := propertiesMap[t]; ok {
  402. mutex.Unlock()
  403. stats.Chit++
  404. return prop
  405. }
  406. stats.Cmiss++
  407. prop := new(StructProperties)
  408. // build properties
  409. prop.Prop = make([]*Properties, t.NumField())
  410. prop.order = make([]int, t.NumField())
  411. for i := 0; i < t.NumField(); i++ {
  412. f := t.Field(i)
  413. p := new(Properties)
  414. p.Init(f.Type, f.Name, f.Tag.Get("protobuf"), f.Offset)
  415. if f.Name == "XXX_extensions" { // special case
  416. p.enc = (*Buffer).enc_map
  417. p.dec = nil // not needed
  418. }
  419. prop.Prop[i] = p
  420. prop.order[i] = i
  421. if debug {
  422. print(i, " ", f.Name, " ", t.String(), " ")
  423. if p.Tag > 0 {
  424. print(p.String())
  425. }
  426. print("\n")
  427. }
  428. if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") {
  429. fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
  430. }
  431. }
  432. // Re-order prop.order.
  433. sort.Sort(prop)
  434. // build required counts
  435. // build tags
  436. reqCount := 0
  437. prop.tags = make(map[int]int)
  438. prop.origNames = make(map[string]int)
  439. for i, p := range prop.Prop {
  440. if strings.HasPrefix(p.Name, "XXX_") {
  441. // Internal fields should not appear in tags/origNames maps.
  442. // They are handled specially when encoding and decoding.
  443. continue
  444. }
  445. if p.Required {
  446. reqCount++
  447. }
  448. prop.tags[p.Tag] = i
  449. prop.origNames[p.OrigName] = i
  450. }
  451. prop.reqCount = reqCount
  452. propertiesMap[t] = prop
  453. mutex.Unlock()
  454. return prop
  455. }
  456. // Return the field index of the named field.
  457. // Returns nil if there is no such field.
  458. func fieldIndex(t reflect.Type, name string) []int {
  459. if field, ok := t.FieldByName(name); ok {
  460. return field.Index
  461. }
  462. return nil
  463. }
  464. // Return the Properties object for the x[0]'th field of the structure.
  465. func propByIndex(t reflect.Type, x []int) *Properties {
  466. if len(x) != 1 {
  467. fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t)
  468. return nil
  469. }
  470. prop := GetProperties(t)
  471. return prop.Prop[x[0]]
  472. }
  473. // Get the address and type of a pointer to a struct from an interface.
  474. func getbase(pb interface{}) (t reflect.Type, b uintptr, err error) {
  475. if pb == nil {
  476. err = ErrNil
  477. return
  478. }
  479. // get the reflect type of the pointer to the struct.
  480. t = reflect.TypeOf(pb)
  481. if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct {
  482. err = ErrNotPtr
  483. return
  484. }
  485. // get the address of the struct.
  486. value := reflect.ValueOf(pb)
  487. b = value.Pointer()
  488. return
  489. }
  490. // A global registry of enum types.
  491. // The generated code will register the generated maps by calling RegisterEnum.
  492. var enumNameMaps = make(map[string]map[int32]string)
  493. var enumValueMaps = make(map[string]map[string]int32)
  494. // RegisterEnum is called from the generated code to install the enum descriptor
  495. // maps into the global table to aid parsing ASCII protocol buffers.
  496. func RegisterEnum(typeName string, nameMap map[int32]string, valueMap map[string]int32) {
  497. if _, ok := enumNameMaps[typeName]; ok {
  498. panic("proto: duplicate enum registered: " + typeName)
  499. }
  500. enumNameMaps[typeName] = nameMap
  501. enumValueMaps[typeName] = valueMap
  502. }