code.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017
  1. package encoder
  2. import (
  3. "fmt"
  4. "reflect"
  5. "unsafe"
  6. "github.com/goccy/go-json/internal/runtime"
  7. )
  8. type Code interface {
  9. Kind() CodeKind
  10. ToOpcode(*compileContext) Opcodes
  11. Filter(*FieldQuery) Code
  12. }
  13. type AnonymousCode interface {
  14. ToAnonymousOpcode(*compileContext) Opcodes
  15. }
  16. type Opcodes []*Opcode
  17. func (o Opcodes) First() *Opcode {
  18. if len(o) == 0 {
  19. return nil
  20. }
  21. return o[0]
  22. }
  23. func (o Opcodes) Last() *Opcode {
  24. if len(o) == 0 {
  25. return nil
  26. }
  27. return o[len(o)-1]
  28. }
  29. func (o Opcodes) Add(codes ...*Opcode) Opcodes {
  30. return append(o, codes...)
  31. }
  32. type CodeKind int
  33. const (
  34. CodeKindInterface CodeKind = iota
  35. CodeKindPtr
  36. CodeKindInt
  37. CodeKindUint
  38. CodeKindFloat
  39. CodeKindString
  40. CodeKindBool
  41. CodeKindStruct
  42. CodeKindMap
  43. CodeKindSlice
  44. CodeKindArray
  45. CodeKindBytes
  46. CodeKindMarshalJSON
  47. CodeKindMarshalText
  48. CodeKindRecursive
  49. )
  50. type IntCode struct {
  51. typ *runtime.Type
  52. bitSize uint8
  53. isString bool
  54. isPtr bool
  55. }
  56. func (c *IntCode) Kind() CodeKind {
  57. return CodeKindInt
  58. }
  59. func (c *IntCode) ToOpcode(ctx *compileContext) Opcodes {
  60. var code *Opcode
  61. switch {
  62. case c.isPtr:
  63. code = newOpCode(ctx, c.typ, OpIntPtr)
  64. case c.isString:
  65. code = newOpCode(ctx, c.typ, OpIntString)
  66. default:
  67. code = newOpCode(ctx, c.typ, OpInt)
  68. }
  69. code.NumBitSize = c.bitSize
  70. ctx.incIndex()
  71. return Opcodes{code}
  72. }
  73. func (c *IntCode) Filter(_ *FieldQuery) Code {
  74. return c
  75. }
  76. type UintCode struct {
  77. typ *runtime.Type
  78. bitSize uint8
  79. isString bool
  80. isPtr bool
  81. }
  82. func (c *UintCode) Kind() CodeKind {
  83. return CodeKindUint
  84. }
  85. func (c *UintCode) ToOpcode(ctx *compileContext) Opcodes {
  86. var code *Opcode
  87. switch {
  88. case c.isPtr:
  89. code = newOpCode(ctx, c.typ, OpUintPtr)
  90. case c.isString:
  91. code = newOpCode(ctx, c.typ, OpUintString)
  92. default:
  93. code = newOpCode(ctx, c.typ, OpUint)
  94. }
  95. code.NumBitSize = c.bitSize
  96. ctx.incIndex()
  97. return Opcodes{code}
  98. }
  99. func (c *UintCode) Filter(_ *FieldQuery) Code {
  100. return c
  101. }
  102. type FloatCode struct {
  103. typ *runtime.Type
  104. bitSize uint8
  105. isPtr bool
  106. }
  107. func (c *FloatCode) Kind() CodeKind {
  108. return CodeKindFloat
  109. }
  110. func (c *FloatCode) ToOpcode(ctx *compileContext) Opcodes {
  111. var code *Opcode
  112. switch {
  113. case c.isPtr:
  114. switch c.bitSize {
  115. case 32:
  116. code = newOpCode(ctx, c.typ, OpFloat32Ptr)
  117. default:
  118. code = newOpCode(ctx, c.typ, OpFloat64Ptr)
  119. }
  120. default:
  121. switch c.bitSize {
  122. case 32:
  123. code = newOpCode(ctx, c.typ, OpFloat32)
  124. default:
  125. code = newOpCode(ctx, c.typ, OpFloat64)
  126. }
  127. }
  128. ctx.incIndex()
  129. return Opcodes{code}
  130. }
  131. func (c *FloatCode) Filter(_ *FieldQuery) Code {
  132. return c
  133. }
  134. type StringCode struct {
  135. typ *runtime.Type
  136. isPtr bool
  137. }
  138. func (c *StringCode) Kind() CodeKind {
  139. return CodeKindString
  140. }
  141. func (c *StringCode) ToOpcode(ctx *compileContext) Opcodes {
  142. isJSONNumberType := c.typ == runtime.Type2RType(jsonNumberType)
  143. var code *Opcode
  144. if c.isPtr {
  145. if isJSONNumberType {
  146. code = newOpCode(ctx, c.typ, OpNumberPtr)
  147. } else {
  148. code = newOpCode(ctx, c.typ, OpStringPtr)
  149. }
  150. } else {
  151. if isJSONNumberType {
  152. code = newOpCode(ctx, c.typ, OpNumber)
  153. } else {
  154. code = newOpCode(ctx, c.typ, OpString)
  155. }
  156. }
  157. ctx.incIndex()
  158. return Opcodes{code}
  159. }
  160. func (c *StringCode) Filter(_ *FieldQuery) Code {
  161. return c
  162. }
  163. type BoolCode struct {
  164. typ *runtime.Type
  165. isPtr bool
  166. }
  167. func (c *BoolCode) Kind() CodeKind {
  168. return CodeKindBool
  169. }
  170. func (c *BoolCode) ToOpcode(ctx *compileContext) Opcodes {
  171. var code *Opcode
  172. switch {
  173. case c.isPtr:
  174. code = newOpCode(ctx, c.typ, OpBoolPtr)
  175. default:
  176. code = newOpCode(ctx, c.typ, OpBool)
  177. }
  178. ctx.incIndex()
  179. return Opcodes{code}
  180. }
  181. func (c *BoolCode) Filter(_ *FieldQuery) Code {
  182. return c
  183. }
  184. type BytesCode struct {
  185. typ *runtime.Type
  186. isPtr bool
  187. }
  188. func (c *BytesCode) Kind() CodeKind {
  189. return CodeKindBytes
  190. }
  191. func (c *BytesCode) ToOpcode(ctx *compileContext) Opcodes {
  192. var code *Opcode
  193. switch {
  194. case c.isPtr:
  195. code = newOpCode(ctx, c.typ, OpBytesPtr)
  196. default:
  197. code = newOpCode(ctx, c.typ, OpBytes)
  198. }
  199. ctx.incIndex()
  200. return Opcodes{code}
  201. }
  202. func (c *BytesCode) Filter(_ *FieldQuery) Code {
  203. return c
  204. }
  205. type SliceCode struct {
  206. typ *runtime.Type
  207. value Code
  208. }
  209. func (c *SliceCode) Kind() CodeKind {
  210. return CodeKindSlice
  211. }
  212. func (c *SliceCode) ToOpcode(ctx *compileContext) Opcodes {
  213. // header => opcode => elem => end
  214. // ^ |
  215. // |________|
  216. size := c.typ.Elem().Size()
  217. header := newSliceHeaderCode(ctx, c.typ)
  218. ctx.incIndex()
  219. ctx.incIndent()
  220. codes := c.value.ToOpcode(ctx)
  221. ctx.decIndent()
  222. codes.First().Flags |= IndirectFlags
  223. elemCode := newSliceElemCode(ctx, c.typ.Elem(), header, size)
  224. ctx.incIndex()
  225. end := newOpCode(ctx, c.typ, OpSliceEnd)
  226. ctx.incIndex()
  227. header.End = end
  228. header.Next = codes.First()
  229. codes.Last().Next = elemCode
  230. elemCode.Next = codes.First()
  231. elemCode.End = end
  232. return Opcodes{header}.Add(codes...).Add(elemCode).Add(end)
  233. }
  234. func (c *SliceCode) Filter(_ *FieldQuery) Code {
  235. return c
  236. }
  237. type ArrayCode struct {
  238. typ *runtime.Type
  239. value Code
  240. }
  241. func (c *ArrayCode) Kind() CodeKind {
  242. return CodeKindArray
  243. }
  244. func (c *ArrayCode) ToOpcode(ctx *compileContext) Opcodes {
  245. // header => opcode => elem => end
  246. // ^ |
  247. // |________|
  248. elem := c.typ.Elem()
  249. alen := c.typ.Len()
  250. size := elem.Size()
  251. header := newArrayHeaderCode(ctx, c.typ, alen)
  252. ctx.incIndex()
  253. ctx.incIndent()
  254. codes := c.value.ToOpcode(ctx)
  255. ctx.decIndent()
  256. codes.First().Flags |= IndirectFlags
  257. elemCode := newArrayElemCode(ctx, elem, header, alen, size)
  258. ctx.incIndex()
  259. end := newOpCode(ctx, c.typ, OpArrayEnd)
  260. ctx.incIndex()
  261. header.End = end
  262. header.Next = codes.First()
  263. codes.Last().Next = elemCode
  264. elemCode.Next = codes.First()
  265. elemCode.End = end
  266. return Opcodes{header}.Add(codes...).Add(elemCode).Add(end)
  267. }
  268. func (c *ArrayCode) Filter(_ *FieldQuery) Code {
  269. return c
  270. }
  271. type MapCode struct {
  272. typ *runtime.Type
  273. key Code
  274. value Code
  275. }
  276. func (c *MapCode) Kind() CodeKind {
  277. return CodeKindMap
  278. }
  279. func (c *MapCode) ToOpcode(ctx *compileContext) Opcodes {
  280. // header => code => value => code => key => code => value => code => end
  281. // ^ |
  282. // |_______________________|
  283. header := newMapHeaderCode(ctx, c.typ)
  284. ctx.incIndex()
  285. keyCodes := c.key.ToOpcode(ctx)
  286. value := newMapValueCode(ctx, c.typ.Elem(), header)
  287. ctx.incIndex()
  288. ctx.incIndent()
  289. valueCodes := c.value.ToOpcode(ctx)
  290. ctx.decIndent()
  291. valueCodes.First().Flags |= IndirectFlags
  292. key := newMapKeyCode(ctx, c.typ.Key(), header)
  293. ctx.incIndex()
  294. end := newMapEndCode(ctx, c.typ, header)
  295. ctx.incIndex()
  296. header.Next = keyCodes.First()
  297. keyCodes.Last().Next = value
  298. value.Next = valueCodes.First()
  299. valueCodes.Last().Next = key
  300. key.Next = keyCodes.First()
  301. header.End = end
  302. key.End = end
  303. value.End = end
  304. return Opcodes{header}.Add(keyCodes...).Add(value).Add(valueCodes...).Add(key).Add(end)
  305. }
  306. func (c *MapCode) Filter(_ *FieldQuery) Code {
  307. return c
  308. }
  309. type StructCode struct {
  310. typ *runtime.Type
  311. fields []*StructFieldCode
  312. isPtr bool
  313. disableIndirectConversion bool
  314. isIndirect bool
  315. isRecursive bool
  316. }
  317. func (c *StructCode) Kind() CodeKind {
  318. return CodeKindStruct
  319. }
  320. func (c *StructCode) lastFieldCode(field *StructFieldCode, firstField *Opcode) *Opcode {
  321. if isEmbeddedStruct(field) {
  322. return c.lastAnonymousFieldCode(firstField)
  323. }
  324. lastField := firstField
  325. for lastField.NextField != nil {
  326. lastField = lastField.NextField
  327. }
  328. return lastField
  329. }
  330. func (c *StructCode) lastAnonymousFieldCode(firstField *Opcode) *Opcode {
  331. // firstField is special StructHead operation for anonymous structure.
  332. // So, StructHead's next operation is truly struct head operation.
  333. lastField := firstField.Next
  334. for lastField.NextField != nil {
  335. lastField = lastField.NextField
  336. }
  337. return lastField
  338. }
  339. func (c *StructCode) ToOpcode(ctx *compileContext) Opcodes {
  340. // header => code => structField => code => end
  341. // ^ |
  342. // |__________|
  343. if c.isRecursive {
  344. recursive := newRecursiveCode(ctx, c.typ, &CompiledCode{})
  345. recursive.Type = c.typ
  346. ctx.incIndex()
  347. *ctx.recursiveCodes = append(*ctx.recursiveCodes, recursive)
  348. return Opcodes{recursive}
  349. }
  350. codes := Opcodes{}
  351. var prevField *Opcode
  352. ctx.incIndent()
  353. for idx, field := range c.fields {
  354. isFirstField := idx == 0
  355. isEndField := idx == len(c.fields)-1
  356. fieldCodes := field.ToOpcode(ctx, isFirstField, isEndField)
  357. for _, code := range fieldCodes {
  358. if c.isIndirect {
  359. code.Flags |= IndirectFlags
  360. }
  361. }
  362. firstField := fieldCodes.First()
  363. if len(codes) > 0 {
  364. codes.Last().Next = firstField
  365. firstField.Idx = codes.First().Idx
  366. }
  367. if prevField != nil {
  368. prevField.NextField = firstField
  369. }
  370. if isEndField {
  371. endField := fieldCodes.Last()
  372. if isEmbeddedStruct(field) {
  373. firstField.End = endField
  374. lastField := c.lastAnonymousFieldCode(firstField)
  375. lastField.NextField = endField
  376. }
  377. if len(codes) > 0 {
  378. codes.First().End = endField
  379. } else {
  380. firstField.End = endField
  381. }
  382. codes = codes.Add(fieldCodes...)
  383. break
  384. }
  385. prevField = c.lastFieldCode(field, firstField)
  386. codes = codes.Add(fieldCodes...)
  387. }
  388. if len(codes) == 0 {
  389. head := &Opcode{
  390. Op: OpStructHead,
  391. Idx: opcodeOffset(ctx.ptrIndex),
  392. Type: c.typ,
  393. DisplayIdx: ctx.opcodeIndex,
  394. Indent: ctx.indent,
  395. }
  396. ctx.incOpcodeIndex()
  397. end := &Opcode{
  398. Op: OpStructEnd,
  399. Idx: opcodeOffset(ctx.ptrIndex),
  400. DisplayIdx: ctx.opcodeIndex,
  401. Indent: ctx.indent,
  402. }
  403. head.NextField = end
  404. head.Next = end
  405. head.End = end
  406. codes = codes.Add(head, end)
  407. ctx.incIndex()
  408. }
  409. ctx.decIndent()
  410. ctx.structTypeToCodes[uintptr(unsafe.Pointer(c.typ))] = codes
  411. return codes
  412. }
  413. func (c *StructCode) ToAnonymousOpcode(ctx *compileContext) Opcodes {
  414. // header => code => structField => code => end
  415. // ^ |
  416. // |__________|
  417. if c.isRecursive {
  418. recursive := newRecursiveCode(ctx, c.typ, &CompiledCode{})
  419. recursive.Type = c.typ
  420. ctx.incIndex()
  421. *ctx.recursiveCodes = append(*ctx.recursiveCodes, recursive)
  422. return Opcodes{recursive}
  423. }
  424. codes := Opcodes{}
  425. var prevField *Opcode
  426. for idx, field := range c.fields {
  427. isFirstField := idx == 0
  428. isEndField := idx == len(c.fields)-1
  429. fieldCodes := field.ToAnonymousOpcode(ctx, isFirstField, isEndField)
  430. for _, code := range fieldCodes {
  431. if c.isIndirect {
  432. code.Flags |= IndirectFlags
  433. }
  434. }
  435. firstField := fieldCodes.First()
  436. if len(codes) > 0 {
  437. codes.Last().Next = firstField
  438. firstField.Idx = codes.First().Idx
  439. }
  440. if prevField != nil {
  441. prevField.NextField = firstField
  442. }
  443. if isEndField {
  444. lastField := fieldCodes.Last()
  445. if len(codes) > 0 {
  446. codes.First().End = lastField
  447. } else {
  448. firstField.End = lastField
  449. }
  450. }
  451. prevField = firstField
  452. codes = codes.Add(fieldCodes...)
  453. }
  454. return codes
  455. }
  456. func (c *StructCode) removeFieldsByTags(tags runtime.StructTags) {
  457. fields := make([]*StructFieldCode, 0, len(c.fields))
  458. for _, field := range c.fields {
  459. if field.isAnonymous {
  460. structCode := field.getAnonymousStruct()
  461. if structCode != nil && !structCode.isRecursive {
  462. structCode.removeFieldsByTags(tags)
  463. if len(structCode.fields) > 0 {
  464. fields = append(fields, field)
  465. }
  466. continue
  467. }
  468. }
  469. if tags.ExistsKey(field.key) {
  470. continue
  471. }
  472. fields = append(fields, field)
  473. }
  474. c.fields = fields
  475. }
  476. func (c *StructCode) enableIndirect() {
  477. if c.isIndirect {
  478. return
  479. }
  480. c.isIndirect = true
  481. if len(c.fields) == 0 {
  482. return
  483. }
  484. structCode := c.fields[0].getStruct()
  485. if structCode == nil {
  486. return
  487. }
  488. structCode.enableIndirect()
  489. }
  490. func (c *StructCode) Filter(query *FieldQuery) Code {
  491. fieldMap := map[string]*FieldQuery{}
  492. for _, field := range query.Fields {
  493. fieldMap[field.Name] = field
  494. }
  495. fields := make([]*StructFieldCode, 0, len(c.fields))
  496. for _, field := range c.fields {
  497. query, exists := fieldMap[field.key]
  498. if !exists {
  499. continue
  500. }
  501. fieldCode := &StructFieldCode{
  502. typ: field.typ,
  503. key: field.key,
  504. tag: field.tag,
  505. value: field.value,
  506. offset: field.offset,
  507. isAnonymous: field.isAnonymous,
  508. isTaggedKey: field.isTaggedKey,
  509. isNilableType: field.isNilableType,
  510. isNilCheck: field.isNilCheck,
  511. isAddrForMarshaler: field.isAddrForMarshaler,
  512. isNextOpPtrType: field.isNextOpPtrType,
  513. }
  514. if len(query.Fields) > 0 {
  515. fieldCode.value = fieldCode.value.Filter(query)
  516. }
  517. fields = append(fields, fieldCode)
  518. }
  519. return &StructCode{
  520. typ: c.typ,
  521. fields: fields,
  522. isPtr: c.isPtr,
  523. disableIndirectConversion: c.disableIndirectConversion,
  524. isIndirect: c.isIndirect,
  525. isRecursive: c.isRecursive,
  526. }
  527. }
  528. type StructFieldCode struct {
  529. typ *runtime.Type
  530. key string
  531. tag *runtime.StructTag
  532. value Code
  533. offset uintptr
  534. isAnonymous bool
  535. isTaggedKey bool
  536. isNilableType bool
  537. isNilCheck bool
  538. isAddrForMarshaler bool
  539. isNextOpPtrType bool
  540. isMarshalerContext bool
  541. }
  542. func (c *StructFieldCode) getStruct() *StructCode {
  543. value := c.value
  544. ptr, ok := value.(*PtrCode)
  545. if ok {
  546. value = ptr.value
  547. }
  548. structCode, ok := value.(*StructCode)
  549. if ok {
  550. return structCode
  551. }
  552. return nil
  553. }
  554. func (c *StructFieldCode) getAnonymousStruct() *StructCode {
  555. if !c.isAnonymous {
  556. return nil
  557. }
  558. return c.getStruct()
  559. }
  560. func optimizeStructHeader(code *Opcode, tag *runtime.StructTag) OpType {
  561. headType := code.ToHeaderType(tag.IsString)
  562. if tag.IsOmitEmpty {
  563. headType = headType.HeadToOmitEmptyHead()
  564. }
  565. return headType
  566. }
  567. func optimizeStructField(code *Opcode, tag *runtime.StructTag) OpType {
  568. fieldType := code.ToFieldType(tag.IsString)
  569. if tag.IsOmitEmpty {
  570. fieldType = fieldType.FieldToOmitEmptyField()
  571. }
  572. return fieldType
  573. }
  574. func (c *StructFieldCode) headerOpcodes(ctx *compileContext, field *Opcode, valueCodes Opcodes) Opcodes {
  575. value := valueCodes.First()
  576. op := optimizeStructHeader(value, c.tag)
  577. field.Op = op
  578. if value.Flags&MarshalerContextFlags != 0 {
  579. field.Flags |= MarshalerContextFlags
  580. }
  581. field.NumBitSize = value.NumBitSize
  582. field.PtrNum = value.PtrNum
  583. field.FieldQuery = value.FieldQuery
  584. fieldCodes := Opcodes{field}
  585. if op.IsMultipleOpHead() {
  586. field.Next = value
  587. fieldCodes = fieldCodes.Add(valueCodes...)
  588. } else {
  589. ctx.decIndex()
  590. }
  591. return fieldCodes
  592. }
  593. func (c *StructFieldCode) fieldOpcodes(ctx *compileContext, field *Opcode, valueCodes Opcodes) Opcodes {
  594. value := valueCodes.First()
  595. op := optimizeStructField(value, c.tag)
  596. field.Op = op
  597. if value.Flags&MarshalerContextFlags != 0 {
  598. field.Flags |= MarshalerContextFlags
  599. }
  600. field.NumBitSize = value.NumBitSize
  601. field.PtrNum = value.PtrNum
  602. field.FieldQuery = value.FieldQuery
  603. fieldCodes := Opcodes{field}
  604. if op.IsMultipleOpField() {
  605. field.Next = value
  606. fieldCodes = fieldCodes.Add(valueCodes...)
  607. } else {
  608. ctx.decIndex()
  609. }
  610. return fieldCodes
  611. }
  612. func (c *StructFieldCode) addStructEndCode(ctx *compileContext, codes Opcodes) Opcodes {
  613. end := &Opcode{
  614. Op: OpStructEnd,
  615. Idx: opcodeOffset(ctx.ptrIndex),
  616. DisplayIdx: ctx.opcodeIndex,
  617. Indent: ctx.indent,
  618. }
  619. codes.Last().Next = end
  620. codes.First().NextField = end
  621. codes = codes.Add(end)
  622. ctx.incOpcodeIndex()
  623. return codes
  624. }
  625. func (c *StructFieldCode) structKey(ctx *compileContext) string {
  626. if ctx.escapeKey {
  627. rctx := &RuntimeContext{Option: &Option{Flag: HTMLEscapeOption}}
  628. return fmt.Sprintf(`%s:`, string(AppendString(rctx, []byte{}, c.key)))
  629. }
  630. return fmt.Sprintf(`"%s":`, c.key)
  631. }
  632. func (c *StructFieldCode) flags() OpFlags {
  633. var flags OpFlags
  634. if c.isTaggedKey {
  635. flags |= IsTaggedKeyFlags
  636. }
  637. if c.isNilableType {
  638. flags |= IsNilableTypeFlags
  639. }
  640. if c.isNilCheck {
  641. flags |= NilCheckFlags
  642. }
  643. if c.isAddrForMarshaler {
  644. flags |= AddrForMarshalerFlags
  645. }
  646. if c.isNextOpPtrType {
  647. flags |= IsNextOpPtrTypeFlags
  648. }
  649. if c.isAnonymous {
  650. flags |= AnonymousKeyFlags
  651. }
  652. if c.isMarshalerContext {
  653. flags |= MarshalerContextFlags
  654. }
  655. return flags
  656. }
  657. func (c *StructFieldCode) toValueOpcodes(ctx *compileContext) Opcodes {
  658. if c.isAnonymous {
  659. anonymCode, ok := c.value.(AnonymousCode)
  660. if ok {
  661. return anonymCode.ToAnonymousOpcode(ctx)
  662. }
  663. }
  664. return c.value.ToOpcode(ctx)
  665. }
  666. func (c *StructFieldCode) ToOpcode(ctx *compileContext, isFirstField, isEndField bool) Opcodes {
  667. field := &Opcode{
  668. Idx: opcodeOffset(ctx.ptrIndex),
  669. Flags: c.flags(),
  670. Key: c.structKey(ctx),
  671. Offset: uint32(c.offset),
  672. Type: c.typ,
  673. DisplayIdx: ctx.opcodeIndex,
  674. Indent: ctx.indent,
  675. DisplayKey: c.key,
  676. }
  677. ctx.incIndex()
  678. valueCodes := c.toValueOpcodes(ctx)
  679. if isFirstField {
  680. codes := c.headerOpcodes(ctx, field, valueCodes)
  681. if isEndField {
  682. codes = c.addStructEndCode(ctx, codes)
  683. }
  684. return codes
  685. }
  686. codes := c.fieldOpcodes(ctx, field, valueCodes)
  687. if isEndField {
  688. if isEnableStructEndOptimization(c.value) {
  689. field.Op = field.Op.FieldToEnd()
  690. } else {
  691. codes = c.addStructEndCode(ctx, codes)
  692. }
  693. }
  694. return codes
  695. }
  696. func (c *StructFieldCode) ToAnonymousOpcode(ctx *compileContext, isFirstField, isEndField bool) Opcodes {
  697. field := &Opcode{
  698. Idx: opcodeOffset(ctx.ptrIndex),
  699. Flags: c.flags() | AnonymousHeadFlags,
  700. Key: c.structKey(ctx),
  701. Offset: uint32(c.offset),
  702. Type: c.typ,
  703. DisplayIdx: ctx.opcodeIndex,
  704. Indent: ctx.indent,
  705. DisplayKey: c.key,
  706. }
  707. ctx.incIndex()
  708. valueCodes := c.toValueOpcodes(ctx)
  709. if isFirstField {
  710. return c.headerOpcodes(ctx, field, valueCodes)
  711. }
  712. return c.fieldOpcodes(ctx, field, valueCodes)
  713. }
  714. func isEnableStructEndOptimization(value Code) bool {
  715. switch value.Kind() {
  716. case CodeKindInt,
  717. CodeKindUint,
  718. CodeKindFloat,
  719. CodeKindString,
  720. CodeKindBool,
  721. CodeKindBytes:
  722. return true
  723. case CodeKindPtr:
  724. return isEnableStructEndOptimization(value.(*PtrCode).value)
  725. default:
  726. return false
  727. }
  728. }
  729. type InterfaceCode struct {
  730. typ *runtime.Type
  731. fieldQuery *FieldQuery
  732. isPtr bool
  733. }
  734. func (c *InterfaceCode) Kind() CodeKind {
  735. return CodeKindInterface
  736. }
  737. func (c *InterfaceCode) ToOpcode(ctx *compileContext) Opcodes {
  738. var code *Opcode
  739. switch {
  740. case c.isPtr:
  741. code = newOpCode(ctx, c.typ, OpInterfacePtr)
  742. default:
  743. code = newOpCode(ctx, c.typ, OpInterface)
  744. }
  745. code.FieldQuery = c.fieldQuery
  746. if c.typ.NumMethod() > 0 {
  747. code.Flags |= NonEmptyInterfaceFlags
  748. }
  749. ctx.incIndex()
  750. return Opcodes{code}
  751. }
  752. func (c *InterfaceCode) Filter(query *FieldQuery) Code {
  753. return &InterfaceCode{
  754. typ: c.typ,
  755. fieldQuery: query,
  756. isPtr: c.isPtr,
  757. }
  758. }
  759. type MarshalJSONCode struct {
  760. typ *runtime.Type
  761. fieldQuery *FieldQuery
  762. isAddrForMarshaler bool
  763. isNilableType bool
  764. isMarshalerContext bool
  765. }
  766. func (c *MarshalJSONCode) Kind() CodeKind {
  767. return CodeKindMarshalJSON
  768. }
  769. func (c *MarshalJSONCode) ToOpcode(ctx *compileContext) Opcodes {
  770. code := newOpCode(ctx, c.typ, OpMarshalJSON)
  771. code.FieldQuery = c.fieldQuery
  772. if c.isAddrForMarshaler {
  773. code.Flags |= AddrForMarshalerFlags
  774. }
  775. if c.isMarshalerContext {
  776. code.Flags |= MarshalerContextFlags
  777. }
  778. if c.isNilableType {
  779. code.Flags |= IsNilableTypeFlags
  780. } else {
  781. code.Flags &= ^IsNilableTypeFlags
  782. }
  783. ctx.incIndex()
  784. return Opcodes{code}
  785. }
  786. func (c *MarshalJSONCode) Filter(query *FieldQuery) Code {
  787. return &MarshalJSONCode{
  788. typ: c.typ,
  789. fieldQuery: query,
  790. isAddrForMarshaler: c.isAddrForMarshaler,
  791. isNilableType: c.isNilableType,
  792. isMarshalerContext: c.isMarshalerContext,
  793. }
  794. }
  795. type MarshalTextCode struct {
  796. typ *runtime.Type
  797. fieldQuery *FieldQuery
  798. isAddrForMarshaler bool
  799. isNilableType bool
  800. }
  801. func (c *MarshalTextCode) Kind() CodeKind {
  802. return CodeKindMarshalText
  803. }
  804. func (c *MarshalTextCode) ToOpcode(ctx *compileContext) Opcodes {
  805. code := newOpCode(ctx, c.typ, OpMarshalText)
  806. code.FieldQuery = c.fieldQuery
  807. if c.isAddrForMarshaler {
  808. code.Flags |= AddrForMarshalerFlags
  809. }
  810. if c.isNilableType {
  811. code.Flags |= IsNilableTypeFlags
  812. } else {
  813. code.Flags &= ^IsNilableTypeFlags
  814. }
  815. ctx.incIndex()
  816. return Opcodes{code}
  817. }
  818. func (c *MarshalTextCode) Filter(query *FieldQuery) Code {
  819. return &MarshalTextCode{
  820. typ: c.typ,
  821. fieldQuery: query,
  822. isAddrForMarshaler: c.isAddrForMarshaler,
  823. isNilableType: c.isNilableType,
  824. }
  825. }
  826. type PtrCode struct {
  827. typ *runtime.Type
  828. value Code
  829. ptrNum uint8
  830. }
  831. func (c *PtrCode) Kind() CodeKind {
  832. return CodeKindPtr
  833. }
  834. func (c *PtrCode) ToOpcode(ctx *compileContext) Opcodes {
  835. codes := c.value.ToOpcode(ctx)
  836. codes.First().Op = convertPtrOp(codes.First())
  837. codes.First().PtrNum = c.ptrNum
  838. return codes
  839. }
  840. func (c *PtrCode) ToAnonymousOpcode(ctx *compileContext) Opcodes {
  841. var codes Opcodes
  842. anonymCode, ok := c.value.(AnonymousCode)
  843. if ok {
  844. codes = anonymCode.ToAnonymousOpcode(ctx)
  845. } else {
  846. codes = c.value.ToOpcode(ctx)
  847. }
  848. codes.First().Op = convertPtrOp(codes.First())
  849. codes.First().PtrNum = c.ptrNum
  850. return codes
  851. }
  852. func (c *PtrCode) Filter(query *FieldQuery) Code {
  853. return &PtrCode{
  854. typ: c.typ,
  855. value: c.value.Filter(query),
  856. ptrNum: c.ptrNum,
  857. }
  858. }
  859. func convertPtrOp(code *Opcode) OpType {
  860. ptrHeadOp := code.Op.HeadToPtrHead()
  861. if code.Op != ptrHeadOp {
  862. if code.PtrNum > 0 {
  863. // ptr field and ptr head
  864. code.PtrNum--
  865. }
  866. return ptrHeadOp
  867. }
  868. switch code.Op {
  869. case OpInt:
  870. return OpIntPtr
  871. case OpUint:
  872. return OpUintPtr
  873. case OpFloat32:
  874. return OpFloat32Ptr
  875. case OpFloat64:
  876. return OpFloat64Ptr
  877. case OpString:
  878. return OpStringPtr
  879. case OpBool:
  880. return OpBoolPtr
  881. case OpBytes:
  882. return OpBytesPtr
  883. case OpNumber:
  884. return OpNumberPtr
  885. case OpArray:
  886. return OpArrayPtr
  887. case OpSlice:
  888. return OpSlicePtr
  889. case OpMap:
  890. return OpMapPtr
  891. case OpMarshalJSON:
  892. return OpMarshalJSONPtr
  893. case OpMarshalText:
  894. return OpMarshalTextPtr
  895. case OpInterface:
  896. return OpInterfacePtr
  897. case OpRecursive:
  898. return OpRecursivePtr
  899. }
  900. return code.Op
  901. }
  902. func isEmbeddedStruct(field *StructFieldCode) bool {
  903. if !field.isAnonymous {
  904. return false
  905. }
  906. t := field.typ
  907. if t.Kind() == reflect.Ptr {
  908. t = t.Elem()
  909. }
  910. return t.Kind() == reflect.Struct
  911. }