github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/amino/gengo/gengo.go (about) 1 package gengo 2 3 import ( 4 "fmt" 5 "reflect" 6 7 "github.com/gnolang/gno/tm2/pkg/amino" 8 "github.com/gnolang/gno/tm2/pkg/amino/libs/press" 9 ) 10 11 // shortcut 12 var _fmt = fmt.Sprintf 13 14 func PrintIntEncoder(p *press.Press, ref string) { 15 p.Pl("{").I(func(p *press.Press) { 16 p.Pl("var buf[10]byte") 17 p.Pl("n := binary.PutVarint(buf[:], %v)", ref) 18 p.Pl("_, err = w.Write(buf[0:n])") 19 }).Pl("}") 20 } 21 22 func PrintStructFieldEncoder(p *press.Press, ref string, info amino.FieldInfo) { 23 name := info.Name 24 fref := ref + "." + name // TODO document restriction on name types to make naive "+" possible. 25 done := p.RandID("done") 26 cond := printStructFieldSkipCond(p, fref, info) 27 p.Pl("{").I(func(p *press.Press) { 28 p.Pl("// Struct field %v", name) 29 p.Pl("// Maybe skip?") 30 p.Pl("// if (%v) {", cond).I(func(p *press.Press) { 31 p.Pl("goto %v", done) 32 }).Pl("}") 33 p.Pl("pos1 := w.Len()") 34 p.Pl("// Write field number & typ3") 35 p.Pl("// TODO") 36 p.Pl("pos2 := w.Len()") 37 p.Pl("// Write field value") 38 // XXX PrintValueEncoder(p, fref, info.Type) 39 p.Pl("XXX PrintValueEncoder()") 40 p.Pl("pos3 := w.Len()") 41 // Maybe skip the writing of zero structs unless also WriteEmpty. 42 if info.Type.Kind() == reflect.Ptr && !info.WriteEmpty { 43 p.Pl("if (pos2 == pos3-1 && w.PeekLastByte() == 0x00) {").I(func(p *press.Press) { 44 p.Pl("w.Truncate(pos1)") 45 }).Pl("}") 46 } 47 }).Pl("}") 48 } 49 50 func printStructFieldSkipCond(p *press.Press, fref string, info amino.FieldInfo) string { 51 // If the value is nil or empty, do not encode. 52 // Amino "zero" structs are not yet well defined/understood. 53 // Field values that are zero structs (and !WriteEmpty) are not skipped 54 // here, but later in PrintStructFieldEncoder() upon inspecting the number 55 // of written bytes. 56 switch info.Type.Kind() { 57 case reflect.Ptr: 58 return _fmt("%v == nil", fref) 59 case reflect.Bool: 60 return _fmt("%v == false", fref) 61 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 62 return _fmt("%v == 0", fref) 63 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 64 return _fmt("%v == 0", fref) 65 case reflect.String: 66 return _fmt("len(%v) == 0", fref) 67 case reflect.Chan, reflect.Map, reflect.Slice: 68 return _fmt("%v == nil || len(%v) == 0", fref, fref) 69 case reflect.Func, reflect.Interface: 70 return _fmt("%v == nil", fref) 71 default: 72 return "true" 73 } 74 }