You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

619 lines
12 KiB

  1. package gen
  2. import (
  3. "fmt"
  4. "strings"
  5. )
  6. var (
  7. identNext = 0
  8. identPrefix = "za"
  9. )
  10. func resetIdent(prefix string) {
  11. identPrefix = prefix
  12. identNext = 0
  13. }
  14. // generate a random identifier name
  15. func randIdent() string {
  16. identNext++
  17. return fmt.Sprintf("%s%04d", identPrefix, identNext)
  18. }
  19. // This code defines the type declaration tree.
  20. //
  21. // Consider the following:
  22. //
  23. // type Marshaler struct {
  24. // Thing1 *float64 `msg:"thing1"`
  25. // Body []byte `msg:"body"`
  26. // }
  27. //
  28. // A parser using this generator as a backend
  29. // should parse the above into:
  30. //
  31. // var val Elem = &Ptr{
  32. // name: "z",
  33. // Value: &Struct{
  34. // Name: "Marshaler",
  35. // Fields: []StructField{
  36. // {
  37. // FieldTag: "thing1",
  38. // FieldElem: &Ptr{
  39. // name: "z.Thing1",
  40. // Value: &BaseElem{
  41. // name: "*z.Thing1",
  42. // Value: Float64,
  43. // Convert: false,
  44. // },
  45. // },
  46. // },
  47. // {
  48. // FieldTag: "body",
  49. // FieldElem: &BaseElem{
  50. // name: "z.Body",
  51. // Value: Bytes,
  52. // Convert: false,
  53. // },
  54. // },
  55. // },
  56. // },
  57. // }
  58. // Base is one of the
  59. // base types
  60. type Primitive uint8
  61. // this is effectively the
  62. // list of currently available
  63. // ReadXxxx / WriteXxxx methods.
  64. const (
  65. Invalid Primitive = iota
  66. Bytes
  67. String
  68. Float32
  69. Float64
  70. Complex64
  71. Complex128
  72. Uint
  73. Uint8
  74. Uint16
  75. Uint32
  76. Uint64
  77. Byte
  78. Int
  79. Int8
  80. Int16
  81. Int32
  82. Int64
  83. Bool
  84. Intf // interface{}
  85. Time // time.Time
  86. Ext // extension
  87. IDENT // IDENT means an unrecognized identifier
  88. )
  89. // all of the recognized identities
  90. // that map to primitive types
  91. var primitives = map[string]Primitive{
  92. "[]byte": Bytes,
  93. "string": String,
  94. "float32": Float32,
  95. "float64": Float64,
  96. "complex64": Complex64,
  97. "complex128": Complex128,
  98. "uint": Uint,
  99. "uint8": Uint8,
  100. "uint16": Uint16,
  101. "uint32": Uint32,
  102. "uint64": Uint64,
  103. "byte": Byte,
  104. "rune": Int32,
  105. "int": Int,
  106. "int8": Int8,
  107. "int16": Int16,
  108. "int32": Int32,
  109. "int64": Int64,
  110. "bool": Bool,
  111. "interface{}": Intf,
  112. "time.Time": Time,
  113. "msgp.Extension": Ext,
  114. }
  115. // types built into the library
  116. // that satisfy all of the
  117. // interfaces.
  118. var builtins = map[string]struct{}{
  119. "msgp.Raw": struct{}{},
  120. "msgp.Number": struct{}{},
  121. }
  122. // common data/methods for every Elem
  123. type common struct{ vname, alias string }
  124. func (c *common) SetVarname(s string) { c.vname = s }
  125. func (c *common) Varname() string { return c.vname }
  126. func (c *common) Alias(typ string) { c.alias = typ }
  127. func (c *common) hidden() {}
  128. func IsPrintable(e Elem) bool {
  129. if be, ok := e.(*BaseElem); ok && !be.Printable() {
  130. return false
  131. }
  132. return true
  133. }
  134. // Elem is a go type capable of being
  135. // serialized into MessagePack. It is
  136. // implemented by *Ptr, *Struct, *Array,
  137. // *Slice, *Map, and *BaseElem.
  138. type Elem interface {
  139. // SetVarname sets this nodes
  140. // variable name and recursively
  141. // sets the names of all its children.
  142. // In general, this should only be
  143. // called on the parent of the tree.
  144. SetVarname(s string)
  145. // Varname returns the variable
  146. // name of the element.
  147. Varname() string
  148. // TypeName is the canonical
  149. // go type name of the node
  150. // e.g. "string", "int", "map[string]float64"
  151. // OR the alias name, if it has been set.
  152. TypeName() string
  153. // Alias sets a type (alias) name
  154. Alias(typ string)
  155. // Copy should perform a deep copy of the object
  156. Copy() Elem
  157. // Complexity returns a measure of the
  158. // complexity of element (greater than
  159. // or equal to 1.)
  160. Complexity() int
  161. hidden()
  162. }
  163. // Ident returns the *BaseElem that corresponds
  164. // to the provided identity.
  165. func Ident(id string) *BaseElem {
  166. p, ok := primitives[id]
  167. if ok {
  168. return &BaseElem{Value: p}
  169. }
  170. be := &BaseElem{Value: IDENT}
  171. be.Alias(id)
  172. return be
  173. }
  174. type Array struct {
  175. common
  176. Index string // index variable name
  177. Size string // array size
  178. Els Elem // child
  179. }
  180. func (a *Array) SetVarname(s string) {
  181. a.common.SetVarname(s)
  182. ridx:
  183. a.Index = randIdent()
  184. // try to avoid using the same
  185. // index as a parent slice
  186. if strings.Contains(a.Varname(), a.Index) {
  187. goto ridx
  188. }
  189. a.Els.SetVarname(fmt.Sprintf("%s[%s]", a.Varname(), a.Index))
  190. }
  191. func (a *Array) TypeName() string {
  192. if a.common.alias != "" {
  193. return a.common.alias
  194. }
  195. a.common.Alias(fmt.Sprintf("[%s]%s", a.Size, a.Els.TypeName()))
  196. return a.common.alias
  197. }
  198. func (a *Array) Copy() Elem {
  199. b := *a
  200. b.Els = a.Els.Copy()
  201. return &b
  202. }
  203. func (a *Array) Complexity() int { return 1 + a.Els.Complexity() }
  204. // Map is a map[string]Elem
  205. type Map struct {
  206. common
  207. Keyidx string // key variable name
  208. Validx string // value variable name
  209. Value Elem // value element
  210. }
  211. func (m *Map) SetVarname(s string) {
  212. m.common.SetVarname(s)
  213. ridx:
  214. m.Keyidx = randIdent()
  215. m.Validx = randIdent()
  216. // just in case
  217. if m.Keyidx == m.Validx {
  218. goto ridx
  219. }
  220. m.Value.SetVarname(m.Validx)
  221. }
  222. func (m *Map) TypeName() string {
  223. if m.common.alias != "" {
  224. return m.common.alias
  225. }
  226. m.common.Alias("map[string]" + m.Value.TypeName())
  227. return m.common.alias
  228. }
  229. func (m *Map) Copy() Elem {
  230. g := *m
  231. g.Value = m.Value.Copy()
  232. return &g
  233. }
  234. func (m *Map) Complexity() int { return 2 + m.Value.Complexity() }
  235. type Slice struct {
  236. common
  237. Index string
  238. Els Elem // The type of each element
  239. }
  240. func (s *Slice) SetVarname(a string) {
  241. s.common.SetVarname(a)
  242. s.Index = randIdent()
  243. varName := s.Varname()
  244. if varName[0] == '*' {
  245. // Pointer-to-slice requires parenthesis for slicing.
  246. varName = "(" + varName + ")"
  247. }
  248. s.Els.SetVarname(fmt.Sprintf("%s[%s]", varName, s.Index))
  249. }
  250. func (s *Slice) TypeName() string {
  251. if s.common.alias != "" {
  252. return s.common.alias
  253. }
  254. s.common.Alias("[]" + s.Els.TypeName())
  255. return s.common.alias
  256. }
  257. func (s *Slice) Copy() Elem {
  258. z := *s
  259. z.Els = s.Els.Copy()
  260. return &z
  261. }
  262. func (s *Slice) Complexity() int {
  263. return 1 + s.Els.Complexity()
  264. }
  265. type Ptr struct {
  266. common
  267. Value Elem
  268. }
  269. func (s *Ptr) SetVarname(a string) {
  270. s.common.SetVarname(a)
  271. // struct fields are dereferenced
  272. // automatically...
  273. switch x := s.Value.(type) {
  274. case *Struct:
  275. // struct fields are automatically dereferenced
  276. x.SetVarname(a)
  277. return
  278. case *BaseElem:
  279. // identities have pointer receivers
  280. if x.Value == IDENT {
  281. x.SetVarname(a)
  282. } else {
  283. x.SetVarname("*" + a)
  284. }
  285. return
  286. default:
  287. s.Value.SetVarname("*" + a)
  288. return
  289. }
  290. }
  291. func (s *Ptr) TypeName() string {
  292. if s.common.alias != "" {
  293. return s.common.alias
  294. }
  295. s.common.Alias("*" + s.Value.TypeName())
  296. return s.common.alias
  297. }
  298. func (s *Ptr) Copy() Elem {
  299. v := *s
  300. v.Value = s.Value.Copy()
  301. return &v
  302. }
  303. func (s *Ptr) Complexity() int { return 1 + s.Value.Complexity() }
  304. func (s *Ptr) Needsinit() bool {
  305. if be, ok := s.Value.(*BaseElem); ok && be.needsref {
  306. return false
  307. }
  308. return true
  309. }
  310. type Struct struct {
  311. common
  312. Fields []StructField // field list
  313. AsTuple bool // write as an array instead of a map
  314. }
  315. func (s *Struct) TypeName() string {
  316. if s.common.alias != "" {
  317. return s.common.alias
  318. }
  319. str := "struct{\n"
  320. for i := range s.Fields {
  321. str += s.Fields[i].FieldName +
  322. " " + s.Fields[i].FieldElem.TypeName() +
  323. " " + s.Fields[i].RawTag + ";\n"
  324. }
  325. str += "}"
  326. s.common.Alias(str)
  327. return s.common.alias
  328. }
  329. func (s *Struct) SetVarname(a string) {
  330. s.common.SetVarname(a)
  331. writeStructFields(s.Fields, a)
  332. }
  333. func (s *Struct) Copy() Elem {
  334. g := *s
  335. g.Fields = make([]StructField, len(s.Fields))
  336. copy(g.Fields, s.Fields)
  337. for i := range s.Fields {
  338. g.Fields[i].FieldElem = s.Fields[i].FieldElem.Copy()
  339. }
  340. return &g
  341. }
  342. func (s *Struct) Complexity() int {
  343. c := 1
  344. for i := range s.Fields {
  345. c += s.Fields[i].FieldElem.Complexity()
  346. }
  347. return c
  348. }
  349. type StructField struct {
  350. FieldTag string // the string inside the `msg:""` tag
  351. RawTag string // the full struct tag
  352. FieldName string // the name of the struct field
  353. FieldElem Elem // the field type
  354. }
  355. type ShimMode int
  356. const (
  357. Cast ShimMode = iota
  358. Convert
  359. )
  360. // BaseElem is an element that
  361. // can be represented by a primitive
  362. // MessagePack type.
  363. type BaseElem struct {
  364. common
  365. ShimMode ShimMode // Method used to shim
  366. ShimToBase string // shim to base type, or empty
  367. ShimFromBase string // shim from base type, or empty
  368. Value Primitive // Type of element
  369. Convert bool // should we do an explicit conversion?
  370. mustinline bool // must inline; not printable
  371. needsref bool // needs reference for shim
  372. }
  373. func (s *BaseElem) Printable() bool { return !s.mustinline }
  374. func (s *BaseElem) Alias(typ string) {
  375. s.common.Alias(typ)
  376. if s.Value != IDENT {
  377. s.Convert = true
  378. }
  379. if strings.Contains(typ, ".") {
  380. s.mustinline = true
  381. }
  382. }
  383. func (s *BaseElem) SetVarname(a string) {
  384. // extensions whose parents
  385. // are not pointers need to
  386. // be explicitly referenced
  387. if s.Value == Ext || s.needsref {
  388. if strings.HasPrefix(a, "*") {
  389. s.common.SetVarname(a[1:])
  390. return
  391. }
  392. s.common.SetVarname("&" + a)
  393. return
  394. }
  395. s.common.SetVarname(a)
  396. }
  397. // TypeName returns the syntactically correct Go
  398. // type name for the base element.
  399. func (s *BaseElem) TypeName() string {
  400. if s.common.alias != "" {
  401. return s.common.alias
  402. }
  403. s.common.Alias(s.BaseType())
  404. return s.common.alias
  405. }
  406. // ToBase, used if Convert==true, is used as tmp = {{ToBase}}({{Varname}})
  407. func (s *BaseElem) ToBase() string {
  408. if s.ShimToBase != "" {
  409. return s.ShimToBase
  410. }
  411. return s.BaseType()
  412. }
  413. // FromBase, used if Convert==true, is used as {{Varname}} = {{FromBase}}(tmp)
  414. func (s *BaseElem) FromBase() string {
  415. if s.ShimFromBase != "" {
  416. return s.ShimFromBase
  417. }
  418. return s.TypeName()
  419. }
  420. // BaseName returns the string form of the
  421. // base type (e.g. Float64, Ident, etc)
  422. func (s *BaseElem) BaseName() string {
  423. // time is a special case;
  424. // we strip the package prefix
  425. if s.Value == Time {
  426. return "Time"
  427. }
  428. return s.Value.String()
  429. }
  430. func (s *BaseElem) BaseType() string {
  431. switch s.Value {
  432. case IDENT:
  433. return s.TypeName()
  434. // exceptions to the naming/capitalization
  435. // rule:
  436. case Intf:
  437. return "interface{}"
  438. case Bytes:
  439. return "[]byte"
  440. case Time:
  441. return "time.Time"
  442. case Ext:
  443. return "msgp.Extension"
  444. // everything else is base.String() with
  445. // the first letter as lowercase
  446. default:
  447. return strings.ToLower(s.BaseName())
  448. }
  449. }
  450. func (s *BaseElem) Needsref(b bool) {
  451. s.needsref = b
  452. }
  453. func (s *BaseElem) Copy() Elem {
  454. g := *s
  455. return &g
  456. }
  457. func (s *BaseElem) Complexity() int {
  458. if s.Convert && !s.mustinline {
  459. return 2
  460. }
  461. // we need to return 1 if !printable(),
  462. // in order to make sure that stuff gets
  463. // inlined appropriately
  464. return 1
  465. }
  466. // Resolved returns whether or not
  467. // the type of the element is
  468. // a primitive or a builtin provided
  469. // by the package.
  470. func (s *BaseElem) Resolved() bool {
  471. if s.Value == IDENT {
  472. _, ok := builtins[s.TypeName()]
  473. return ok
  474. }
  475. return true
  476. }
  477. func (k Primitive) String() string {
  478. switch k {
  479. case String:
  480. return "String"
  481. case Bytes:
  482. return "Bytes"
  483. case Float32:
  484. return "Float32"
  485. case Float64:
  486. return "Float64"
  487. case Complex64:
  488. return "Complex64"
  489. case Complex128:
  490. return "Complex128"
  491. case Uint:
  492. return "Uint"
  493. case Uint8:
  494. return "Uint8"
  495. case Uint16:
  496. return "Uint16"
  497. case Uint32:
  498. return "Uint32"
  499. case Uint64:
  500. return "Uint64"
  501. case Byte:
  502. return "Byte"
  503. case Int:
  504. return "Int"
  505. case Int8:
  506. return "Int8"
  507. case Int16:
  508. return "Int16"
  509. case Int32:
  510. return "Int32"
  511. case Int64:
  512. return "Int64"
  513. case Bool:
  514. return "Bool"
  515. case Intf:
  516. return "Intf"
  517. case Time:
  518. return "time.Time"
  519. case Ext:
  520. return "Extension"
  521. case IDENT:
  522. return "Ident"
  523. default:
  524. return "INVALID"
  525. }
  526. }
  527. // writeStructFields is a trampoline for writeBase for
  528. // all of the fields in a struct
  529. func writeStructFields(s []StructField, name string) {
  530. for i := range s {
  531. s[i].FieldElem.SetVarname(fmt.Sprintf("%s.%s", name, s[i].FieldName))
  532. }
  533. }
  534. // coerceArraySize ensures we can compare constant array lengths.
  535. //
  536. // msgpack array headers are 32 bit unsigned, which is reflected in the
  537. // ArrayHeader implementation in this library using uint32. On the Go side, we
  538. // can declare array lengths as any constant integer width, which breaks when
  539. // attempting a direct comparison to an array header's uint32.
  540. //
  541. func coerceArraySize(asz string) string {
  542. return fmt.Sprintf("uint32(%s)", asz)
  543. }