summaryrefslogtreecommitdiff
path: root/vendor/github.com/goccy/go-json/internal/encoder/code.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/goccy/go-json/internal/encoder/code.go')
-rw-r--r--vendor/github.com/goccy/go-json/internal/encoder/code.go1023
1 files changed, 0 insertions, 1023 deletions
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/code.go b/vendor/github.com/goccy/go-json/internal/encoder/code.go
deleted file mode 100644
index 5b08faefc..000000000
--- a/vendor/github.com/goccy/go-json/internal/encoder/code.go
+++ /dev/null
@@ -1,1023 +0,0 @@
-package encoder
-
-import (
- "fmt"
- "reflect"
- "unsafe"
-
- "github.com/goccy/go-json/internal/runtime"
-)
-
-type Code interface {
- Kind() CodeKind
- ToOpcode(*compileContext) Opcodes
- Filter(*FieldQuery) Code
-}
-
-type AnonymousCode interface {
- ToAnonymousOpcode(*compileContext) Opcodes
-}
-
-type Opcodes []*Opcode
-
-func (o Opcodes) First() *Opcode {
- if len(o) == 0 {
- return nil
- }
- return o[0]
-}
-
-func (o Opcodes) Last() *Opcode {
- if len(o) == 0 {
- return nil
- }
- return o[len(o)-1]
-}
-
-func (o Opcodes) Add(codes ...*Opcode) Opcodes {
- return append(o, codes...)
-}
-
-type CodeKind int
-
-const (
- CodeKindInterface CodeKind = iota
- CodeKindPtr
- CodeKindInt
- CodeKindUint
- CodeKindFloat
- CodeKindString
- CodeKindBool
- CodeKindStruct
- CodeKindMap
- CodeKindSlice
- CodeKindArray
- CodeKindBytes
- CodeKindMarshalJSON
- CodeKindMarshalText
- CodeKindRecursive
-)
-
-type IntCode struct {
- typ *runtime.Type
- bitSize uint8
- isString bool
- isPtr bool
-}
-
-func (c *IntCode) Kind() CodeKind {
- return CodeKindInt
-}
-
-func (c *IntCode) ToOpcode(ctx *compileContext) Opcodes {
- var code *Opcode
- switch {
- case c.isPtr:
- code = newOpCode(ctx, c.typ, OpIntPtr)
- case c.isString:
- code = newOpCode(ctx, c.typ, OpIntString)
- default:
- code = newOpCode(ctx, c.typ, OpInt)
- }
- code.NumBitSize = c.bitSize
- ctx.incIndex()
- return Opcodes{code}
-}
-
-func (c *IntCode) Filter(_ *FieldQuery) Code {
- return c
-}
-
-type UintCode struct {
- typ *runtime.Type
- bitSize uint8
- isString bool
- isPtr bool
-}
-
-func (c *UintCode) Kind() CodeKind {
- return CodeKindUint
-}
-
-func (c *UintCode) ToOpcode(ctx *compileContext) Opcodes {
- var code *Opcode
- switch {
- case c.isPtr:
- code = newOpCode(ctx, c.typ, OpUintPtr)
- case c.isString:
- code = newOpCode(ctx, c.typ, OpUintString)
- default:
- code = newOpCode(ctx, c.typ, OpUint)
- }
- code.NumBitSize = c.bitSize
- ctx.incIndex()
- return Opcodes{code}
-}
-
-func (c *UintCode) Filter(_ *FieldQuery) Code {
- return c
-}
-
-type FloatCode struct {
- typ *runtime.Type
- bitSize uint8
- isPtr bool
-}
-
-func (c *FloatCode) Kind() CodeKind {
- return CodeKindFloat
-}
-
-func (c *FloatCode) ToOpcode(ctx *compileContext) Opcodes {
- var code *Opcode
- switch {
- case c.isPtr:
- switch c.bitSize {
- case 32:
- code = newOpCode(ctx, c.typ, OpFloat32Ptr)
- default:
- code = newOpCode(ctx, c.typ, OpFloat64Ptr)
- }
- default:
- switch c.bitSize {
- case 32:
- code = newOpCode(ctx, c.typ, OpFloat32)
- default:
- code = newOpCode(ctx, c.typ, OpFloat64)
- }
- }
- ctx.incIndex()
- return Opcodes{code}
-}
-
-func (c *FloatCode) Filter(_ *FieldQuery) Code {
- return c
-}
-
-type StringCode struct {
- typ *runtime.Type
- isPtr bool
-}
-
-func (c *StringCode) Kind() CodeKind {
- return CodeKindString
-}
-
-func (c *StringCode) ToOpcode(ctx *compileContext) Opcodes {
- isJSONNumberType := c.typ == runtime.Type2RType(jsonNumberType)
- var code *Opcode
- if c.isPtr {
- if isJSONNumberType {
- code = newOpCode(ctx, c.typ, OpNumberPtr)
- } else {
- code = newOpCode(ctx, c.typ, OpStringPtr)
- }
- } else {
- if isJSONNumberType {
- code = newOpCode(ctx, c.typ, OpNumber)
- } else {
- code = newOpCode(ctx, c.typ, OpString)
- }
- }
- ctx.incIndex()
- return Opcodes{code}
-}
-
-func (c *StringCode) Filter(_ *FieldQuery) Code {
- return c
-}
-
-type BoolCode struct {
- typ *runtime.Type
- isPtr bool
-}
-
-func (c *BoolCode) Kind() CodeKind {
- return CodeKindBool
-}
-
-func (c *BoolCode) ToOpcode(ctx *compileContext) Opcodes {
- var code *Opcode
- switch {
- case c.isPtr:
- code = newOpCode(ctx, c.typ, OpBoolPtr)
- default:
- code = newOpCode(ctx, c.typ, OpBool)
- }
- ctx.incIndex()
- return Opcodes{code}
-}
-
-func (c *BoolCode) Filter(_ *FieldQuery) Code {
- return c
-}
-
-type BytesCode struct {
- typ *runtime.Type
- isPtr bool
-}
-
-func (c *BytesCode) Kind() CodeKind {
- return CodeKindBytes
-}
-
-func (c *BytesCode) ToOpcode(ctx *compileContext) Opcodes {
- var code *Opcode
- switch {
- case c.isPtr:
- code = newOpCode(ctx, c.typ, OpBytesPtr)
- default:
- code = newOpCode(ctx, c.typ, OpBytes)
- }
- ctx.incIndex()
- return Opcodes{code}
-}
-
-func (c *BytesCode) Filter(_ *FieldQuery) Code {
- return c
-}
-
-type SliceCode struct {
- typ *runtime.Type
- value Code
-}
-
-func (c *SliceCode) Kind() CodeKind {
- return CodeKindSlice
-}
-
-func (c *SliceCode) ToOpcode(ctx *compileContext) Opcodes {
- // header => opcode => elem => end
- // ^ |
- // |________|
- size := c.typ.Elem().Size()
- header := newSliceHeaderCode(ctx, c.typ)
- ctx.incIndex()
-
- ctx.incIndent()
- codes := c.value.ToOpcode(ctx)
- ctx.decIndent()
-
- codes.First().Flags |= IndirectFlags
- elemCode := newSliceElemCode(ctx, c.typ.Elem(), header, size)
- ctx.incIndex()
- end := newOpCode(ctx, c.typ, OpSliceEnd)
- ctx.incIndex()
- header.End = end
- header.Next = codes.First()
- codes.Last().Next = elemCode
- elemCode.Next = codes.First()
- elemCode.End = end
- return Opcodes{header}.Add(codes...).Add(elemCode).Add(end)
-}
-
-func (c *SliceCode) Filter(_ *FieldQuery) Code {
- return c
-}
-
-type ArrayCode struct {
- typ *runtime.Type
- value Code
-}
-
-func (c *ArrayCode) Kind() CodeKind {
- return CodeKindArray
-}
-
-func (c *ArrayCode) ToOpcode(ctx *compileContext) Opcodes {
- // header => opcode => elem => end
- // ^ |
- // |________|
- elem := c.typ.Elem()
- alen := c.typ.Len()
- size := elem.Size()
-
- header := newArrayHeaderCode(ctx, c.typ, alen)
- ctx.incIndex()
-
- ctx.incIndent()
- codes := c.value.ToOpcode(ctx)
- ctx.decIndent()
-
- codes.First().Flags |= IndirectFlags
-
- elemCode := newArrayElemCode(ctx, elem, header, alen, size)
- ctx.incIndex()
-
- end := newOpCode(ctx, c.typ, OpArrayEnd)
- ctx.incIndex()
-
- header.End = end
- header.Next = codes.First()
- codes.Last().Next = elemCode
- elemCode.Next = codes.First()
- elemCode.End = end
-
- return Opcodes{header}.Add(codes...).Add(elemCode).Add(end)
-}
-
-func (c *ArrayCode) Filter(_ *FieldQuery) Code {
- return c
-}
-
-type MapCode struct {
- typ *runtime.Type
- key Code
- value Code
-}
-
-func (c *MapCode) Kind() CodeKind {
- return CodeKindMap
-}
-
-func (c *MapCode) ToOpcode(ctx *compileContext) Opcodes {
- // header => code => value => code => key => code => value => code => end
- // ^ |
- // |_______________________|
- header := newMapHeaderCode(ctx, c.typ)
- ctx.incIndex()
-
- keyCodes := c.key.ToOpcode(ctx)
-
- value := newMapValueCode(ctx, c.typ.Elem(), header)
- ctx.incIndex()
-
- ctx.incIndent()
- valueCodes := c.value.ToOpcode(ctx)
- ctx.decIndent()
-
- valueCodes.First().Flags |= IndirectFlags
-
- key := newMapKeyCode(ctx, c.typ.Key(), header)
- ctx.incIndex()
-
- end := newMapEndCode(ctx, c.typ, header)
- ctx.incIndex()
-
- header.Next = keyCodes.First()
- keyCodes.Last().Next = value
- value.Next = valueCodes.First()
- valueCodes.Last().Next = key
- key.Next = keyCodes.First()
-
- header.End = end
- key.End = end
- value.End = end
- return Opcodes{header}.Add(keyCodes...).Add(value).Add(valueCodes...).Add(key).Add(end)
-}
-
-func (c *MapCode) Filter(_ *FieldQuery) Code {
- return c
-}
-
-type StructCode struct {
- typ *runtime.Type
- fields []*StructFieldCode
- isPtr bool
- disableIndirectConversion bool
- isIndirect bool
- isRecursive bool
-}
-
-func (c *StructCode) Kind() CodeKind {
- return CodeKindStruct
-}
-
-func (c *StructCode) lastFieldCode(field *StructFieldCode, firstField *Opcode) *Opcode {
- if isEmbeddedStruct(field) {
- return c.lastAnonymousFieldCode(firstField)
- }
- lastField := firstField
- for lastField.NextField != nil {
- lastField = lastField.NextField
- }
- return lastField
-}
-
-func (c *StructCode) lastAnonymousFieldCode(firstField *Opcode) *Opcode {
- // firstField is special StructHead operation for anonymous structure.
- // So, StructHead's next operation is truly struct head operation.
- for firstField.Op == OpStructHead || firstField.Op == OpStructField {
- firstField = firstField.Next
- }
- lastField := firstField
- for lastField.NextField != nil {
- lastField = lastField.NextField
- }
- return lastField
-}
-
-func (c *StructCode) ToOpcode(ctx *compileContext) Opcodes {
- // header => code => structField => code => end
- // ^ |
- // |__________|
- if c.isRecursive {
- recursive := newRecursiveCode(ctx, c.typ, &CompiledCode{})
- recursive.Type = c.typ
- ctx.incIndex()
- *ctx.recursiveCodes = append(*ctx.recursiveCodes, recursive)
- return Opcodes{recursive}
- }
- codes := Opcodes{}
- var prevField *Opcode
- ctx.incIndent()
- for idx, field := range c.fields {
- isFirstField := idx == 0
- isEndField := idx == len(c.fields)-1
- fieldCodes := field.ToOpcode(ctx, isFirstField, isEndField)
- for _, code := range fieldCodes {
- if c.isIndirect {
- code.Flags |= IndirectFlags
- }
- }
- firstField := fieldCodes.First()
- if len(codes) > 0 {
- codes.Last().Next = firstField
- firstField.Idx = codes.First().Idx
- }
- if prevField != nil {
- prevField.NextField = firstField
- }
- if isEndField {
- endField := fieldCodes.Last()
- if len(codes) > 0 {
- codes.First().End = endField
- } else {
- firstField.End = endField
- }
- codes = codes.Add(fieldCodes...)
- break
- }
- prevField = c.lastFieldCode(field, firstField)
- codes = codes.Add(fieldCodes...)
- }
- if len(codes) == 0 {
- head := &Opcode{
- Op: OpStructHead,
- Idx: opcodeOffset(ctx.ptrIndex),
- Type: c.typ,
- DisplayIdx: ctx.opcodeIndex,
- Indent: ctx.indent,
- }
- ctx.incOpcodeIndex()
- end := &Opcode{
- Op: OpStructEnd,
- Idx: opcodeOffset(ctx.ptrIndex),
- DisplayIdx: ctx.opcodeIndex,
- Indent: ctx.indent,
- }
- head.NextField = end
- head.Next = end
- head.End = end
- codes = codes.Add(head, end)
- ctx.incIndex()
- }
- ctx.decIndent()
- ctx.structTypeToCodes[uintptr(unsafe.Pointer(c.typ))] = codes
- return codes
-}
-
-func (c *StructCode) ToAnonymousOpcode(ctx *compileContext) Opcodes {
- // header => code => structField => code => end
- // ^ |
- // |__________|
- if c.isRecursive {
- recursive := newRecursiveCode(ctx, c.typ, &CompiledCode{})
- recursive.Type = c.typ
- ctx.incIndex()
- *ctx.recursiveCodes = append(*ctx.recursiveCodes, recursive)
- return Opcodes{recursive}
- }
- codes := Opcodes{}
- var prevField *Opcode
- for idx, field := range c.fields {
- isFirstField := idx == 0
- isEndField := idx == len(c.fields)-1
- fieldCodes := field.ToAnonymousOpcode(ctx, isFirstField, isEndField)
- for _, code := range fieldCodes {
- if c.isIndirect {
- code.Flags |= IndirectFlags
- }
- }
- firstField := fieldCodes.First()
- if len(codes) > 0 {
- codes.Last().Next = firstField
- firstField.Idx = codes.First().Idx
- }
- if prevField != nil {
- prevField.NextField = firstField
- }
- if isEndField {
- lastField := fieldCodes.Last()
- if len(codes) > 0 {
- codes.First().End = lastField
- } else {
- firstField.End = lastField
- }
- }
- prevField = firstField
- codes = codes.Add(fieldCodes...)
- }
- return codes
-}
-
-func (c *StructCode) removeFieldsByTags(tags runtime.StructTags) {
- fields := make([]*StructFieldCode, 0, len(c.fields))
- for _, field := range c.fields {
- if field.isAnonymous {
- structCode := field.getAnonymousStruct()
- if structCode != nil && !structCode.isRecursive {
- structCode.removeFieldsByTags(tags)
- if len(structCode.fields) > 0 {
- fields = append(fields, field)
- }
- continue
- }
- }
- if tags.ExistsKey(field.key) {
- continue
- }
- fields = append(fields, field)
- }
- c.fields = fields
-}
-
-func (c *StructCode) enableIndirect() {
- if c.isIndirect {
- return
- }
- c.isIndirect = true
- if len(c.fields) == 0 {
- return
- }
- structCode := c.fields[0].getStruct()
- if structCode == nil {
- return
- }
- structCode.enableIndirect()
-}
-
-func (c *StructCode) Filter(query *FieldQuery) Code {
- fieldMap := map[string]*FieldQuery{}
- for _, field := range query.Fields {
- fieldMap[field.Name] = field
- }
- fields := make([]*StructFieldCode, 0, len(c.fields))
- for _, field := range c.fields {
- query, exists := fieldMap[field.key]
- if !exists {
- continue
- }
- fieldCode := &StructFieldCode{
- typ: field.typ,
- key: field.key,
- tag: field.tag,
- value: field.value,
- offset: field.offset,
- isAnonymous: field.isAnonymous,
- isTaggedKey: field.isTaggedKey,
- isNilableType: field.isNilableType,
- isNilCheck: field.isNilCheck,
- isAddrForMarshaler: field.isAddrForMarshaler,
- isNextOpPtrType: field.isNextOpPtrType,
- }
- if len(query.Fields) > 0 {
- fieldCode.value = fieldCode.value.Filter(query)
- }
- fields = append(fields, fieldCode)
- }
- return &StructCode{
- typ: c.typ,
- fields: fields,
- isPtr: c.isPtr,
- disableIndirectConversion: c.disableIndirectConversion,
- isIndirect: c.isIndirect,
- isRecursive: c.isRecursive,
- }
-}
-
-type StructFieldCode struct {
- typ *runtime.Type
- key string
- tag *runtime.StructTag
- value Code
- offset uintptr
- isAnonymous bool
- isTaggedKey bool
- isNilableType bool
- isNilCheck bool
- isAddrForMarshaler bool
- isNextOpPtrType bool
- isMarshalerContext bool
-}
-
-func (c *StructFieldCode) getStruct() *StructCode {
- value := c.value
- ptr, ok := value.(*PtrCode)
- if ok {
- value = ptr.value
- }
- structCode, ok := value.(*StructCode)
- if ok {
- return structCode
- }
- return nil
-}
-
-func (c *StructFieldCode) getAnonymousStruct() *StructCode {
- if !c.isAnonymous {
- return nil
- }
- return c.getStruct()
-}
-
-func optimizeStructHeader(code *Opcode, tag *runtime.StructTag) OpType {
- headType := code.ToHeaderType(tag.IsString)
- if tag.IsOmitEmpty {
- headType = headType.HeadToOmitEmptyHead()
- }
- return headType
-}
-
-func optimizeStructField(code *Opcode, tag *runtime.StructTag) OpType {
- fieldType := code.ToFieldType(tag.IsString)
- if tag.IsOmitEmpty {
- fieldType = fieldType.FieldToOmitEmptyField()
- }
- return fieldType
-}
-
-func (c *StructFieldCode) headerOpcodes(ctx *compileContext, field *Opcode, valueCodes Opcodes) Opcodes {
- value := valueCodes.First()
- op := optimizeStructHeader(value, c.tag)
- field.Op = op
- if value.Flags&MarshalerContextFlags != 0 {
- field.Flags |= MarshalerContextFlags
- }
- field.NumBitSize = value.NumBitSize
- field.PtrNum = value.PtrNum
- field.FieldQuery = value.FieldQuery
- fieldCodes := Opcodes{field}
- if op.IsMultipleOpHead() {
- field.Next = value
- fieldCodes = fieldCodes.Add(valueCodes...)
- } else {
- ctx.decIndex()
- }
- return fieldCodes
-}
-
-func (c *StructFieldCode) fieldOpcodes(ctx *compileContext, field *Opcode, valueCodes Opcodes) Opcodes {
- value := valueCodes.First()
- op := optimizeStructField(value, c.tag)
- field.Op = op
- if value.Flags&MarshalerContextFlags != 0 {
- field.Flags |= MarshalerContextFlags
- }
- field.NumBitSize = value.NumBitSize
- field.PtrNum = value.PtrNum
- field.FieldQuery = value.FieldQuery
-
- fieldCodes := Opcodes{field}
- if op.IsMultipleOpField() {
- field.Next = value
- fieldCodes = fieldCodes.Add(valueCodes...)
- } else {
- ctx.decIndex()
- }
- return fieldCodes
-}
-
-func (c *StructFieldCode) addStructEndCode(ctx *compileContext, codes Opcodes) Opcodes {
- end := &Opcode{
- Op: OpStructEnd,
- Idx: opcodeOffset(ctx.ptrIndex),
- DisplayIdx: ctx.opcodeIndex,
- Indent: ctx.indent,
- }
- codes.Last().Next = end
- code := codes.First()
- for code.Op == OpStructField || code.Op == OpStructHead {
- code = code.Next
- }
- for code.NextField != nil {
- code = code.NextField
- }
- code.NextField = end
-
- codes = codes.Add(end)
- ctx.incOpcodeIndex()
- return codes
-}
-
-func (c *StructFieldCode) structKey(ctx *compileContext) string {
- if ctx.escapeKey {
- rctx := &RuntimeContext{Option: &Option{Flag: HTMLEscapeOption}}
- return fmt.Sprintf(`%s:`, string(AppendString(rctx, []byte{}, c.key)))
- }
- return fmt.Sprintf(`"%s":`, c.key)
-}
-
-func (c *StructFieldCode) flags() OpFlags {
- var flags OpFlags
- if c.isTaggedKey {
- flags |= IsTaggedKeyFlags
- }
- if c.isNilableType {
- flags |= IsNilableTypeFlags
- }
- if c.isNilCheck {
- flags |= NilCheckFlags
- }
- if c.isAddrForMarshaler {
- flags |= AddrForMarshalerFlags
- }
- if c.isNextOpPtrType {
- flags |= IsNextOpPtrTypeFlags
- }
- if c.isAnonymous {
- flags |= AnonymousKeyFlags
- }
- if c.isMarshalerContext {
- flags |= MarshalerContextFlags
- }
- return flags
-}
-
-func (c *StructFieldCode) toValueOpcodes(ctx *compileContext) Opcodes {
- if c.isAnonymous {
- anonymCode, ok := c.value.(AnonymousCode)
- if ok {
- return anonymCode.ToAnonymousOpcode(ctx)
- }
- }
- return c.value.ToOpcode(ctx)
-}
-
-func (c *StructFieldCode) ToOpcode(ctx *compileContext, isFirstField, isEndField bool) Opcodes {
- field := &Opcode{
- Idx: opcodeOffset(ctx.ptrIndex),
- Flags: c.flags(),
- Key: c.structKey(ctx),
- Offset: uint32(c.offset),
- Type: c.typ,
- DisplayIdx: ctx.opcodeIndex,
- Indent: ctx.indent,
- DisplayKey: c.key,
- }
- ctx.incIndex()
- valueCodes := c.toValueOpcodes(ctx)
- if isFirstField {
- codes := c.headerOpcodes(ctx, field, valueCodes)
- if isEndField {
- codes = c.addStructEndCode(ctx, codes)
- }
- return codes
- }
- codes := c.fieldOpcodes(ctx, field, valueCodes)
- if isEndField {
- if isEnableStructEndOptimization(c.value) {
- field.Op = field.Op.FieldToEnd()
- } else {
- codes = c.addStructEndCode(ctx, codes)
- }
- }
- return codes
-}
-
-func (c *StructFieldCode) ToAnonymousOpcode(ctx *compileContext, isFirstField, isEndField bool) Opcodes {
- field := &Opcode{
- Idx: opcodeOffset(ctx.ptrIndex),
- Flags: c.flags() | AnonymousHeadFlags,
- Key: c.structKey(ctx),
- Offset: uint32(c.offset),
- Type: c.typ,
- DisplayIdx: ctx.opcodeIndex,
- Indent: ctx.indent,
- DisplayKey: c.key,
- }
- ctx.incIndex()
- valueCodes := c.toValueOpcodes(ctx)
- if isFirstField {
- return c.headerOpcodes(ctx, field, valueCodes)
- }
- return c.fieldOpcodes(ctx, field, valueCodes)
-}
-
-func isEnableStructEndOptimization(value Code) bool {
- switch value.Kind() {
- case CodeKindInt,
- CodeKindUint,
- CodeKindFloat,
- CodeKindString,
- CodeKindBool,
- CodeKindBytes:
- return true
- case CodeKindPtr:
- return isEnableStructEndOptimization(value.(*PtrCode).value)
- default:
- return false
- }
-}
-
-type InterfaceCode struct {
- typ *runtime.Type
- fieldQuery *FieldQuery
- isPtr bool
-}
-
-func (c *InterfaceCode) Kind() CodeKind {
- return CodeKindInterface
-}
-
-func (c *InterfaceCode) ToOpcode(ctx *compileContext) Opcodes {
- var code *Opcode
- switch {
- case c.isPtr:
- code = newOpCode(ctx, c.typ, OpInterfacePtr)
- default:
- code = newOpCode(ctx, c.typ, OpInterface)
- }
- code.FieldQuery = c.fieldQuery
- if c.typ.NumMethod() > 0 {
- code.Flags |= NonEmptyInterfaceFlags
- }
- ctx.incIndex()
- return Opcodes{code}
-}
-
-func (c *InterfaceCode) Filter(query *FieldQuery) Code {
- return &InterfaceCode{
- typ: c.typ,
- fieldQuery: query,
- isPtr: c.isPtr,
- }
-}
-
-type MarshalJSONCode struct {
- typ *runtime.Type
- fieldQuery *FieldQuery
- isAddrForMarshaler bool
- isNilableType bool
- isMarshalerContext bool
-}
-
-func (c *MarshalJSONCode) Kind() CodeKind {
- return CodeKindMarshalJSON
-}
-
-func (c *MarshalJSONCode) ToOpcode(ctx *compileContext) Opcodes {
- code := newOpCode(ctx, c.typ, OpMarshalJSON)
- code.FieldQuery = c.fieldQuery
- if c.isAddrForMarshaler {
- code.Flags |= AddrForMarshalerFlags
- }
- if c.isMarshalerContext {
- code.Flags |= MarshalerContextFlags
- }
- if c.isNilableType {
- code.Flags |= IsNilableTypeFlags
- } else {
- code.Flags &= ^IsNilableTypeFlags
- }
- ctx.incIndex()
- return Opcodes{code}
-}
-
-func (c *MarshalJSONCode) Filter(query *FieldQuery) Code {
- return &MarshalJSONCode{
- typ: c.typ,
- fieldQuery: query,
- isAddrForMarshaler: c.isAddrForMarshaler,
- isNilableType: c.isNilableType,
- isMarshalerContext: c.isMarshalerContext,
- }
-}
-
-type MarshalTextCode struct {
- typ *runtime.Type
- fieldQuery *FieldQuery
- isAddrForMarshaler bool
- isNilableType bool
-}
-
-func (c *MarshalTextCode) Kind() CodeKind {
- return CodeKindMarshalText
-}
-
-func (c *MarshalTextCode) ToOpcode(ctx *compileContext) Opcodes {
- code := newOpCode(ctx, c.typ, OpMarshalText)
- code.FieldQuery = c.fieldQuery
- if c.isAddrForMarshaler {
- code.Flags |= AddrForMarshalerFlags
- }
- if c.isNilableType {
- code.Flags |= IsNilableTypeFlags
- } else {
- code.Flags &= ^IsNilableTypeFlags
- }
- ctx.incIndex()
- return Opcodes{code}
-}
-
-func (c *MarshalTextCode) Filter(query *FieldQuery) Code {
- return &MarshalTextCode{
- typ: c.typ,
- fieldQuery: query,
- isAddrForMarshaler: c.isAddrForMarshaler,
- isNilableType: c.isNilableType,
- }
-}
-
-type PtrCode struct {
- typ *runtime.Type
- value Code
- ptrNum uint8
-}
-
-func (c *PtrCode) Kind() CodeKind {
- return CodeKindPtr
-}
-
-func (c *PtrCode) ToOpcode(ctx *compileContext) Opcodes {
- codes := c.value.ToOpcode(ctx)
- codes.First().Op = convertPtrOp(codes.First())
- codes.First().PtrNum = c.ptrNum
- return codes
-}
-
-func (c *PtrCode) ToAnonymousOpcode(ctx *compileContext) Opcodes {
- var codes Opcodes
- anonymCode, ok := c.value.(AnonymousCode)
- if ok {
- codes = anonymCode.ToAnonymousOpcode(ctx)
- } else {
- codes = c.value.ToOpcode(ctx)
- }
- codes.First().Op = convertPtrOp(codes.First())
- codes.First().PtrNum = c.ptrNum
- return codes
-}
-
-func (c *PtrCode) Filter(query *FieldQuery) Code {
- return &PtrCode{
- typ: c.typ,
- value: c.value.Filter(query),
- ptrNum: c.ptrNum,
- }
-}
-
-func convertPtrOp(code *Opcode) OpType {
- ptrHeadOp := code.Op.HeadToPtrHead()
- if code.Op != ptrHeadOp {
- if code.PtrNum > 0 {
- // ptr field and ptr head
- code.PtrNum--
- }
- return ptrHeadOp
- }
- switch code.Op {
- case OpInt:
- return OpIntPtr
- case OpUint:
- return OpUintPtr
- case OpFloat32:
- return OpFloat32Ptr
- case OpFloat64:
- return OpFloat64Ptr
- case OpString:
- return OpStringPtr
- case OpBool:
- return OpBoolPtr
- case OpBytes:
- return OpBytesPtr
- case OpNumber:
- return OpNumberPtr
- case OpArray:
- return OpArrayPtr
- case OpSlice:
- return OpSlicePtr
- case OpMap:
- return OpMapPtr
- case OpMarshalJSON:
- return OpMarshalJSONPtr
- case OpMarshalText:
- return OpMarshalTextPtr
- case OpInterface:
- return OpInterfacePtr
- case OpRecursive:
- return OpRecursivePtr
- }
- return code.Op
-}
-
-func isEmbeddedStruct(field *StructFieldCode) bool {
- if !field.isAnonymous {
- return false
- }
- t := field.typ
- if t.Kind() == reflect.Ptr {
- t = t.Elem()
- }
- return t.Kind() == reflect.Struct
-}