code.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023
  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. for firstField.Op == OpStructHead || firstField.Op == OpStructField {
  334. firstField = firstField.Next
  335. }
  336. lastField := firstField
  337. for lastField.NextField != nil {
  338. lastField = lastField.NextField
  339. }
  340. return lastField
  341. }
  342. func (c *StructCode) ToOpcode(ctx *compileContext) Opcodes {
  343. // header => code => structField => code => end
  344. // ^ |
  345. // |__________|
  346. if c.isRecursive {
  347. recursive := newRecursiveCode(ctx, c.typ, &CompiledCode{})
  348. recursive.Type = c.typ
  349. ctx.incIndex()
  350. *ctx.recursiveCodes = append(*ctx.recursiveCodes, recursive)
  351. return Opcodes{recursive}
  352. }
  353. codes := Opcodes{}
  354. var prevField *Opcode
  355. ctx.incIndent()
  356. for idx, field := range c.fields {
  357. isFirstField := idx == 0
  358. isEndField := idx == len(c.fields)-1
  359. fieldCodes := field.ToOpcode(ctx, isFirstField, isEndField)
  360. for _, code := range fieldCodes {
  361. if c.isIndirect {
  362. code.Flags |= IndirectFlags
  363. }
  364. }
  365. firstField := fieldCodes.First()
  366. if len(codes) > 0 {
  367. codes.Last().Next = firstField
  368. firstField.Idx = codes.First().Idx
  369. }
  370. if prevField != nil {
  371. prevField.NextField = firstField
  372. }
  373. if isEndField {
  374. endField := fieldCodes.Last()
  375. if len(codes) > 0 {
  376. codes.First().End = endField
  377. } else {
  378. firstField.End = endField
  379. }
  380. codes = codes.Add(fieldCodes...)
  381. break
  382. }
  383. prevField = c.lastFieldCode(field, firstField)
  384. codes = codes.Add(fieldCodes...)
  385. }
  386. if len(codes) == 0 {
  387. head := &Opcode{
  388. Op: OpStructHead,
  389. Idx: opcodeOffset(ctx.ptrIndex),
  390. Type: c.typ,
  391. DisplayIdx: ctx.opcodeIndex,
  392. Indent: ctx.indent,
  393. }
  394. ctx.incOpcodeIndex()
  395. end := &Opcode{
  396. Op: OpStructEnd,
  397. Idx: opcodeOffset(ctx.ptrIndex),
  398. DisplayIdx: ctx.opcodeIndex,
  399. Indent: ctx.indent,
  400. }
  401. head.NextField = end
  402. head.Next = end
  403. head.End = end
  404. codes = codes.Add(head, end)
  405. ctx.incIndex()
  406. }
  407. ctx.decIndent()
  408. ctx.structTypeToCodes[uintptr(unsafe.Pointer(c.typ))] = codes
  409. return codes
  410. }
  411. func (c *StructCode) ToAnonymousOpcode(ctx *compileContext) Opcodes {
  412. // header => code => structField => code => end
  413. // ^ |
  414. // |__________|
  415. if c.isRecursive {
  416. recursive := newRecursiveCode(ctx, c.typ, &CompiledCode{})
  417. recursive.Type = c.typ
  418. ctx.incIndex()
  419. *ctx.recursiveCodes = append(*ctx.recursiveCodes, recursive)
  420. return Opcodes{recursive}
  421. }
  422. codes := Opcodes{}
  423. var prevField *Opcode
  424. for idx, field := range c.fields {
  425. isFirstField := idx == 0
  426. isEndField := idx == len(c.fields)-1
  427. fieldCodes := field.ToAnonymousOpcode(ctx, isFirstField, isEndField)
  428. for _, code := range fieldCodes {
  429. if c.isIndirect {
  430. code.Flags |= IndirectFlags
  431. }
  432. }
  433. firstField := fieldCodes.First()
  434. if len(codes) > 0 {
  435. codes.Last().Next = firstField
  436. firstField.Idx = codes.First().Idx
  437. }
  438. if prevField != nil {
  439. prevField.NextField = firstField
  440. }
  441. if isEndField {
  442. lastField := fieldCodes.Last()
  443. if len(codes) > 0 {
  444. codes.First().End = lastField
  445. } else {
  446. firstField.End = lastField
  447. }
  448. }
  449. prevField = firstField
  450. codes = codes.Add(fieldCodes...)
  451. }
  452. return codes
  453. }
  454. func (c *StructCode) removeFieldsByTags(tags runtime.StructTags) {
  455. fields := make([]*StructFieldCode, 0, len(c.fields))
  456. for _, field := range c.fields {
  457. if field.isAnonymous {
  458. structCode := field.getAnonymousStruct()
  459. if structCode != nil && !structCode.isRecursive {
  460. structCode.removeFieldsByTags(tags)
  461. if len(structCode.fields) > 0 {
  462. fields = append(fields, field)
  463. }
  464. continue
  465. }
  466. }
  467. if tags.ExistsKey(field.key) {
  468. continue
  469. }
  470. fields = append(fields, field)
  471. }
  472. c.fields = fields
  473. }
  474. func (c *StructCode) enableIndirect() {
  475. if c.isIndirect {
  476. return
  477. }
  478. c.isIndirect = true
  479. if len(c.fields) == 0 {
  480. return
  481. }
  482. structCode := c.fields[0].getStruct()
  483. if structCode == nil {
  484. return
  485. }
  486. structCode.enableIndirect()
  487. }
  488. func (c *StructCode) Filter(query *FieldQuery) Code {
  489. fieldMap := map[string]*FieldQuery{}
  490. for _, field := range query.Fields {
  491. fieldMap[field.Name] = field
  492. }
  493. fields := make([]*StructFieldCode, 0, len(c.fields))
  494. for _, field := range c.fields {
  495. query, exists := fieldMap[field.key]
  496. if !exists {
  497. continue
  498. }
  499. fieldCode := &StructFieldCode{
  500. typ: field.typ,
  501. key: field.key,
  502. tag: field.tag,
  503. value: field.value,
  504. offset: field.offset,
  505. isAnonymous: field.isAnonymous,
  506. isTaggedKey: field.isTaggedKey,
  507. isNilableType: field.isNilableType,
  508. isNilCheck: field.isNilCheck,
  509. isAddrForMarshaler: field.isAddrForMarshaler,
  510. isNextOpPtrType: field.isNextOpPtrType,
  511. }
  512. if len(query.Fields) > 0 {
  513. fieldCode.value = fieldCode.value.Filter(query)
  514. }
  515. fields = append(fields, fieldCode)
  516. }
  517. return &StructCode{
  518. typ: c.typ,
  519. fields: fields,
  520. isPtr: c.isPtr,
  521. disableIndirectConversion: c.disableIndirectConversion,
  522. isIndirect: c.isIndirect,
  523. isRecursive: c.isRecursive,
  524. }
  525. }
  526. type StructFieldCode struct {
  527. typ *runtime.Type
  528. key string
  529. tag *runtime.StructTag
  530. value Code
  531. offset uintptr
  532. isAnonymous bool
  533. isTaggedKey bool
  534. isNilableType bool
  535. isNilCheck bool
  536. isAddrForMarshaler bool
  537. isNextOpPtrType bool
  538. isMarshalerContext bool
  539. }
  540. func (c *StructFieldCode) getStruct() *StructCode {
  541. value := c.value
  542. ptr, ok := value.(*PtrCode)
  543. if ok {
  544. value = ptr.value
  545. }
  546. structCode, ok := value.(*StructCode)
  547. if ok {
  548. return structCode
  549. }
  550. return nil
  551. }
  552. func (c *StructFieldCode) getAnonymousStruct() *StructCode {
  553. if !c.isAnonymous {
  554. return nil
  555. }
  556. return c.getStruct()
  557. }
  558. func optimizeStructHeader(code *Opcode, tag *runtime.StructTag) OpType {
  559. headType := code.ToHeaderType(tag.IsString)
  560. if tag.IsOmitEmpty {
  561. headType = headType.HeadToOmitEmptyHead()
  562. }
  563. return headType
  564. }
  565. func optimizeStructField(code *Opcode, tag *runtime.StructTag) OpType {
  566. fieldType := code.ToFieldType(tag.IsString)
  567. if tag.IsOmitEmpty {
  568. fieldType = fieldType.FieldToOmitEmptyField()
  569. }
  570. return fieldType
  571. }
  572. func (c *StructFieldCode) headerOpcodes(ctx *compileContext, field *Opcode, valueCodes Opcodes) Opcodes {
  573. value := valueCodes.First()
  574. op := optimizeStructHeader(value, c.tag)
  575. field.Op = op
  576. if value.Flags&MarshalerContextFlags != 0 {
  577. field.Flags |= MarshalerContextFlags
  578. }
  579. field.NumBitSize = value.NumBitSize
  580. field.PtrNum = value.PtrNum
  581. field.FieldQuery = value.FieldQuery
  582. fieldCodes := Opcodes{field}
  583. if op.IsMultipleOpHead() {
  584. field.Next = value
  585. fieldCodes = fieldCodes.Add(valueCodes...)
  586. } else {
  587. ctx.decIndex()
  588. }
  589. return fieldCodes
  590. }
  591. func (c *StructFieldCode) fieldOpcodes(ctx *compileContext, field *Opcode, valueCodes Opcodes) Opcodes {
  592. value := valueCodes.First()
  593. op := optimizeStructField(value, c.tag)
  594. field.Op = op
  595. if value.Flags&MarshalerContextFlags != 0 {
  596. field.Flags |= MarshalerContextFlags
  597. }
  598. field.NumBitSize = value.NumBitSize
  599. field.PtrNum = value.PtrNum
  600. field.FieldQuery = value.FieldQuery
  601. fieldCodes := Opcodes{field}
  602. if op.IsMultipleOpField() {
  603. field.Next = value
  604. fieldCodes = fieldCodes.Add(valueCodes...)
  605. } else {
  606. ctx.decIndex()
  607. }
  608. return fieldCodes
  609. }
  610. func (c *StructFieldCode) addStructEndCode(ctx *compileContext, codes Opcodes) Opcodes {
  611. end := &Opcode{
  612. Op: OpStructEnd,
  613. Idx: opcodeOffset(ctx.ptrIndex),
  614. DisplayIdx: ctx.opcodeIndex,
  615. Indent: ctx.indent,
  616. }
  617. codes.Last().Next = end
  618. code := codes.First()
  619. for code.Op == OpStructField || code.Op == OpStructHead {
  620. code = code.Next
  621. }
  622. for code.NextField != nil {
  623. code = code.NextField
  624. }
  625. code.NextField = end
  626. codes = codes.Add(end)
  627. ctx.incOpcodeIndex()
  628. return codes
  629. }
  630. func (c *StructFieldCode) structKey(ctx *compileContext) string {
  631. if ctx.escapeKey {
  632. rctx := &RuntimeContext{Option: &Option{Flag: HTMLEscapeOption}}
  633. return fmt.Sprintf(`%s:`, string(AppendString(rctx, []byte{}, c.key)))
  634. }
  635. return fmt.Sprintf(`"%s":`, c.key)
  636. }
  637. func (c *StructFieldCode) flags() OpFlags {
  638. var flags OpFlags
  639. if c.isTaggedKey {
  640. flags |= IsTaggedKeyFlags
  641. }
  642. if c.isNilableType {
  643. flags |= IsNilableTypeFlags
  644. }
  645. if c.isNilCheck {
  646. flags |= NilCheckFlags
  647. }
  648. if c.isAddrForMarshaler {
  649. flags |= AddrForMarshalerFlags
  650. }
  651. if c.isNextOpPtrType {
  652. flags |= IsNextOpPtrTypeFlags
  653. }
  654. if c.isAnonymous {
  655. flags |= AnonymousKeyFlags
  656. }
  657. if c.isMarshalerContext {
  658. flags |= MarshalerContextFlags
  659. }
  660. return flags
  661. }
  662. func (c *StructFieldCode) toValueOpcodes(ctx *compileContext) Opcodes {
  663. if c.isAnonymous {
  664. anonymCode, ok := c.value.(AnonymousCode)
  665. if ok {
  666. return anonymCode.ToAnonymousOpcode(ctx)
  667. }
  668. }
  669. return c.value.ToOpcode(ctx)
  670. }
  671. func (c *StructFieldCode) ToOpcode(ctx *compileContext, isFirstField, isEndField bool) Opcodes {
  672. field := &Opcode{
  673. Idx: opcodeOffset(ctx.ptrIndex),
  674. Flags: c.flags(),
  675. Key: c.structKey(ctx),
  676. Offset: uint32(c.offset),
  677. Type: c.typ,
  678. DisplayIdx: ctx.opcodeIndex,
  679. Indent: ctx.indent,
  680. DisplayKey: c.key,
  681. }
  682. ctx.incIndex()
  683. valueCodes := c.toValueOpcodes(ctx)
  684. if isFirstField {
  685. codes := c.headerOpcodes(ctx, field, valueCodes)
  686. if isEndField {
  687. codes = c.addStructEndCode(ctx, codes)
  688. }
  689. return codes
  690. }
  691. codes := c.fieldOpcodes(ctx, field, valueCodes)
  692. if isEndField {
  693. if isEnableStructEndOptimization(c.value) {
  694. field.Op = field.Op.FieldToEnd()
  695. } else {
  696. codes = c.addStructEndCode(ctx, codes)
  697. }
  698. }
  699. return codes
  700. }
  701. func (c *StructFieldCode) ToAnonymousOpcode(ctx *compileContext, isFirstField, isEndField bool) Opcodes {
  702. field := &Opcode{
  703. Idx: opcodeOffset(ctx.ptrIndex),
  704. Flags: c.flags() | AnonymousHeadFlags,
  705. Key: c.structKey(ctx),
  706. Offset: uint32(c.offset),
  707. Type: c.typ,
  708. DisplayIdx: ctx.opcodeIndex,
  709. Indent: ctx.indent,
  710. DisplayKey: c.key,
  711. }
  712. ctx.incIndex()
  713. valueCodes := c.toValueOpcodes(ctx)
  714. if isFirstField {
  715. return c.headerOpcodes(ctx, field, valueCodes)
  716. }
  717. return c.fieldOpcodes(ctx, field, valueCodes)
  718. }
  719. func isEnableStructEndOptimization(value Code) bool {
  720. switch value.Kind() {
  721. case CodeKindInt,
  722. CodeKindUint,
  723. CodeKindFloat,
  724. CodeKindString,
  725. CodeKindBool,
  726. CodeKindBytes:
  727. return true
  728. case CodeKindPtr:
  729. return isEnableStructEndOptimization(value.(*PtrCode).value)
  730. default:
  731. return false
  732. }
  733. }
  734. type InterfaceCode struct {
  735. typ *runtime.Type
  736. fieldQuery *FieldQuery
  737. isPtr bool
  738. }
  739. func (c *InterfaceCode) Kind() CodeKind {
  740. return CodeKindInterface
  741. }
  742. func (c *InterfaceCode) ToOpcode(ctx *compileContext) Opcodes {
  743. var code *Opcode
  744. switch {
  745. case c.isPtr:
  746. code = newOpCode(ctx, c.typ, OpInterfacePtr)
  747. default:
  748. code = newOpCode(ctx, c.typ, OpInterface)
  749. }
  750. code.FieldQuery = c.fieldQuery
  751. if c.typ.NumMethod() > 0 {
  752. code.Flags |= NonEmptyInterfaceFlags
  753. }
  754. ctx.incIndex()
  755. return Opcodes{code}
  756. }
  757. func (c *InterfaceCode) Filter(query *FieldQuery) Code {
  758. return &InterfaceCode{
  759. typ: c.typ,
  760. fieldQuery: query,
  761. isPtr: c.isPtr,
  762. }
  763. }
  764. type MarshalJSONCode struct {
  765. typ *runtime.Type
  766. fieldQuery *FieldQuery
  767. isAddrForMarshaler bool
  768. isNilableType bool
  769. isMarshalerContext bool
  770. }
  771. func (c *MarshalJSONCode) Kind() CodeKind {
  772. return CodeKindMarshalJSON
  773. }
  774. func (c *MarshalJSONCode) ToOpcode(ctx *compileContext) Opcodes {
  775. code := newOpCode(ctx, c.typ, OpMarshalJSON)
  776. code.FieldQuery = c.fieldQuery
  777. if c.isAddrForMarshaler {
  778. code.Flags |= AddrForMarshalerFlags
  779. }
  780. if c.isMarshalerContext {
  781. code.Flags |= MarshalerContextFlags
  782. }
  783. if c.isNilableType {
  784. code.Flags |= IsNilableTypeFlags
  785. } else {
  786. code.Flags &= ^IsNilableTypeFlags
  787. }
  788. ctx.incIndex()
  789. return Opcodes{code}
  790. }
  791. func (c *MarshalJSONCode) Filter(query *FieldQuery) Code {
  792. return &MarshalJSONCode{
  793. typ: c.typ,
  794. fieldQuery: query,
  795. isAddrForMarshaler: c.isAddrForMarshaler,
  796. isNilableType: c.isNilableType,
  797. isMarshalerContext: c.isMarshalerContext,
  798. }
  799. }
  800. type MarshalTextCode struct {
  801. typ *runtime.Type
  802. fieldQuery *FieldQuery
  803. isAddrForMarshaler bool
  804. isNilableType bool
  805. }
  806. func (c *MarshalTextCode) Kind() CodeKind {
  807. return CodeKindMarshalText
  808. }
  809. func (c *MarshalTextCode) ToOpcode(ctx *compileContext) Opcodes {
  810. code := newOpCode(ctx, c.typ, OpMarshalText)
  811. code.FieldQuery = c.fieldQuery
  812. if c.isAddrForMarshaler {
  813. code.Flags |= AddrForMarshalerFlags
  814. }
  815. if c.isNilableType {
  816. code.Flags |= IsNilableTypeFlags
  817. } else {
  818. code.Flags &= ^IsNilableTypeFlags
  819. }
  820. ctx.incIndex()
  821. return Opcodes{code}
  822. }
  823. func (c *MarshalTextCode) Filter(query *FieldQuery) Code {
  824. return &MarshalTextCode{
  825. typ: c.typ,
  826. fieldQuery: query,
  827. isAddrForMarshaler: c.isAddrForMarshaler,
  828. isNilableType: c.isNilableType,
  829. }
  830. }
  831. type PtrCode struct {
  832. typ *runtime.Type
  833. value Code
  834. ptrNum uint8
  835. }
  836. func (c *PtrCode) Kind() CodeKind {
  837. return CodeKindPtr
  838. }
  839. func (c *PtrCode) ToOpcode(ctx *compileContext) Opcodes {
  840. codes := c.value.ToOpcode(ctx)
  841. codes.First().Op = convertPtrOp(codes.First())
  842. codes.First().PtrNum = c.ptrNum
  843. return codes
  844. }
  845. func (c *PtrCode) ToAnonymousOpcode(ctx *compileContext) Opcodes {
  846. var codes Opcodes
  847. anonymCode, ok := c.value.(AnonymousCode)
  848. if ok {
  849. codes = anonymCode.ToAnonymousOpcode(ctx)
  850. } else {
  851. codes = c.value.ToOpcode(ctx)
  852. }
  853. codes.First().Op = convertPtrOp(codes.First())
  854. codes.First().PtrNum = c.ptrNum
  855. return codes
  856. }
  857. func (c *PtrCode) Filter(query *FieldQuery) Code {
  858. return &PtrCode{
  859. typ: c.typ,
  860. value: c.value.Filter(query),
  861. ptrNum: c.ptrNum,
  862. }
  863. }
  864. func convertPtrOp(code *Opcode) OpType {
  865. ptrHeadOp := code.Op.HeadToPtrHead()
  866. if code.Op != ptrHeadOp {
  867. if code.PtrNum > 0 {
  868. // ptr field and ptr head
  869. code.PtrNum--
  870. }
  871. return ptrHeadOp
  872. }
  873. switch code.Op {
  874. case OpInt:
  875. return OpIntPtr
  876. case OpUint:
  877. return OpUintPtr
  878. case OpFloat32:
  879. return OpFloat32Ptr
  880. case OpFloat64:
  881. return OpFloat64Ptr
  882. case OpString:
  883. return OpStringPtr
  884. case OpBool:
  885. return OpBoolPtr
  886. case OpBytes:
  887. return OpBytesPtr
  888. case OpNumber:
  889. return OpNumberPtr
  890. case OpArray:
  891. return OpArrayPtr
  892. case OpSlice:
  893. return OpSlicePtr
  894. case OpMap:
  895. return OpMapPtr
  896. case OpMarshalJSON:
  897. return OpMarshalJSONPtr
  898. case OpMarshalText:
  899. return OpMarshalTextPtr
  900. case OpInterface:
  901. return OpInterfacePtr
  902. case OpRecursive:
  903. return OpRecursivePtr
  904. }
  905. return code.Op
  906. }
  907. func isEmbeddedStruct(field *StructFieldCode) bool {
  908. if !field.isAnonymous {
  909. return false
  910. }
  911. t := field.typ
  912. if t.Kind() == reflect.Ptr {
  913. t = t.Elem()
  914. }
  915. return t.Kind() == reflect.Struct
  916. }