159
genCodecPkg = "codec1978"
161
genTopLevelVarName = "x"
165
genAnythingCanBeNil = true
169
genStructCanonical = true
175
genFastpathCanonical = true
178
genFastpathTrimTypes = true
181
type genStringDecAsBytes string
182
type genStringDecZC string
184
var genStringDecAsBytesTyp = reflect.TypeOf(genStringDecAsBytes(""))
185
var genStringDecZCTyp = reflect.TypeOf(genStringDecZC(""))
186
var genFormats = []string{"Json", "Cbor", "Msgpack", "Binc", "Simple"}
189
errGenAllTypesSamePkg = errors.New("All types must be in the same package")
190
errGenExpectArrayOrMap = errors.New("unexpected type - expecting array/map/slice")
191
errGenUnexpectedTypeFastpath = errors.New("fast-path: unexpected type - requires map or slice")
197
genTypenameEnc = base32.NewEncoding("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef")
198
genQNameRegex = regexp.MustCompile(`[A-Za-z_.]+`)
205
func (x *genBuf) sIf(b bool, s, t string) *genBuf {
207
x.buf = append(x.buf, s...)
209
x.buf = append(x.buf, t...)
213
func (x *genBuf) s(s string) *genBuf { x.buf = append(x.buf, s...); return x }
214
func (x *genBuf) b(s []byte) *genBuf { x.buf = append(x.buf, s...); return x }
215
func (x *genBuf) v() string { return string(x.buf) }
216
func (x *genBuf) f(s string, args ...interface{}) { x.s(fmt.Sprintf(s, args...)) }
217
func (x *genBuf) reset() {
224
type genRunner struct {
237
im map[string]reflect.Type
238
imn map[string]string
241
is map[reflect.Type]struct{}
246
ty map[reflect.Type]struct{}
247
tm map[reflect.Type]struct{}
256
jsonOnlyWhen, toArrayWhen, omitEmptyWhen *bool
261
type genIfClause struct {
265
func (g *genIfClause) end(x *genRunner) {
271
func (g *genIfClause) c(last bool) (v string) {
289
func Gen(w io.Writer, buildTags, pkgName, uid string, noExtensions bool,
290
jsonOnlyWhen, toArrayWhen, omitEmptyWhen *bool,
291
ti *TypeInfos, types ...reflect.Type) (warnings []string) {
302
te: make(map[uintptr]bool),
303
td: make(map[uintptr]bool),
304
tz: make(map[uintptr]bool),
305
im: make(map[string]reflect.Type),
306
imn: make(map[string]string),
307
is: make(map[reflect.Type]struct{}),
308
tm: make(map[reflect.Type]struct{}),
309
ty: make(map[reflect.Type]struct{}),
310
ts: []reflect.Type{},
311
bp: genImportPath(types[0]),
314
jsonOnlyWhen: jsonOnlyWhen,
315
toArrayWhen: toArrayWhen,
316
omitEmptyWhen: omitEmptyWhen,
324
rr := rand.New(rand.NewSource(time.Now().UnixNano()))
325
x.xs = strconv.FormatInt(rr.Int63n(9999), 10)
329
x.cp = genImportPath(reflect.TypeOf(x))
330
x.imn[x.cp] = genCodecPkg
333
for i := 0; i < len(x.t); {
336
if genImportPath(t) != x.bp {
337
halt.onerror(errGenAllTypesSamePkg)
339
ti1 := x.ti.get(rt2id(t), t)
340
if ti1.flagMissingFielder || ti1.flagMissingFielderPtr {
342
warnings = append(warnings, fmt.Sprintf("type: '%v' not generated; implements codec.MissingFielder", t))
343
copy(x.t[i:], x.t[i+1:])
344
x.t = x.t[:len(x.t)-1]
351
x.line("// +build go1.6")
353
x.line("// +build " + buildTags)
357
// Code generated by codecgen - DO NOT EDIT.
360
x.line("package " + pkgName)
364
x.cpfx = genCodecPkg + "."
365
x.linef("%s \"%s\"", genCodecPkg, x.cp)
368
imKeys := make([]string, 0, len(x.im))
369
for k := range x.im {
370
imKeys = append(imKeys, k)
373
for _, k := range imKeys {
377
x.linef("%s \"%s\"", x.imn[k], k)
381
for _, k := range [...]string{"runtime", "errors", "strconv", "sort"} {
382
if _, ok := x.im[k]; !ok {
383
x.line("\"" + k + "\"")
390
x.linef("// ----- content types ----")
391
x.linef("codecSelferCcUTF8%s = %v", x.xs, int64(cUTF8))
392
x.linef("codecSelferCcRAW%s = %v", x.xs, int64(cRAW))
393
x.linef("// ----- value types used ----")
394
for _, vt := range [...]valueType{
395
valueTypeArray, valueTypeMap, valueTypeString,
396
valueTypeInt, valueTypeUint, valueTypeFloat,
399
x.linef("codecSelferValueType%s%s = %v", vt.String(), x.xs, int64(vt))
402
x.linef("codecSelferBitsize%s = uint8(32 << (^uint(0) >> 63))", x.xs)
403
x.linef("codecSelferDecContainerLenNil%s = %d", x.xs, int64(containerLenNil))
406
x.line("errCodecSelferOnlyMapOrArrayEncodeToStruct" + x.xs + " = " + "errors.New(`only encoded map or array can be decoded into a struct`)")
407
x.line("_ sort.Interface = nil")
411
x.hn = "codecSelfer" + x.xs
412
x.line("type " + x.hn + " struct{}")
414
x.linef("func %sFalse() bool { return false }", x.hn)
415
x.linef("func %sTrue() bool { return true }", x.hn)
419
for _, s := range []string{"string", "uint64", "int64", "float64"} {
420
x.linef("type %s%sSlice []%s", x.hn, s, s)
421
x.linef("func (p %s%sSlice) Len() int { return len(p) }", x.hn, s)
422
x.linef("func (p %s%sSlice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] }", x.hn, s)
423
x.linef("func (p %s%sSlice) Less(i, j int) bool { return p[uint(i)] < p[uint(j)] }", x.hn, s)
428
x.line("func init() {")
429
x.linef("if %sGenVersion != %v {", x.cpfx, genVersion)
430
x.line("_, file, _, _ := runtime.Caller(0)")
431
x.linef("ver := strconv.FormatInt(int64(%sGenVersion), 10)", x.cpfx)
432
x.outf(`panic(errors.New("codecgen version mismatch: current: %v, need " + ver + ". Re-generate file: " + file))`, genVersion)
435
x.line("if false { // reference the types, but skip this branch at build/run time")
436
for _, k := range imKeys {
438
x.linef("var _ %s.%s", x.imn[k], t.Name())
446
for _, t := range x.t {
448
x.linef("func (%s) codecSelferViaCodecgen() {}", x.genTypeName(t))
454
for _, t := range x.ts {
458
x.linef("func (x %s) enc%s(v %s%s, e *%sEncoder) {", x.hn, x.genMethodNameT(t), x.arr2str(t, "*"), x.genTypeName(t), x.cpfx)
459
x.genRequiredMethodVars(true)
461
case reflect.Array, reflect.Slice, reflect.Chan:
462
x.encListFallback("v", t)
464
x.encMapFallback("v", t)
466
halt.onerror(errGenExpectArrayOrMap)
473
x.linef("func (x %s) dec%s(v *%s, d *%sDecoder) {", x.hn, x.genMethodNameT(t), x.genTypeName(t), x.cpfx)
474
x.genRequiredMethodVars(false)
476
case reflect.Array, reflect.Slice, reflect.Chan:
477
x.decListFallback("v", rtid, t)
479
x.decMapFallback("v", rtid, t)
481
halt.onerror(errGenExpectArrayOrMap)
487
for t := range x.ty {
496
func (x *genRunner) checkForSelfer(t reflect.Type, varname string) bool {
499
return varname != genTopLevelVarName
502
func (x *genRunner) arr2str(t reflect.Type, s string) string {
503
if t.Kind() == reflect.Array {
509
func (x *genRunner) genRequiredMethodVars(encode bool) {
510
x.line("var h " + x.hn)
512
x.line("z, r := " + x.cpfx + "GenHelper().Encoder(e)")
514
x.line("z, r := " + x.cpfx + "GenHelper().Decoder(d)")
516
x.line("_, _, _ = h, z, r")
519
func (x *genRunner) genRefPkgs(t reflect.Type) {
520
if _, ok := x.is[t]; ok {
524
tpkg, tname := genImportPath(t), t.Name()
525
if tpkg != "" && tpkg != x.bp && tpkg != x.cp && tname != "" && tname[0] >= 'A' && tname[0] <= 'Z' {
526
if _, ok := x.im[tpkg]; !ok {
528
if idx := strings.LastIndex(tpkg, "/"); idx < 0 {
532
x.imn[tpkg] = "pkg" + strconv.FormatUint(x.imc, 10) + "_" + genGoIdentifier(tpkg[idx+1:], false)
537
case reflect.Array, reflect.Slice, reflect.Ptr, reflect.Chan:
538
x.genRefPkgs(t.Elem())
540
x.genRefPkgs(t.Elem())
541
x.genRefPkgs(t.Key())
543
for i := 0; i < t.NumField(); i++ {
544
if fname := t.Field(i).Name; fname != "" && fname[0] >= 'A' && fname[0] <= 'Z' {
545
x.genRefPkgs(t.Field(i).Type)
552
func (x *genRunner) sayFalse() string {
555
return x.hn + "False()"
561
func (x *genRunner) sayTrue() string {
564
return x.hn + "True()"
569
func (x *genRunner) varsfx() string {
571
return strconv.FormatUint(x.c, 10)
574
func (x *genRunner) varsfxreset() {
578
func (x *genRunner) out(s string) {
579
_, err := io.WriteString(x.w, s)
583
func (x *genRunner) outf(s string, params ...interface{}) {
584
_, err := fmt.Fprintf(x.w, s, params...)
588
func (x *genRunner) line(s string) {
590
if len(s) == 0 || s[len(s)-1] != '\n' {
595
func (x *genRunner) lineIf(s string) {
601
func (x *genRunner) linef(s string, params ...interface{}) {
603
if len(s) == 0 || s[len(s)-1] != '\n' {
608
func (x *genRunner) genTypeName(t reflect.Type) (n string) {
615
for t.Kind() == reflect.Ptr {
619
if tn := t.Name(); tn != "" {
620
return ptrPfx + x.genTypeNamePrim(t)
624
return ptrPfx + "map[" + x.genTypeName(t.Key()) + "]" + x.genTypeName(t.Elem())
626
return ptrPfx + "[]" + x.genTypeName(t.Elem())
628
return ptrPfx + "[" + strconv.FormatInt(int64(t.Len()), 10) + "]" + x.genTypeName(t.Elem())
630
return ptrPfx + t.ChanDir().String() + " " + x.genTypeName(t.Elem())
633
return ptrPfx + "interface{}"
635
return ptrPfx + x.genTypeNamePrim(t)
640
func (x *genRunner) genTypeNamePrim(t reflect.Type) (n string) {
643
} else if genImportPath(t) == "" || genImportPath(t) == genImportPath(x.tc) {
646
return x.imn[genImportPath(t)] + "." + t.Name()
651
func (x *genRunner) genZeroValueR(t reflect.Type) string {
654
case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func,
655
reflect.Slice, reflect.Map, reflect.Invalid:
661
case reflect.Struct, reflect.Array:
662
return x.genTypeName(t) + "{}"
663
default: // all numbers
668
func (x *genRunner) genMethodNameT(t reflect.Type) (s string) {
669
return genMethodNameT(t, x.tc)
672
func (x *genRunner) tryGenIsZero(t reflect.Type) (done bool) {
673
if t.Kind() != reflect.Struct || t.Implements(isCodecEmptyerTyp) {
679
if _, ok := x.tz[rtid]; ok {
687
ti := x.ti.get(rtid, t)
688
tisfi := ti.sfi.source() // always use sequence from file. decStruct expects same thing.
689
varname := genTopLevelVarName
691
x.linef("func (%s *%s) IsCodecEmpty() bool {", varname, x.genTypeName(t))
693
anonSeen := make(map[reflect.Type]bool)
695
for _, si := range tisfi {
696
if si.path.parent != nil {
697
root := si.path.root()
698
if anonSeen[root.typ] {
701
anonSeen[root.typ] = true
703
t2 := genOmitEmptyLinePreChecks(varname, t, si, &omitline, true)
704
// if Ptr, we already checked if nil above
705
if t2.Type.Kind() != reflect.Ptr {
706
x.doEncOmitEmptyLine(t2, varname, &omitline)
711
x.linef("return !(%s)", omitline.v())
718
func (x *genRunner) selfer(encode bool) {
720
// ti := x.ti.get(rt2id(t), t)
722
// always make decode use a pointer receiver,
723
// and structs/arrays always use a ptr receiver (encode|decode)
724
isptr := !encode || t.Kind() == reflect.Array || (t.Kind() == reflect.Struct && t != timeTyp)
727
fnSigPfx := "func (" + genTopLevelVarName + " "
731
fnSigPfx += x.genTypeName(t)
738
x.line(") CodecEncodeSelf(e *" + x.cpfx + "Encoder) {")
739
x.genRequiredMethodVars(true)
740
if t0.Kind() == reflect.Struct {
741
x.linef("if z.EncBasicHandle().CheckCircularRef { z.EncEncode(%s); return }", genTopLevelVarName)
743
x.encVar(genTopLevelVarName, t)
745
x.line(") CodecDecodeSelf(d *" + x.cpfx + "Decoder) {")
746
x.genRequiredMethodVars(false)
747
// do not use decVar, as there is no need to check TryDecodeAsNil
748
// or way to elegantly handle that, and also setting it to a
749
// non-nil value doesn't affect the pointer passed.
750
// x.decVar(genTopLevelVarName, t, false)
751
x.dec(genTopLevelVarName, t0, true)
756
if encode || t0.Kind() != reflect.Struct {
760
// write is containerMap
762
x.line(") codecDecodeSelfFromMap(l int, d *" + x.cpfx + "Decoder) {")
763
x.genRequiredMethodVars(false)
764
x.decStructMap(genTopLevelVarName, "l", rt2id(t0), t0)
768
// write containerArray
770
x.line(") codecDecodeSelfFromArray(l int, d *" + x.cpfx + "Decoder) {")
771
x.genRequiredMethodVars(false)
772
x.decStructArray(genTopLevelVarName, "l", "return", rt2id(t0), t0)
778
// used for chan, array, slice, map
779
func (x *genRunner) xtraSM(varname string, t reflect.Type, ti *typeInfo, encode, isptr bool) {
780
var ptrPfx, addrPfx string
787
x.linef("h.enc%s((%s%s)(%s), e)", x.genMethodNameT(t), ptrPfx, x.genTypeName(t), varname)
789
x.linef("h.dec%s((*%s)(%s%s), d)", x.genMethodNameT(t), x.genTypeName(t), addrPfx, varname)
791
x.registerXtraT(t, ti)
794
func (x *genRunner) registerXtraT(t reflect.Type, ti *typeInfo) {
795
// recursively register the types
797
if tk == reflect.Ptr {
798
x.registerXtraT(t.Elem(), nil)
801
if _, ok := x.tm[t]; ok {
806
case reflect.Chan, reflect.Slice, reflect.Array, reflect.Map:
810
// only register the type if it will not default to a fast-path
812
ti = x.ti.get(rt2id(t), t)
814
if _, rtidu := genFastpathUnderlying(t, ti.rtid, ti); fastpathAvIndex(rtidu) != -1 {
818
x.ts = append(x.ts, t)
819
// check if this refers to any xtra types eg. a slice of array: add the array
820
x.registerXtraT(t.Elem(), nil)
821
if tk == reflect.Map {
822
x.registerXtraT(t.Key(), nil)
826
// encVar will encode a variable.
827
// The parameter, t, is the reflect.Type of the variable itself
828
func (x *genRunner) encVar(varname string, t reflect.Type) {
830
// case reflect.Ptr, reflect.Interface, reflect.Slice, reflect.Map, reflect.Chan:
831
// do not include checkNil for slice and maps, as we already checkNil below it
833
case reflect.Ptr, reflect.Interface, reflect.Chan:
836
x.encVarChkNil(varname, t, checkNil)
839
func (x *genRunner) encVarChkNil(varname string, t reflect.Type, checkNil bool) {
841
x.linef("if %s == nil { r.EncodeNil() } else {", varname)
848
if tek == reflect.Array || (tek == reflect.Struct && telem != timeTyp) {
849
x.enc(varname, genNonPtr(t), true)
853
x.line(genTempVarPfx + i + " := *" + varname)
854
x.enc(genTempVarPfx+i, genNonPtr(t), false)
855
case reflect.Struct, reflect.Array:
857
x.enc(varname, t, false)
861
x.line(genTempVarPfx + i + " := &" + varname)
862
x.enc(genTempVarPfx+i, t, true)
864
x.enc(varname, t, false)
872
// enc will encode a variable (varname) of type t, where t represents T.
873
// if t is !time.Time and t is of kind reflect.Struct or reflect.Array, varname is of type *T
874
// (to prevent copying),
875
// else t is of type T
876
func (x *genRunner) enc(varname string, t reflect.Type, isptr bool) {
878
ti2 := x.ti.get(rtid, t)
879
// We call CodecEncodeSelf if one of the following are honored:
880
// - the type already implements Selfer, call that
881
// - the type has a Selfer implementation just created, use that
882
// - the type is in the list of the ones we will generate for, but it is not currently being generated
885
// tptr := reflect.PtrTo(t)
889
// - type is time.Time, RawExt, Raw
890
// - the type implements (Text|JSON|Binary)(Unm|M)arshal
892
var hasIf genIfClause
893
defer hasIf.end(x) // end if block (if necessary)
895
var ptrPfx, addrPfx string
903
x.linef("%s z.EncBasicHandle().TimeBuiltin() { r.EncodeTime(%s%s)", hasIf.c(false), ptrPfx, varname)
907
x.linef("%s z.EncRaw(%s%s)", hasIf.c(true), ptrPfx, varname)
911
x.linef("%s r.EncodeRawExt(%s%s)", hasIf.c(true), addrPfx, varname)
914
// only check for extensions if extensions are configured,
915
// and the type is named, and has a packagePath,
916
// and this is not the CodecEncodeSelf or CodecDecodeSelf method (i.e. it is not a Selfer)
917
if !x.nx && varname != genTopLevelVarName && t != genStringDecAsBytesTyp &&
918
t != genStringDecZCTyp && genImportPath(t) != "" && t.Name() != "" {
919
yy := fmt.Sprintf("%sxt%s", genTempVarPfx, mi)
920
x.linef("%s %s := z.Extension(%s); %s != nil { z.EncExtension(%s, %s) ",
921
hasIf.c(false), yy, varname, yy, varname, yy)
924
if x.checkForSelfer(t, varname) {
926
x.linef("%s %s.CodecEncodeSelf(e)", hasIf.c(true), varname)
929
if ti2.flagSelferPtr {
931
x.linef("%s %s.CodecEncodeSelf(e)", hasIf.c(true), varname)
933
x.linef("%s %ssf%s := &%s", hasIf.c(true), genTempVarPfx, mi, varname)
934
x.linef("%ssf%s.CodecEncodeSelf(e)", genTempVarPfx, mi)
939
if _, ok := x.te[rtid]; ok {
940
x.linef("%s %s.CodecEncodeSelf(e)", hasIf.c(true), varname)
946
for _, t0 := range x.t {
949
if x.checkForSelfer(t, varname) {
950
x.linef("%s %s.CodecEncodeSelf(e)", hasIf.c(true), varname)
963
if ti2.flagBinaryMarshaler {
964
x.linef("%s z.EncBinary() { z.EncBinaryMarshal(%s%v) ", hasIf.c(false), ptrPfx, varname)
965
} else if ti2.flagBinaryMarshalerPtr {
966
x.linef("%s z.EncBinary() { z.EncBinaryMarshal(%s%v) ", hasIf.c(false), addrPfx, varname)
969
if ti2.flagJsonMarshaler {
970
x.linef("%s !z.EncBinary() && z.IsJSONHandle() { z.EncJSONMarshal(%s%v) ", hasIf.c(false), ptrPfx, varname)
971
} else if ti2.flagJsonMarshalerPtr {
972
x.linef("%s !z.EncBinary() && z.IsJSONHandle() { z.EncJSONMarshal(%s%v) ", hasIf.c(false), addrPfx, varname)
973
} else if ti2.flagTextMarshaler {
974
x.linef("%s !z.EncBinary() { z.EncTextMarshal(%s%v) ", hasIf.c(false), ptrPfx, varname)
975
} else if ti2.flagTextMarshalerPtr {
976
x.linef("%s !z.EncBinary() { z.EncTextMarshal(%s%v) ", hasIf.c(false), addrPfx, varname)
979
x.lineIf(hasIf.c(true))
982
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
983
x.line("r.EncodeInt(int64(" + varname + "))")
984
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
985
x.line("r.EncodeUint(uint64(" + varname + "))")
986
case reflect.Float32:
987
x.line("r.EncodeFloat32(float32(" + varname + "))")
988
case reflect.Float64:
989
x.line("r.EncodeFloat64(float64(" + varname + "))")
990
case reflect.Complex64:
991
x.linef("z.EncEncodeComplex64(complex64(%s))", varname)
992
case reflect.Complex128:
993
x.linef("z.EncEncodeComplex128(complex128(%s))", varname)
995
x.line("r.EncodeBool(bool(" + varname + "))")
997
x.linef("r.EncodeString(string(%s))", varname)
999
x.xtraSM(varname, t, ti2, true, false)
1000
// x.encListFallback(varname, rtid, t)
1002
_, rtidu := genFastpathUnderlying(t, rtid, ti2)
1003
if fastpathAvIndex(rtidu) != -1 {
1004
g := x.newFastpathGenV(ti2.key)
1005
x.linef("z.F.%sV((%s)(%s[:]), e)", g.MethodNamePfx("Enc", false), x.genTypeName(ti2.key), varname)
1007
x.xtraSM(varname, t, ti2, true, true)
1010
// if nil, call dedicated function
1011
// if a []byte, call dedicated function
1012
// if a known fastpath slice, call dedicated function
1013
// else write encode function in-line.
1014
// - if elements are primitives or Selfers, call dedicated function on each member.
1015
// - else call Encoder.encode(XXX) on it.
1017
x.linef("if %s == nil { r.EncodeNil() } else {", varname)
1018
if rtid == uint8SliceTypId {
1019
x.line("r.EncodeStringBytesRaw([]byte(" + varname + "))")
1021
tu, rtidu := genFastpathUnderlying(t, rtid, ti2)
1022
if fastpathAvIndex(rtidu) != -1 {
1023
g := x.newFastpathGenV(tu)
1025
x.linef("z.F.%sV(%s, e)", g.MethodNamePfx("Enc", false), varname)
1027
x.linef("z.F.%sV((%s)(%s), e)", g.MethodNamePfx("Enc", false), x.genTypeName(tu), varname)
1030
x.xtraSM(varname, t, ti2, true, false)
1033
x.linef("} // end block: if %s slice == nil", varname)
1035
// if nil, call dedicated function
1036
// if a known fastpath map, call dedicated function
1037
// else write encode function in-line.
1038
// - if elements are primitives or Selfers, call dedicated function on each member.
1039
// - else call Encoder.encode(XXX) on it.
1040
x.linef("if %s == nil { r.EncodeNil() } else {", varname)
1041
tu, rtidu := genFastpathUnderlying(t, rtid, ti2)
1042
if fastpathAvIndex(rtidu) != -1 {
1043
g := x.newFastpathGenV(tu)
1045
x.linef("z.F.%sV(%s, e)", g.MethodNamePfx("Enc", false), varname)
1047
x.linef("z.F.%sV((%s)(%s), e)", g.MethodNamePfx("Enc", false), x.genTypeName(tu), varname)
1050
x.xtraSM(varname, t, ti2, true, false)
1052
x.linef("} // end block: if %s map == nil", varname)
1053
case reflect.Struct:
1056
x.line("z.EncFallback(" + varname + ")")
1059
x.encStruct(varname, rtid, t)
1064
x.line("z.EncFallback(" + varname + ")")
1068
func (x *genRunner) encZero(t reflect.Type) {
1070
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1071
x.line("r.EncodeInt(0)")
1072
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
1073
x.line("r.EncodeUint(0)")
1074
case reflect.Float32:
1075
x.line("r.EncodeFloat32(0)")
1076
case reflect.Float64:
1077
x.line("r.EncodeFloat64(0)")
1078
case reflect.Complex64:
1079
x.line("z.EncEncodeComplex64(0)")
1080
case reflect.Complex128:
1081
x.line("z.EncEncodeComplex128(0)")
1083
x.line("r.EncodeBool(false)")
1084
case reflect.String:
1085
x.linef(`r.EncodeString("")`)
1087
x.line("r.EncodeNil()")
1091
func genOmitEmptyLinePreChecks(varname string, t reflect.Type, si *structFieldInfo, omitline *genBuf, oneLevel bool) (t2 reflect.StructField) {
1092
// xdebug2f("calling genOmitEmptyLinePreChecks on: %v", t)
1095
// go through the loop, record the t2 field explicitly,
1096
// and gather the omit line if embedded in pointers.
1097
fullpath := si.path.fullpath()
1098
for i, path := range fullpath {
1099
for t2typ.Kind() == reflect.Ptr {
1100
t2typ = t2typ.Elem()
1102
t2 = t2typ.Field(int(path.index))
1104
varname3 = varname3 + "." + t2.Name
1105
// do not include actual field in the omit line.
1106
// that is done subsequently (right after - below).
1107
if i+1 < len(fullpath) && t2typ.Kind() == reflect.Ptr {
1108
omitline.s(varname3).s(" != nil && ")
1117
func (x *genRunner) doEncOmitEmptyLine(t2 reflect.StructField, varname string, buf *genBuf) {
1119
x.encOmitEmptyLine(t2, varname, buf)
1122
func (x *genRunner) encOmitEmptyLine(t2 reflect.StructField, varname string, buf *genBuf) {
1123
// xdebugf("calling encOmitEmptyLine on: %v", t2.Type)
1124
// smartly check omitEmpty on a struct type, as it may contain uncomparable map/slice/etc.
1125
// also, for maps/slices, check if len ! 0 (not if == zero value)
1126
varname2 := varname + "." + t2.Name
1127
switch t2.Type.Kind() {
1128
case reflect.Struct:
1129
rtid2 := rt2id(t2.Type)
1130
ti2 := x.ti.get(rtid2, t2.Type)
1131
// xdebugf(">>>> structfield: omitempty: type: %s, field: %s\n", t2.Type.Name(), t2.Name)
1132
if ti2.rtid == timeTypId {
1133
buf.s("!(").s(varname2).s(".IsZero())")
1136
if ti2.flagIsZeroerPtr || ti2.flagIsZeroer {
1137
buf.s("!(").s(varname2).s(".IsZero())")
1140
if t2.Type.Implements(isCodecEmptyerTyp) {
1141
buf.s("!(").s(varname2).s(".IsCodecEmpty())")
1144
_, ok := x.tz[rtid2]
1146
buf.s("!(").s(varname2).s(".IsCodecEmpty())")
1149
// if we *should* create a IsCodecEmpty for it, but haven't yet, add it here
1150
// _, ok = x.ty[rtid2]
1151
if genImportPath(t2.Type) == x.bp {
1152
x.ty[t2.Type] = struct{}{}
1153
buf.s("!(").s(varname2).s(".IsCodecEmpty())")
1156
if ti2.flagComparable {
1157
buf.s(varname2).s(" != ").s(x.genZeroValueR(t2.Type))
1161
buf.s(x.sayFalse()) // buf.s("false")
1163
for i, n := 0, t2.Type.NumField(); i < n; i++ {
1164
f := t2.Type.Field(i)
1165
if f.PkgPath != "" { // unexported
1169
x.encOmitEmptyLine(f, varname2, buf)
1173
buf.s(" || ").s(x.sayTrue())
1177
buf.s("bool(").s(varname2).s(")")
1178
case reflect.Map, reflect.Slice, reflect.Chan:
1179
buf.s("len(").s(varname2).s(") != 0")
1181
tlen := t2.Type.Len()
1184
} else if t2.Type.Comparable() {
1185
buf.s(varname2).s(" != ").s(x.genZeroValueR(t2.Type))
1186
} else { // then we cannot even compare the individual values
1187
// TODO use playground to check if you can compare to a
1188
// zero value of an array, even if array not comparable.
1192
buf.s(varname2).s(" != ").s(x.genZeroValueR(t2.Type))
1196
func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) {
1197
// Use knowledge from structfieldinfo (mbs, encodable fields. Ignore omitempty. )
1198
// replicate code in kStruct i.e. for each field, deref type to non-pointer, and call x.enc on it
1200
// if t === type currently running selfer on, do for all
1201
ti := x.ti.get(rtid, t)
1203
// sepVarname := genTempVarPfx + "sep" + i
1204
numfieldsvar := genTempVarPfx + "q" + i
1205
ti2arrayvar := genTempVarPfx + "r" + i
1206
struct2arrvar := genTempVarPfx + "2arr" + i
1208
tisfi := ti.sfi.source() // always use sequence from file. decStruct expects same thing.
1210
type genFQN struct {
1216
sf reflect.StructField
1219
genFQNs := make([]genFQN, len(tisfi))
1220
si2Pos := make(map[*structFieldInfo]int) // stores position in sorted structFieldInfos
1222
for j, si := range tisfi {
1226
q.nilVar = genTempVarPfx + "n" + q.i
1231
fullpath := si.path.fullpath()
1232
for _, path := range fullpath {
1233
for t2typ.Kind() == reflect.Ptr {
1234
t2typ = t2typ.Elem()
1236
q.sf = t2typ.Field(int(path.index))
1238
q.fqname += "." + q.sf.Name
1239
if t2typ.Kind() == reflect.Ptr {
1241
q.nilLine.f("%s == nil", q.fqname)
1244
q.nilLine.f(" || %s == nil", q.fqname)
1251
// x.line(sepVarname + " := !z.EncBinary()")
1252
x.linef("%s := z.EncBasicHandle().StructToArray", struct2arrvar)
1253
// x.linef("_, _ = %s, %s", sepVarname, struct2arrvar)
1254
x.linef("_ = %s", struct2arrvar)
1255
x.linef("const %s bool = %v // struct tag has 'toArray'", ti2arrayvar, ti.toArray)
1257
for j := range genFQNs {
1260
x.linef("var %s bool = %s", q.nilVar, q.nilLine.v())
1265
// due to omitEmpty, we need to calculate the
1266
// number of non-empty things we write out first.
1267
// This is required as we need to pre-determine the size of the container,
1268
// to support length-prefixing.
1269
omitEmptySometimes := x.omitEmptyWhen == nil
1270
omitEmptyAlways := (x.omitEmptyWhen != nil && *(x.omitEmptyWhen))
1271
// omitEmptyNever := (x.omitEmptyWhen != nil && !*(x.omitEmptyWhen))
1273
toArraySometimes := x.toArrayWhen == nil
1274
toArrayAlways := (x.toArrayWhen != nil && *(x.toArrayWhen))
1275
toArrayNever := (x.toArrayWhen != nil && !(*(x.toArrayWhen)))
1277
if (omitEmptySometimes && ti.anyOmitEmpty) || omitEmptyAlways {
1278
x.linef("var %s = [%v]bool{ // should field at this index be written?", numfieldsvar, len(tisfi))
1280
for _, si := range tisfi {
1281
if omitEmptySometimes && !si.path.omitEmpty {
1282
x.linef("true, // %s", si.encName) // si.fieldName)
1286
t2 := genOmitEmptyLinePreChecks(varname, t, si, &omitline, false)
1287
x.doEncOmitEmptyLine(t2, varname, &omitline)
1288
x.linef("%s, // %s", omitline.v(), si.encName) // si.fieldName)
1291
x.linef("_ = %s", numfieldsvar)
1294
if toArraySometimes {
1295
x.linef("if %s || %s {", ti2arrayvar, struct2arrvar) // if ti.toArray
1297
if toArraySometimes || toArrayAlways {
1298
x.linef("z.EncWriteArrayStart(%d)", len(tisfi))
1300
for j, si := range tisfi {
1301
doOmitEmptyCheck := (omitEmptySometimes && si.path.omitEmpty) || omitEmptyAlways
1303
// if the type of the field is a Selfer, or one of the ones
1305
x.linef("if %s { z.EncWriteArrayElem(); r.EncodeNil() } else { ", q.nilVar)
1307
x.linef("z.EncWriteArrayElem()")
1308
if doOmitEmptyCheck {
1309
x.linef("if %s[%v] {", numfieldsvar, j)
1311
x.encVarChkNil(q.fqname, q.sf.Type, false)
1312
if doOmitEmptyCheck {
1314
x.encZero(q.sf.Type)
1322
x.line("z.EncWriteArrayEnd()")
1324
if toArraySometimes {
1325
x.linef("} else {") // if not ti.toArray
1327
if toArraySometimes || toArrayNever {
1328
if (omitEmptySometimes && ti.anyOmitEmpty) || omitEmptyAlways {
1329
x.linef("var %snn%s int", genTempVarPfx, i)
1330
x.linef("for _, b := range %s { if b { %snn%s++ } }", numfieldsvar, genTempVarPfx, i)
1331
x.linef("z.EncWriteMapStart(%snn%s)", genTempVarPfx, i)
1332
x.linef("%snn%s = %v", genTempVarPfx, i, 0)
1334
x.linef("z.EncWriteMapStart(%d)", len(tisfi))
1337
fn := func(tisfi []*structFieldInfo) {
1338
// tisfi here may be source or sorted, so use the src position stored elsewhere
1339
for _, si := range tisfi {
1342
doOmitEmptyCheck := (omitEmptySometimes && si.path.omitEmpty) || omitEmptyAlways
1343
if doOmitEmptyCheck {
1344
x.linef("if %s[%v] {", numfieldsvar, pos)
1346
x.linef("z.EncWriteMapElemKey()")
1348
// emulate EncStructFieldKey
1351
x.linef("r.EncodeInt(z.M.Int(strconv.ParseInt(`%s`, 10, 64)))", si.encName)
1353
x.linef("r.EncodeUint(z.M.Uint(strconv.ParseUint(`%s`, 10, 64)))", si.encName)
1354
case valueTypeFloat:
1355
x.linef("r.EncodeFloat64(z.M.Float(strconv.ParseFloat(`%s`, 64)))", si.encName)
1357
if x.jsonOnlyWhen == nil {
1358
if si.path.encNameAsciiAlphaNum {
1359
x.linef(`if z.IsJSONHandle() { z.EncWr().WriteStr("\"%s\"") } else { `, si.encName)
1361
x.linef("r.EncodeString(`%s`)", si.encName)
1362
if si.path.encNameAsciiAlphaNum {
1365
} else if *(x.jsonOnlyWhen) {
1366
if si.path.encNameAsciiAlphaNum {
1367
x.linef(`z.EncWr().WriteStr("\"%s\"")`, si.encName)
1369
x.linef("r.EncodeString(`%s`)", si.encName)
1372
x.linef("r.EncodeString(`%s`)", si.encName)
1375
x.line("z.EncWriteMapElemValue()")
1377
x.line("if " + q.nilVar + " { r.EncodeNil() } else { ")
1378
x.encVarChkNil(q.fqname, q.sf.Type, false)
1381
x.encVarChkNil(q.fqname, q.sf.Type, false)
1383
if doOmitEmptyCheck {
1389
if genStructCanonical {
1390
x.linef("if z.EncBasicHandle().Canonical {") // if Canonical block
1392
x.linef("} else {") // else !Canonical block
1394
x.linef("}") // end if Canonical block
1399
x.line("z.EncWriteMapEnd()")
1401
if toArraySometimes {
1402
x.linef("} ") // end if/else ti.toArray
1406
func (x *genRunner) encListFallback(varname string, t reflect.Type) {
1407
x.linef("if %s == nil { r.EncodeNil(); return }", varname)
1408
elemBytes := t.Elem().Kind() == reflect.Uint8
1409
if t.AssignableTo(uint8SliceTyp) {
1410
x.linef("r.EncodeStringBytesRaw([]byte(%s))", varname)
1413
if t.Kind() == reflect.Array && elemBytes {
1414
x.linef("r.EncodeStringBytesRaw(((*[%d]byte)(%s))[:])", t.Len(), varname)
1418
if t.Kind() == reflect.Chan {
1420
Label, Chan, Slice, Sfx string
1422
tm, err := template.New("").Parse(genEncChanTmpl)
1424
x.linef("if %s == nil { r.EncodeNil() } else { ", varname)
1425
x.linef("var sch%s []%s", i, x.genTypeName(t.Elem()))
1426
err = tm.Execute(x.w, &ts{"Lsch" + i, varname, "sch" + i, i})
1429
x.linef("r.EncodeStringBytesRaw([]byte(%s))", "sch"+i)
1436
x.line("z.EncWriteArrayStart(len(" + varname + "))")
1438
// x.linef("for _, %sv%s := range %s {", genTempVarPfx, i, varname)
1439
// x.linef("z.EncWriteArrayElem()")
1440
// x.encVar(genTempVarPfx+"v"+i, t.Elem())
1443
x.linef("for %sv%s := range %s {", genTempVarPfx, i, varname)
1444
x.linef("z.EncWriteArrayElem()")
1445
x.encVar(fmt.Sprintf("%s[%sv%s]", varname, genTempVarPfx, i), t.Elem())
1448
x.line("z.EncWriteArrayEnd()")
1449
if t.Kind() == reflect.Chan {
1454
func (x *genRunner) encMapFallback(varname string, t reflect.Type) {
1455
x.linef("if %s == nil { r.EncodeNil()", varname)
1456
x.line("} else if z.EncBasicHandle().Canonical {")
1458
// Solve for easy case accomodated by sort package without reflection i.e.
1459
// map keys of type: float, int, string (pre-defined/builtin types).
1461
// To do this, we will get the keys into an array of uint64|float64|string,
1462
// sort them, then write them out, and grab the value and encode it appropriately
1464
tkind := tkey.Kind()
1466
// for tkeybase.Kind() == reflect.Ptr {
1467
// tkeybase = tkeybase.Elem()
1469
// tikey := x.ti.get(rt2id(tkeybase), tkeybase)
1471
// pre-defined types have a name and no pkgpath and appropriate kind
1472
predeclared := tkey.PkgPath() == "" && tkey.Name() != ""
1474
canonSortKind := reflect.Invalid
1476
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1477
canonSortKind = reflect.Int64
1478
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
1479
canonSortKind = reflect.Uint64
1480
case reflect.Float32, reflect.Float64:
1481
canonSortKind = reflect.Float64
1482
case reflect.String:
1483
canonSortKind = reflect.String
1486
var i string = x.varsfx()
1488
fnCanonNumBoolStrKind := func() {
1490
x.linef("var %svv%s %s", genTempVarPfx, i, x.genTypeName(tkey))
1491
x.linef("%sencfn%s := z.EncFnGivenAddr(&%svv%s)", genTempVarPfx, i, genTempVarPfx, i)
1493
// get the type, get the slice type its mapped to, and complete the code
1494
x.linef("%ss%s := make([]%s, 0, len(%s))", genTempVarPfx, i, canonSortKind, varname)
1495
x.linef("for k, _ := range %s {", varname)
1496
x.linef(" %ss%s = append(%ss%s, %s(k))", genTempVarPfx, i, genTempVarPfx, i, canonSortKind)
1498
x.linef("sort.Sort(%s%sSlice(%ss%s))", x.hn, canonSortKind, genTempVarPfx, i)
1499
x.linef("z.EncWriteMapStart(len(%s))", varname)
1500
x.linef("for _, %sv%s := range %ss%s {", genTempVarPfx, i, genTempVarPfx, i)
1501
x.linef(" z.EncWriteMapElemKey()")
1504
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32:
1505
x.linef("r.EncodeInt(int64(%sv%s))", genTempVarPfx, i)
1507
x.linef("r.EncodeInt(%sv%s)", genTempVarPfx, i)
1508
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uintptr:
1509
x.linef("r.EncodeUint(%sv%s)", genTempVarPfx, i)
1510
case reflect.Uint64:
1511
x.linef("r.EncodeUint(uint64(%sv%s))", genTempVarPfx, i)
1512
case reflect.Float32:
1513
x.linef("r.EncodeFloat32(float32(%sv%s))", genTempVarPfx, i)
1514
case reflect.Float64:
1515
x.linef("r.EncodeFloat64(%sv%s)", genTempVarPfx, i)
1516
case reflect.String:
1517
x.linef("r.EncodeString(%sv%s)", genTempVarPfx, i)
1520
x.linef("%svv%s = %s(%sv%s)", genTempVarPfx, i, x.genTypeName(tkey), genTempVarPfx, i)
1521
x.linef("z.EncEncodeNumBoolStrKindGivenAddr(&%svv%s, %sencfn%s)", genTempVarPfx, i, genTempVarPfx, i)
1523
x.linef(" z.EncWriteMapElemValue()")
1524
vname := genTempVarPfx + "e" + i
1526
x.linef("%s := %s[%s(%sv%s)]", vname, varname, x.genTypeName(tkey), genTempVarPfx, i)
1528
x.linef("%s := %s[%svv%s]", vname, varname, genTempVarPfx, i)
1530
x.encVar(vname, t.Elem())
1533
x.line("z.EncWriteMapEnd()")
1537
// if canonSortKind != reflect.Invalid && !tikey.flagMarshalInterface {
1539
// fnCanonNumBoolStrKind()
1541
// // handle if an extension
1542
// x.linef("if z.Extension(%s(%s)) != nil { z.EncEncodeMapNonNil(%s) } else {",
1543
// x.genTypeName(tkey), x.genZeroValueR(tkey), varname)
1544
// fnCanonNumBoolStrKind()
1548
// x.linef("z.EncEncodeMapNonNil(%s)", varname)
1551
if canonSortKind != reflect.Invalid {
1552
fnCanonNumBoolStrKind()
1554
x.linef("z.EncEncodeMapNonNil(%s)", varname)
1559
x.linef("z.EncWriteMapStart(len(%s))", varname)
1560
x.linef("for %sk%s, %sv%s := range %s {", genTempVarPfx, i, genTempVarPfx, i, varname)
1561
x.linef("z.EncWriteMapElemKey()")
1562
x.encVar(genTempVarPfx+"k"+i, t.Key())
1563
x.line("z.EncWriteMapElemValue()")
1564
x.encVar(genTempVarPfx+"v"+i, t.Elem())
1566
x.line("z.EncWriteMapEnd()")
1571
func (x *genRunner) decVarInitPtr(varname, nilvar string, t reflect.Type, si *structFieldInfo,
1572
newbuf, nilbuf *genBuf) (varname3 string, t2 reflect.StructField) {
1573
//we must accommodate anonymous fields, where the embedded field is a nil pointer in the value.
1574
// t2 = t.FieldByIndex(si.is)
1577
t2kind := t2typ.Kind()
1580
fullpath := si.path.fullpath()
1581
for _, path := range fullpath {
1582
// only one-level pointers can be seen in a type
1583
if t2typ.Kind() == reflect.Ptr {
1584
t2typ = t2typ.Elem()
1586
t2 = t2typ.Field(int(path.index))
1588
varname3 = varname3 + "." + t2.Name
1589
t2kind = t2typ.Kind()
1590
if t2kind != reflect.Ptr {
1594
if len(newbuf.buf) > 0 {
1597
newbuf.f("if %s == nil { %s = new(%s) }", varname3, varname3, x.genTypeName(t2typ.Elem()))
1601
nilbuf.s("if ").s(varname3).s(" != nil")
1604
nilbuf.s(" && ").s(varname3).s(" != nil")
1611
nilbuf.s(" { ").s("// remove the if-true\n")
1614
nilbuf.s(nilvar).s(" = true")
1615
} else if tk := t2typ.Kind(); tk == reflect.Ptr {
1616
if strings.IndexByte(varname3, '.') != -1 || strings.IndexByte(varname3, '[') != -1 {
1617
nilbuf.s(varname3).s(" = nil")
1619
nilbuf.s("*").s(varname3).s(" = ").s(x.genZeroValueR(t2typ.Elem()))
1622
nilbuf.s(varname3).s(" = ").s(x.genZeroValueR(t2typ))
1631
// decVar takes a variable called varname, of type t
1632
func (x *genRunner) decVarMain(varname, rand string, t reflect.Type, checkNotNil bool) {
1633
// We only encode as nil if a nillable value.
1634
// This removes some of the wasted checks for TryDecodeAsNil.
1635
// We need to think about this more, to see what happens if omitempty, etc
1636
// cause a nil value to be stored when something is expected.
1637
// This could happen when decoding from a struct encoded as an array.
1638
// For that, decVar should be called with canNil=true, to force true as its value.
1640
if t.Kind() != reflect.Ptr {
1641
if t.PkgPath() != "" || !x.decTryAssignPrimitive(varname, t, false) {
1642
x.dec(varname, t, false)
1646
x.linef("if %s == nil { %s = new(%s) }", varname, varname, x.genTypeName(t.Elem()))
1648
// Ensure we set underlying ptr to a non-nil value (so we can deref to it later).
1649
// There's a chance of a **T in here which is nil.
1651
for t = t.Elem(); t.Kind() == reflect.Ptr; t = t.Elem() {
1654
x.linef("if %s%s == nil { %s%s = new(%s)}", ptrPfx, varname, ptrPfx, varname, x.genTypeName(t))
1657
// Should we create temp var if a slice/map indexing? No. dec(...) can now handle it.
1660
x.dec(varname, t, true)
1662
varname2 = genTempVarPfx + "z" + rand
1663
x.line(varname2 + " := " + ptrPfx + varname)
1664
x.dec(varname2, t, true)
1669
// decVar takes a variable called varname, of type t
1670
func (x *genRunner) decVar(varname, nilvar string, t reflect.Type, canBeNil, checkNotNil bool) {
1672
// We only encode as nil if a nillable value.
1673
// This removes some of the wasted checks for TryDecodeAsNil.
1674
// We need to think about this more, to see what happens if omitempty, etc
1675
// cause a nil value to be stored when something is expected.
1676
// This could happen when decoding from a struct encoded as an array.
1677
// For that, decVar should be called with canNil=true, to force true as its value.
1680
if t.Kind() == reflect.Ptr {
1682
x.decVarInitPtr(varname, nilvar, t, nil, nil, &buf)
1683
x.linef("if r.TryNil() { %s } else {", buf.buf)
1684
x.decVarMain(varname, i, t, checkNotNil)
1687
x.decVarMain(varname, i, t, checkNotNil)
1691
// dec will decode a variable (varname) of type t or ptrTo(t) if isptr==true.
1692
func (x *genRunner) dec(varname string, t reflect.Type, isptr bool) {
1694
// - the varname is to a pointer already. No need to take address of it
1695
// - t is always a baseType T (not a *T, etc).
1697
ti2 := x.ti.get(rtid, t)
1700
// - type is time.Time, Raw, RawExt
1701
// - the type implements (Text|JSON|Binary)(Unm|M)arshal
1705
var hasIf genIfClause
1708
var ptrPfx, addrPfx string
1715
x.linef("%s z.DecBasicHandle().TimeBuiltin() { %s%v = r.DecodeTime()", hasIf.c(false), ptrPfx, varname)
1719
x.linef("%s %s%v = z.DecRaw()", hasIf.c(true), ptrPfx, varname)
1724
x.linef("%s r.DecodeExt(%s%v, 0, nil)", hasIf.c(true), addrPfx, varname)
1728
// only check for extensions if extensions are configured,
1729
// and the type is named, and has a packagePath,
1730
// and this is not the CodecEncodeSelf or CodecDecodeSelf method (i.e. it is not a Selfer)
1731
// xdebugf("genRunner.dec: varname: %v, t: %v, genImportPath: %v, t.Name: %v", varname, t, genImportPath(t), t.Name())
1732
if !x.nx && varname != genTopLevelVarName && t != genStringDecAsBytesTyp &&
1733
t != genStringDecZCTyp && genImportPath(t) != "" && t.Name() != "" {
1734
// first check if extensions are configued, before doing the interface conversion
1735
yy := fmt.Sprintf("%sxt%s", genTempVarPfx, mi)
1736
x.linef("%s %s := z.Extension(%s); %s != nil { z.DecExtension(%s%s, %s) ", hasIf.c(false), yy, varname, yy, addrPfx, varname, yy)
1739
if x.checkForSelfer(t, varname) {
1741
x.linef("%s %s.CodecDecodeSelf(d)", hasIf.c(true), varname)
1744
if ti2.flagSelferPtr {
1745
x.linef("%s %s.CodecDecodeSelf(d)", hasIf.c(true), varname)
1748
if _, ok := x.td[rtid]; ok {
1749
x.linef("%s %s.CodecDecodeSelf(d)", hasIf.c(true), varname)
1755
for _, t0 := range x.t {
1758
if x.checkForSelfer(t, varname) {
1759
x.linef("%s %s.CodecDecodeSelf(d)", hasIf.c(true), varname)
1772
if ti2.flagBinaryUnmarshaler {
1773
x.linef("%s z.DecBinary() { z.DecBinaryUnmarshal(%s%v) ", hasIf.c(false), ptrPfx, varname)
1774
} else if ti2.flagBinaryUnmarshalerPtr {
1775
x.linef("%s z.DecBinary() { z.DecBinaryUnmarshal(%s%v) ", hasIf.c(false), addrPfx, varname)
1777
if ti2.flagJsonUnmarshaler {
1778
x.linef("%s !z.DecBinary() && z.IsJSONHandle() { z.DecJSONUnmarshal(%s%v)", hasIf.c(false), ptrPfx, varname)
1779
} else if ti2.flagJsonUnmarshalerPtr {
1780
x.linef("%s !z.DecBinary() && z.IsJSONHandle() { z.DecJSONUnmarshal(%s%v)", hasIf.c(false), addrPfx, varname)
1781
} else if ti2.flagTextUnmarshaler {
1782
x.linef("%s !z.DecBinary() { z.DecTextUnmarshal(%s%v)", hasIf.c(false), ptrPfx, varname)
1783
} else if ti2.flagTextUnmarshalerPtr {
1784
x.linef("%s !z.DecBinary() { z.DecTextUnmarshal(%s%v)", hasIf.c(false), addrPfx, varname)
1787
x.lineIf(hasIf.c(true))
1789
if x.decTryAssignPrimitive(varname, t, isptr) {
1795
x.xtraSM(varname, t, ti2, false, isptr)
1797
_, rtidu := genFastpathUnderlying(t, rtid, ti2)
1798
if fastpathAvIndex(rtidu) != -1 {
1799
g := x.newFastpathGenV(ti2.key)
1800
x.linef("z.F.%sN((%s)(%s[:]), d)", g.MethodNamePfx("Dec", false), x.genTypeName(ti2.key), varname)
1802
x.xtraSM(varname, t, ti2, false, isptr)
1805
// if a []byte, call dedicated function
1806
// if a known fastpath slice, call dedicated function
1807
// else write encode function in-line.
1808
// - if elements are primitives or Selfers, call dedicated function on each member.
1809
// - else call Encoder.encode(XXX) on it.
1811
if rtid == uint8SliceTypId {
1812
x.linef("%s%s = z.DecodeBytesInto(%s(%s[]byte)(%s))", ptrPfx, varname, ptrPfx, ptrPfx, varname)
1814
tu, rtidu := genFastpathUnderlying(t, rtid, ti2)
1815
if fastpathAvIndex(rtidu) != -1 {
1816
g := x.newFastpathGenV(tu)
1818
x.linef("z.F.%sX(%s%s, d)", g.MethodNamePfx("Dec", false), addrPfx, varname)
1820
x.linef("z.F.%sX((*%s)(%s%s), d)", g.MethodNamePfx("Dec", false), x.genTypeName(tu), addrPfx, varname)
1823
x.xtraSM(varname, t, ti2, false, isptr)
1824
// x.decListFallback(varname, rtid, false, t)
1828
// if a known fastpath map, call dedicated function
1829
// else write encode function in-line.
1830
// - if elements are primitives or Selfers, call dedicated function on each member.
1831
// - else call Encoder.encode(XXX) on it.
1833
tu, rtidu := genFastpathUnderlying(t, rtid, ti2)
1834
if fastpathAvIndex(rtidu) != -1 {
1835
g := x.newFastpathGenV(tu)
1837
x.linef("z.F.%sX(%s%s, d)", g.MethodNamePfx("Dec", false), addrPfx, varname)
1839
x.linef("z.F.%sX((*%s)(%s%s), d)", g.MethodNamePfx("Dec", false), x.genTypeName(tu), addrPfx, varname)
1842
x.xtraSM(varname, t, ti2, false, isptr)
1844
case reflect.Struct:
1846
// no need to create temp variable if isptr, or x.F or x[F]
1847
if isptr || strings.IndexByte(varname, '.') != -1 || strings.IndexByte(varname, '[') != -1 {
1848
x.decStruct(varname, rtid, t)
1850
varname2 := genTempVarPfx + "j" + mi
1851
x.line(varname2 + " := &" + varname)
1852
x.decStruct(varname2, rtid, t)
1855
// delete(x.td, rtid)
1856
x.line("z.DecFallback(" + addrPfx + varname + ", false)")
1862
x.line("z.DecFallback(" + addrPfx + varname + ", true)")
1866
func (x *genRunner) decTryAssignPrimitive(varname string, t reflect.Type, isptr bool) (done bool) {
1867
// This should only be used for exact primitives (ie un-named types).
1868
// Named types may be implementations of Selfer, Unmarshaler, etc.
1869
// They should be handled by dec(...)
1877
x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), codecSelferBitsize%s))", ptr, varname, x.genTypeName(t), x.xs)
1879
x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), 8))", ptr, varname, x.genTypeName(t))
1881
x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), 16))", ptr, varname, x.genTypeName(t))
1883
x.linef("%s%s = (%s)(z.C.IntV(r.DecodeInt64(), 32))", ptr, varname, x.genTypeName(t))
1885
x.linef("%s%s = (%s)(r.DecodeInt64())", ptr, varname, x.genTypeName(t))
1888
x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), codecSelferBitsize%s))", ptr, varname, x.genTypeName(t), x.xs)
1890
x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), 8))", ptr, varname, x.genTypeName(t))
1891
case reflect.Uint16:
1892
x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), 16))", ptr, varname, x.genTypeName(t))
1893
case reflect.Uint32:
1894
x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), 32))", ptr, varname, x.genTypeName(t))
1895
case reflect.Uint64:
1896
x.linef("%s%s = (%s)(r.DecodeUint64())", ptr, varname, x.genTypeName(t))
1897
case reflect.Uintptr:
1898
x.linef("%s%s = (%s)(z.C.UintV(r.DecodeUint64(), codecSelferBitsize%s))", ptr, varname, x.genTypeName(t), x.xs)
1900
case reflect.Float32:
1901
x.linef("%s%s = (%s)(z.DecDecodeFloat32())", ptr, varname, x.genTypeName(t))
1902
case reflect.Float64:
1903
x.linef("%s%s = (%s)(r.DecodeFloat64())", ptr, varname, x.genTypeName(t))
1905
case reflect.Complex64:
1906
x.linef("%s%s = (%s)(complex(z.DecDecodeFloat32(), 0))", ptr, varname, x.genTypeName(t))
1907
case reflect.Complex128:
1908
x.linef("%s%s = (%s)(complex(r.DecodeFloat64(), 0))", ptr, varname, x.genTypeName(t))
1911
x.linef("%s%s = (%s)(r.DecodeBool())", ptr, varname, x.genTypeName(t))
1912
case reflect.String:
1913
if t == genStringDecAsBytesTyp {
1914
x.linef("%s%s = r.DecodeStringAsBytes()", ptr, varname)
1915
} else if t == genStringDecZCTyp {
1916
x.linef("%s%s = (string)(z.DecStringZC(r.DecodeStringAsBytes()))", ptr, varname)
1918
x.linef("%s%s = (%s)(z.DecStringZC(r.DecodeStringAsBytes()))", ptr, varname, x.genTypeName(t))
1926
func (x *genRunner) decListFallback(varname string, rtid uintptr, t reflect.Type) {
1927
if t.AssignableTo(uint8SliceTyp) {
1928
x.line("*" + varname + " = z.DecodeBytesInto(*((*[]byte)(" + varname + ")))")
1931
if t.Kind() == reflect.Array && t.Elem().Kind() == reflect.Uint8 {
1932
x.linef("r.DecodeBytes( ((*[%d]byte)(%s))[:])", t.Len(), varname)
1935
type tstruc struct {
1946
ts := tstruc{genTempVarPfx, x.xs, x.varsfx(), varname, x.genTypeName(t), x.genTypeName(telem), genIsImmutable(telem), int(telem.Size())}
1948
funcs := make(template.FuncMap)
1950
funcs["decLineVar"] = func(varname string) string {
1951
x.decVar(varname, "", telem, false, true)
1954
funcs["var"] = func(s string) string {
1955
return ts.TempVar + s + ts.Rand
1957
funcs["xs"] = func() string {
1960
funcs["zero"] = func() string {
1961
return x.genZeroValueR(telem)
1963
funcs["isArray"] = func() bool {
1964
return t.Kind() == reflect.Array
1966
funcs["isSlice"] = func() bool {
1967
return t.Kind() == reflect.Slice
1969
funcs["isChan"] = func() bool {
1970
return t.Kind() == reflect.Chan
1972
tm, err := template.New("").Funcs(funcs).Parse(genDecListTmpl)
1974
genCheckErr(tm.Execute(x.w, &ts))
1977
func (x *genRunner) decMapFallback(varname string, rtid uintptr, t reflect.Type) {
1978
type tstruc struct {
1990
genTempVarPfx, x.xs, x.varsfx(), varname, x.genTypeName(tkey),
1991
x.genTypeName(telem), int(telem.Size() + tkey.Size()),
1994
funcs := make(template.FuncMap)
1995
funcs["decElemZero"] = func() string {
1996
return x.genZeroValueR(telem)
1998
funcs["decElemKindImmutable"] = func() bool {
1999
return genIsImmutable(telem)
2001
funcs["decElemKindPtr"] = func() bool {
2002
return telem.Kind() == reflect.Ptr
2004
funcs["decElemKindIntf"] = func() bool {
2005
return telem.Kind() == reflect.Interface
2007
funcs["decLineVarKStrBytes"] = func(varname string) string {
2008
x.decVar(varname, "", genStringDecAsBytesTyp, false, true)
2011
funcs["decLineVarKStrZC"] = func(varname string) string {
2012
x.decVar(varname, "", genStringDecZCTyp, false, true)
2015
funcs["decLineVarK"] = func(varname string) string {
2016
x.decVar(varname, "", tkey, false, true)
2019
funcs["decLineVar"] = func(varname, decodedNilVarname string) string {
2020
x.decVar(varname, decodedNilVarname, telem, false, true)
2023
funcs["var"] = func(s string) string {
2024
return ts.TempVar + s + ts.Rand
2026
funcs["xs"] = func() string {
2030
tm, err := template.New("").Funcs(funcs).Parse(genDecMapTmpl)
2032
genCheckErr(tm.Execute(x.w, &ts))
2035
func (x *genRunner) decStructMapSwitch(kName string, varname string, rtid uintptr, t reflect.Type) {
2036
ti := x.ti.get(rtid, t)
2037
tisfi := ti.sfi.source() // always use sequence from file. decStruct expects same thing.
2038
x.line("switch string(" + kName + ") {")
2039
var newbuf, nilbuf genBuf
2040
for _, si := range tisfi {
2041
x.line("case \"" + si.encName + "\":")
2044
varname3, t2 := x.decVarInitPtr(varname, "", t, si, &newbuf, &nilbuf)
2045
if len(newbuf.buf) > 0 {
2046
x.linef("if r.TryNil() { %s } else { %s", nilbuf.buf, newbuf.buf)
2048
x.decVarMain(varname3, x.varsfx(), t2.Type, false)
2049
if len(newbuf.buf) > 0 {
2054
// pass the slice here, so that the string will not escape, and maybe save allocation
2055
x.linef("z.DecStructFieldNotFound(-1, string(%s))", kName)
2056
x.linef("} // end switch %s", kName)
2059
func (x *genRunner) decStructMap(varname, lenvarname string, rtid uintptr, t reflect.Type) {
2060
tpfx := genTempVarPfx
2061
ti := x.ti.get(rtid, t)
2063
kName := tpfx + "s" + i
2065
x.linef("var %shl%s bool = %s >= 0", tpfx, i, lenvarname) // has length
2066
x.linef("for %sj%s := 0; z.DecContainerNext(%sj%s, %s, %shl%s); %sj%s++ {",
2067
tpfx, i, tpfx, i, lenvarname, tpfx, i, tpfx, i)
2069
x.line("z.DecReadMapElemKey()")
2071
// emulate decstructfieldkey
2074
x.linef("%s := strconv.AppendInt(z.DecScratchArrayBuffer()[:0], r.DecodeInt64(), 10)", kName)
2076
x.linef("%s := strconv.AppendUint(z.DecScratchArrayBuffer()[:0], r.DecodeUint64(), 10)", kName)
2077
case valueTypeFloat:
2078
x.linef("%s := strconv.AppendFloat(z.DecScratchArrayBuffer()[:0], r.DecodeFloat64(), 'f', -1, 64)", kName)
2080
x.linef("%s := r.DecodeStringAsBytes()", kName)
2083
x.line("z.DecReadMapElemValue()")
2084
x.decStructMapSwitch(kName, varname, rtid, t)
2086
x.line("} // end for " + tpfx + "j" + i)
2089
func (x *genRunner) decStructArray(varname, lenvarname, breakString string, rtid uintptr, t reflect.Type) {
2090
tpfx := genTempVarPfx
2092
ti := x.ti.get(rtid, t)
2093
tisfi := ti.sfi.source() // always use sequence from file. decStruct expects same thing.
2094
x.linef("var %sj%s int", tpfx, i)
2095
x.linef("var %sb%s bool", tpfx, i) // break
2096
x.linef("var %shl%s bool = %s >= 0", tpfx, i, lenvarname) // has length
2097
var newbuf, nilbuf genBuf
2098
for _, si := range tisfi {
2099
x.linef("%sb%s = !z.DecContainerNext(%sj%s, %s, %shl%s)", tpfx, i, tpfx, i, lenvarname, tpfx, i)
2100
x.linef("if %sb%s { z.DecReadArrayEnd(); %s }", tpfx, i, breakString)
2101
x.line("z.DecReadArrayElem()")
2104
varname3, t2 := x.decVarInitPtr(varname, "", t, si, &newbuf, &nilbuf)
2105
if len(newbuf.buf) > 0 {
2106
x.linef("if r.TryNil() { %s } else { %s", nilbuf.buf, newbuf.buf)
2108
x.decVarMain(varname3, x.varsfx(), t2.Type, false)
2109
if len(newbuf.buf) > 0 {
2112
x.linef("%sj%s++", tpfx, i)
2114
// read remaining values and throw away.
2115
x.linef("for ; z.DecContainerNext(%sj%s, %s, %shl%s); %sj%s++ {",
2116
tpfx, i, lenvarname, tpfx, i, tpfx, i)
2117
x.line("z.DecReadArrayElem()")
2118
x.linef(`z.DecStructFieldNotFound(%sj%s - 1, "")`, tpfx, i)
2122
func (x *genRunner) decStruct(varname string, rtid uintptr, t reflect.Type) {
2123
// varname MUST be a ptr, or a struct field or a slice element.
2125
x.linef("%sct%s := r.ContainerType()", genTempVarPfx, i)
2126
x.linef("if %sct%s == codecSelferValueTypeNil%s {", genTempVarPfx, i, x.xs)
2127
x.linef("*(%s) = %s{}", varname, x.genTypeName(t))
2128
x.linef("} else if %sct%s == codecSelferValueTypeMap%s {", genTempVarPfx, i, x.xs)
2129
x.line(genTempVarPfx + "l" + i + " := z.DecReadMapStart()")
2130
x.linef("if %sl%s == 0 {", genTempVarPfx, i)
2133
x.linef("%s.codecDecodeSelfFromMap(%sl%s, d)", varname, genTempVarPfx, i)
2136
x.line("z.DecReadMapEnd()")
2138
// else if container is array
2139
x.linef("} else if %sct%s == codecSelferValueTypeArray%s {", genTempVarPfx, i, x.xs)
2140
x.line(genTempVarPfx + "l" + i + " := z.DecReadArrayStart()")
2141
x.linef("if %sl%s != 0 {", genTempVarPfx, i)
2142
x.linef("%s.codecDecodeSelfFromArray(%sl%s, d)", varname, genTempVarPfx, i)
2144
x.line("z.DecReadArrayEnd()")
2147
x.line("panic(errCodecSelferOnlyMapOrArrayEncodeToStruct" + x.xs + ")")
2153
type fastpathGenV struct {
2154
// fastpathGenV is either a primitive (Primitive != "") or a map (MapKey != "") or a slice
2162
func (x *genRunner) newFastpathGenV(t reflect.Type) (v fastpathGenV) {
2163
v.NoCanonical = !genFastpathCanonical
2165
case reflect.Slice, reflect.Array:
2167
v.Elem = x.genTypeName(te)
2168
v.Size = int(te.Size())
2172
v.Elem = x.genTypeName(te)
2173
v.MapKey = x.genTypeName(tk)
2174
v.Size = int(te.Size() + tk.Size())
2176
halt.onerror(errGenUnexpectedTypeFastpath)
2181
func (x *fastpathGenV) MethodNamePfx(prefix string, prim bool) string {
2184
name = append(name, prefix...)
2187
name = append(name, genTitleCaseName(x.Primitive)...)
2190
name = append(name, "Slice"...)
2192
name = append(name, "Map"...)
2193
name = append(name, genTitleCaseName(x.MapKey)...)
2195
name = append(name, genTitleCaseName(x.Elem)...)
2200
// genImportPath returns import path of a non-predeclared named typed, or an empty string otherwise.
2202
// This handles the misbehaviour that occurs when 1.5-style vendoring is enabled,
2203
// where PkgPath returns the full path, including the vendoring pre-fix that should have been stripped.
2205
func genImportPath(t reflect.Type) (s string) {
2208
// HACK: always handle vendoring. It should be typically on in go 1.6, 1.7
2209
s = genStripVendor(s)
2214
// A go identifier is (letter|_)[letter|number|_]*
2215
func genGoIdentifier(s string, checkFirstChar bool) string {
2216
b := make([]byte, 0, len(s))
2217
t := make([]byte, 4)
2219
for i, r := range s {
2220
if checkFirstChar && i == 0 && !unicode.IsLetter(r) {
2223
// r must be unicode_letter, unicode_digit or _
2224
if unicode.IsLetter(r) || unicode.IsDigit(r) {
2225
n = utf8.EncodeRune(t, r)
2226
b = append(b, t[:n]...)
2234
func genNonPtr(t reflect.Type) reflect.Type {
2235
for t.Kind() == reflect.Ptr {
2241
func genFastpathUnderlying(t reflect.Type, rtid uintptr, ti *typeInfo) (tu reflect.Type, rtidu uintptr) {
2244
if ti.flagHasPkgPath {
2245
tu = ti.fastpathUnderlying
2251
func genTitleCaseName(s string) string {
2253
case "interface{}", "interface {}":
2255
case "[]byte", "[]uint8", "bytes":
2258
return strings.ToUpper(s[0:1]) + s[1:]
2262
func genMethodNameT(t reflect.Type, tRef reflect.Type) (n string) {
2264
for t.Kind() == reflect.Ptr {
2269
if tn := t.Name(); tn != "" {
2270
if tRef != nil && genImportPath(t) == genImportPath(tRef) {
2273
if genQNameRegex.MatchString(tstr) {
2274
return ptrPfx + strings.Replace(tstr, ".", "_", 1000)
2276
return ptrPfx + genCustomTypeName(tstr)
2282
return ptrPfx + "Map" + genMethodNameT(t.Key(), tRef) + genMethodNameT(t.Elem(), tRef)
2284
return ptrPfx + "Slice" + genMethodNameT(t.Elem(), tRef)
2286
return ptrPfx + "Array" + strconv.FormatInt(int64(t.Len()), 10) + genMethodNameT(t.Elem(), tRef)
2289
switch t.ChanDir() {
2290
case reflect.SendDir:
2292
case reflect.RecvDir:
2297
return ptrPfx + cx + genMethodNameT(t.Elem(), tRef)
2300
return ptrPfx + "Interface"
2302
if tRef != nil && genImportPath(t) == genImportPath(tRef) {
2304
return ptrPfx + t.Name()
2306
return ptrPfx + genCustomTypeName(tstr)
2309
// best way to get the package name inclusive
2310
if t.Name() != "" && genQNameRegex.MatchString(tstr) {
2311
return ptrPfx + strings.Replace(tstr, ".", "_", 1000)
2313
return ptrPfx + genCustomTypeName(tstr)
2320
// genCustomNameForType base32 encodes the t.String() value in such a way
2321
// that it can be used within a function name.
2322
func genCustomTypeName(tstr string) string {
2323
len2 := genTypenameEnc.EncodedLen(len(tstr))
2324
bufx := make([]byte, len2)
2325
genTypenameEnc.Encode(bufx, []byte(tstr))
2326
for i := len2 - 1; i >= 0; i-- {
2333
return string(bufx[:len2])
2336
func genIsImmutable(t reflect.Type) (v bool) {
2337
return scalarBitset.isset(byte(t.Kind()))
2340
type genInternal struct {
2342
Values []fastpathGenV
2346
func (x genInternal) FastpathLen() (l int) {
2347
for _, v := range x.Values {
2348
// if v.Primitive == "" && !(v.MapKey == "" && v.Elem == "uint8") {
2349
if v.Primitive == "" {
2356
func genInternalZeroValue(s string) string {
2358
case "interface{}", "interface {}":
2360
case "[]byte", "[]uint8", "bytes":
2371
var genInternalNonZeroValueIdx [6]uint64
2372
var genInternalNonZeroValueStrs = [...][6]string{
2373
{`"string-is-an-interface-1"`, "true", `"some-string-1"`, `[]byte("some-string-1")`, "11.1", "111"},
2374
{`"string-is-an-interface-2"`, "false", `"some-string-2"`, `[]byte("some-string-2")`, "22.2", "77"},
2375
{`"string-is-an-interface-3"`, "true", `"some-string-3"`, `[]byte("some-string-3")`, "33.3e3", "127"},
2380
func genInternalNonZeroValue(s string) string {
2383
case "interface{}", "interface {}":
2389
case "bytes", "[]byte", "[]uint8":
2391
case "float32", "float64", "float", "double", "complex", "complex64", "complex128":
2396
genInternalNonZeroValueIdx[i]++
2397
idx := genInternalNonZeroValueIdx[i]
2398
slen := uint64(len(genInternalNonZeroValueStrs))
2399
return genInternalNonZeroValueStrs[idx%slen][i]
2403
func genInternalEncCommandAsString(s string, vname string) string {
2406
return "e.e.EncodeUint(" + vname + ")"
2407
case "uint", "uint8", "uint16", "uint32":
2408
return "e.e.EncodeUint(uint64(" + vname + "))"
2410
return "e.e.EncodeInt(" + vname + ")"
2411
case "int", "int8", "int16", "int32":
2412
return "e.e.EncodeInt(int64(" + vname + "))"
2413
case "[]byte", "[]uint8", "bytes":
2414
return "e.e.EncodeStringBytesRaw(" + vname + ")"
2416
return "e.e.EncodeString(" + vname + ")"
2418
return "e.e.EncodeFloat32(" + vname + ")"
2420
return "e.e.EncodeFloat64(" + vname + ")"
2422
return "e.e.EncodeBool(" + vname + ")"
2426
return "e.encode(" + vname + ")"
2431
func genInternalDecCommandAsString(s string, mapkey bool) string {
2434
return "uint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))"
2436
return "uint8(chkOvf.UintV(d.d.DecodeUint64(), 8))"
2438
return "uint16(chkOvf.UintV(d.d.DecodeUint64(), 16))"
2440
return "uint32(chkOvf.UintV(d.d.DecodeUint64(), 32))"
2442
return "d.d.DecodeUint64()"
2444
return "uintptr(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))"
2446
return "int(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))"
2448
return "int8(chkOvf.IntV(d.d.DecodeInt64(), 8))"
2450
return "int16(chkOvf.IntV(d.d.DecodeInt64(), 16))"
2452
return "int32(chkOvf.IntV(d.d.DecodeInt64(), 32))"
2454
return "d.d.DecodeInt64()"
2461
return "d.stringZC(d.d.DecodeStringAsBytes())"
2462
case "[]byte", "[]uint8", "bytes":
2463
return "d.d.DecodeBytes([]byte{})"
2465
return "float32(d.decodeFloat32())"
2467
return "d.d.DecodeFloat64()"
2469
return "complex(d.decodeFloat32(), 0)"
2471
return "complex(d.d.DecodeFloat64(), 0)"
2473
return "d.d.DecodeBool()"
2475
halt.onerror(errors.New("gen internal: unknown type for decode: " + s))
2505
func genInternalSortType(s string, elem bool) string {
2513
func genStripVendor(s string) string {
2516
const vendorStart = "vendor/"
2517
const vendorInline = "/vendor/"
2518
if i := strings.LastIndex(s, vendorInline); i >= 0 {
2519
s = s[i+len(vendorInline):]
2520
} else if strings.HasPrefix(s, vendorStart) {
2521
s = s[len(vendorStart):]
2527
var genInternalV = genInternal{Version: genVersion}
2528
var genInternalTmplFuncs template.FuncMap
2529
var genInternalOnce sync.Once
2531
func genInternalInit() {
2532
wordSizeBytes := int(intBitsize) / 8
2534
typesizes := map[string]int{
2535
"interface{}": 2 * wordSizeBytes,
2536
"string": 2 * wordSizeBytes,
2537
"[]byte": 3 * wordSizeBytes,
2538
"uint": 1 * wordSizeBytes,
2543
"uintptr": 1 * wordSizeBytes,
2544
"int": 1 * wordSizeBytes,
2559
var types = [...]string{
2579
var primitivetypes, slicetypes, mapkeytypes, mapvaltypes []string
2581
primitivetypes = types[:]
2582
slicetypes = types[:]
2583
mapkeytypes = types[:]
2584
mapvaltypes = types[:]
2586
if genFastpathTrimTypes {
2590
slicetypes = genInternalFastpathSliceTypes()
2591
mapkeytypes = genInternalFastpathMapKeyTypes()
2592
mapvaltypes = genInternalFastpathMapValueTypes()
2606
var gt = genInternal{Version: genVersion, Formats: genFormats}
2610
for _, s := range primitivetypes {
2611
gt.Values = append(gt.Values,
2612
fastpathGenV{Primitive: s, Size: typesizes[s], NoCanonical: !genFastpathCanonical})
2614
for _, s := range slicetypes {
2618
gt.Values = append(gt.Values,
2619
fastpathGenV{Elem: s, Size: typesizes[s], NoCanonical: !genFastpathCanonical})
2621
for _, s := range mapkeytypes {
2626
for _, ms := range mapvaltypes {
2627
gt.Values = append(gt.Values,
2628
fastpathGenV{MapKey: s, Elem: ms, Size: typesizes[s] + typesizes[ms], NoCanonical: !genFastpathCanonical})
2632
funcs := make(template.FuncMap)
2634
funcs["encmd"] = genInternalEncCommandAsString
2635
funcs["decmd"] = genInternalDecCommandAsString
2636
funcs["zerocmd"] = genInternalZeroValue
2637
funcs["nonzerocmd"] = genInternalNonZeroValue
2638
funcs["hasprefix"] = strings.HasPrefix
2639
funcs["sorttype"] = genInternalSortType
2642
genInternalTmplFuncs = funcs
2646
func genInternalGoFile(r io.Reader, w io.Writer) (err error) {
2647
genInternalOnce.Do(genInternalInit)
2651
t := template.New("").Funcs(genInternalTmplFuncs)
2653
tmplstr, err := ioutil.ReadAll(r)
2658
if t, err = t.Parse(string(tmplstr)); err != nil {
2662
var out bytes.Buffer
2663
err = t.Execute(&out, gt)
2668
bout, err := format.Source(out.Bytes())
2670
w.Write(out.Bytes())
2678
func genInternalFastpathSliceTypes() []string {
2701
func genInternalFastpathMapKeyTypes() []string {
2723
func genInternalFastpathMapValueTypes() []string {
2758
func genInternalSortableTypes() []string {
2759
return genInternalFastpathMapKeyTypes()
2767
func genInternalSortablePlusTypes() []string {
2780
func genTypeForShortName(s string) string {
2790
func genArgs(args ...interface{}) map[string]interface{} {
2791
m := make(map[string]interface{}, len(args)/2)
2792
for i := 0; i < len(args); {
2793
m[args[i].(string)] = args[i+1]
2799
func genEndsWith(s0 string, sn ...string) bool {
2800
for _, s := range sn {
2801
if strings.HasSuffix(s0, s) {
2808
func genCheckErr(err error) {
2812
func genRunSortTmpl2Go(fnameIn, fnameOut string) {
2815
funcs := make(template.FuncMap)
2816
funcs["sortables"] = genInternalSortableTypes
2817
funcs["sortablesplus"] = genInternalSortablePlusTypes
2818
funcs["tshort"] = genTypeForShortName
2819
funcs["endswith"] = genEndsWith
2820
funcs["args"] = genArgs
2822
t := template.New("").Funcs(funcs)
2823
fin, err := os.Open(fnameIn)
2826
fout, err := os.Create(fnameOut)
2829
tmplstr, err := ioutil.ReadAll(fin)
2831
t, err = t.Parse(string(tmplstr))
2833
var out bytes.Buffer
2834
err = t.Execute(&out, 0)
2836
bout, err := format.Source(out.Bytes())
2838
fout.Write(out.Bytes())
2842
_, err = fout.Write(bout)
2846
func genRunTmpl2Go(fnameIn, fnameOut string) {
2848
fin, err := os.Open(fnameIn)
2851
fout, err := os.Create(fnameOut)
2854
err = genInternalGoFile(fin, fout)
2861
func (path *structFieldInfoPathNode) root() *structFieldInfoPathNode {
2863
if path.parent != nil {
2870
func (path *structFieldInfoPathNode) fullpath() (p []*structFieldInfoPathNode) {
2874
p = make([]*structFieldInfoPathNode, d)
2875
for d--; d >= 0; d-- {