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  }