diff --git a/generate/generate.go b/generate/generate.go index 796af57..b0be848 100644 --- a/generate/generate.go +++ b/generate/generate.go @@ -67,6 +67,7 @@ type Generator struct { type decodeBranchRequest struct { hash [16]byte typ Type + name string } func (this *Generator) Generate(protocol *Protocol) (n int, err error) { @@ -102,9 +103,9 @@ func (this *Generator) Generate(protocol *Protocol) (n int, err error) { // request queue for { - hash, typ, ok := this.pullDecodeBranchRequest() + hash, typ, name, ok := this.pullDecodeBranchRequest() if !ok { break } - nn, err := this.generateDecodeBranch(hash, typ) + nn, err := this.generateDecodeBranch(hash, typ, name) n += nn; if err != nil { return n, err } } @@ -193,7 +194,7 @@ func (this *Generator) generateTypedef(name string, typ Type) (n int, err error) nn, err = this.iprintf("}\n") n += nn; if err != nil { return n, err } - nn, err = this.generateDecodeValue(typ, "this", "tag") + nn, err = this.generateDecodeValue(typ, name, "this", "tag") n += nn; if err != nil { return n, err } nn, err = this.iprintf("return n, nil\n") n += nn; if err != nil { return n, err } @@ -282,7 +283,7 @@ func (this *Generator) generateMessage(method uint16, message Message) (n int, e nn, err = this.iprintf("}\n") n += nn; if err != nil { return n, err } - nn, err = this.generateDecodeValue(message.Type, "this", "tag") + nn, err = this.generateDecodeValue(message.Type, this.resolveMessageName(message.Name), "this", "tag") n += nn; if err != nil { return n, err } nn, err = this.iprintf("return n, nil\n") n += nn; if err != nil { return n, err } @@ -471,7 +472,10 @@ func (this *Generator) generateEncodeValue(typ Type, valueSource, tagSource stri // - n int // - err error // - nn int -func (this *Generator) generateDecodeValue(typ Type, valueSource, tagSource string) (n int, err error) { +// +// The typeName paramterer is handled in the way described in the documentation +// for [Generator.generateDecodeBranch]. +func (this *Generator) generateDecodeValue(typ Type, typeName, valueSource, tagSource string) (n int, err error) { switch typ := typ.(type) { case TypeInt: // SI: (none) @@ -537,7 +541,7 @@ func (this *Generator) generateDecodeValue(typ Type, valueSource, tagSource stri } case TypeArray: // OTA: * - nn, err := this.generateDecodeBranchCall(typ, valueSource, tagSource) + nn, err := this.generateDecodeBranchCall(typ, typeName, valueSource, tagSource) n += nn; if err != nil { return n, err } case TypeTable: // KTV: ( )* @@ -549,7 +553,7 @@ func (this *Generator) generateDecodeValue(typ Type, valueSource, tagSource stri n += nn; if err != nil { return n, err } case TypeTableDefined: // KTV: ( )* - nn, err := this.generateDecodeBranchCall(typ, valueSource, tagSource) + nn, err := this.generateDecodeBranchCall(typ, typeName, valueSource, tagSource) n += nn; if err != nil { return n, err } case TypeNamed: // WHATEVER: [WHATEVER] @@ -576,24 +580,36 @@ func (this *Generator) generateDecodeValue(typ Type, valueSource, tagSource stri // - n int // - err error // - nn int -func (this *Generator) generateDecodeBranchCall(typ Type, valueSource, tagSource string) (n int, err error) { +// +// The typeName paramterer is handled in the way described in the documentation +// for [Generator.generateDecodeBranch]. +func (this *Generator) generateDecodeBranchCall(typ Type, typeName, valueSource, tagSource string) (n int, err error) { hash := HashType(typ) - nn, err := this.iprintf("nn, err = %s(%s, decoder, %s)\n", this.decodeBranchName(hash), valueSource, tagSource) + nn, err := this.iprintf( + "nn, err = %s(%s, decoder, %s)\n", + this.decodeBranchName(hash, typeName), valueSource, tagSource) n += nn; if err != nil { return n, err } nn, err = this.generateErrorCheck() n += nn; if err != nil { return n, err } - this.pushDecodeBranchRequest(hash, typ) + this.pushDecodeBranchRequest(hash, typ, typeName) return n, nil } // generateDecodeBranch generates an aggregate decoder function definition for a -// specified type. It assumes that hash == HashType(typ). -func (this *Generator) generateDecodeBranch(hash [16]byte, typ Type) (n int, err error) { - nn, err := this.iprintf("\nfunc %s[T ~", this.decodeBranchName(hash)) +// specified type. It assumes that hash == HashType(typ). If typeName is not +// empty, it will be used as the type in the argument list instead of the result +// of [Generator.generateType]. +func (this *Generator) generateDecodeBranch(hash [16]byte, typ Type, typeName string) (n int, err error) { + nn, err := this.iprintf("\nfunc %s(this *", this.decodeBranchName(hash, typeName)) n += nn; if err != nil { return n, err } - nn, err = this.generateType(typ) - n += nn; if err != nil { return n, err } - nn, err = this.printf("](this *T, decoder *tape.Decoder, tag tape.Tag) (n int, err error) {\n") + if typeName == "" { + nn, err = this.generateType(typ) + n += nn; if err != nil { return n, err } + } else { + nn, err = this.print(typeName) + n += nn; if err != nil { return n, err } + } + nn, err = this.printf(", decoder *tape.Decoder, tag tape.Tag) (n int, err error) {\n") n += nn; if err != nil { return n, err } this.push() @@ -665,7 +681,7 @@ func (this *Generator) generateDecodeBranch(hash [16]byte, typ Type) (n int, err nn, err = this.iprintf("for index := range int(%s) {\n", lengthVar) n += nn; if err != nil { return n, err } this.push() - nn, err = this.generateDecodeValue(typ.Element, "(*this)[index]", elementTagVar) + nn, err = this.generateDecodeValue(typ.Element, "", "(*this)[index]", elementTagVar) n += nn; if err != nil { return n, err } this.pop() nn, err = this.iprintf("}\n") @@ -740,7 +756,9 @@ func (this *Generator) generateDecodeBranch(hash [16]byte, typ Type) (n int, err n += nn; if err != nil { return n, err } // decode payload - nn, err = this.generateDecodeValue(field.Type, fmt.Sprintf("&(this.%s)", field.Name), fieldTagVar) + nn, err = this.generateDecodeValue( + field.Type, "", + fmt.Sprintf("&(this.%s)", field.Name), fieldTagVar) n += nn; if err != nil { return n, err } this.pop() } @@ -775,31 +793,36 @@ func (this *Generator) generateDecodeBranch(hash [16]byte, typ Type) (n int, err return n, nil } -func (this *Generator) decodeBranchName(hash [16]byte) string { - return fmt.Sprintf("decodeBranch_%s", hex.EncodeToString(hash[:])) +func (this *Generator) decodeBranchName(hash [16]byte, name string) string { + if name == "" { + return fmt.Sprintf("decodeBranch_%s", hex.EncodeToString(hash[:])) + } else { + return fmt.Sprintf("decodeBranch_%s_%s", hex.EncodeToString(hash[:]), name) + } } // pushDecodeBranchRequest pushes a new branch decode function request to the // back of the queue, if it is not already in the queue. -func (this *Generator) pushDecodeBranchRequest(hash [16]byte, typ Type) { +func (this *Generator) pushDecodeBranchRequest(hash [16]byte, typ Type, name string) { for _, item := range this.decodeBranchRequestQueue { - if item.hash == hash { return } + if item.hash == hash && item.name == name { return } } this.decodeBranchRequestQueue = append(this.decodeBranchRequestQueue, decodeBranchRequest { hash: hash, typ: typ, + name: name, }) } // pullDecodeBranchRequest pulls a branch decode function request from the front // of the queue. -func (this *Generator) pullDecodeBranchRequest() (hash [16]byte, typ Type, ok bool) { +func (this *Generator) pullDecodeBranchRequest() (hash [16]byte, typ Type, name string, ok bool) { if len(this.decodeBranchRequestQueue) < 1 { - return [16]byte { }, nil, false + return [16]byte { }, nil, "", false } request := this.decodeBranchRequestQueue[0] this.decodeBranchRequestQueue = this.decodeBranchRequestQueue[1:] - return request.hash, request.typ, true + return request.hash, request.typ, request.name, true } func (this *Generator) generateErrorCheck() (n int, err error) {