Closed vanackere closed 3 years ago
This looks like a real bug.
Let me look into it this weekend.
BTW, can you run it without RecursiveEmptyCheck and post what you see? Thanks.
Mhh I see the same bug without RecursiveEmptyCheck:
--- FAIL: TestToJSON (0.00s)
user_test.go:16:
Error Trace: user_test.go:16
Error: Not equal:
expected: "{\"ID\":12,\"MaybeEmpty\":{\"A\":\"a\",\"B\":\"\"}}"
actual : "{\"ID\":12}"
Diff:
--- Expected
+++ Actual
@@ -1 +1 @@
-{"ID":12,"MaybeEmpty":{"A":"a","B":""}}
+{"ID":12}
Test: TestToJSON
I updated the title and made the bug reproduction code shorter (it turns out that the ID field was not necessary either)
Here is the generated file in case it helps:
// +build go1.6
// Code generated by codecgen - DO NOT EDIT.
package testcodec
import (
"errors"
"runtime"
"strconv"
codec1978 "github.com/ugorji/go/codec"
)
const (
// ----- content types ----
codecSelferCcUTF81977 = 1
codecSelferCcRAW1977 = 255
// ----- value types used ----
codecSelferValueTypeArray1977 = 10
codecSelferValueTypeMap1977 = 9
codecSelferValueTypeString1977 = 6
codecSelferValueTypeInt1977 = 2
codecSelferValueTypeUint1977 = 3
codecSelferValueTypeFloat1977 = 4
codecSelferValueTypeNil1977 = 1
codecSelferBitsize1977 = uint8(32 << (^uint(0) >> 63))
codecSelferDecContainerLenNil1977 = -2147483648
)
var (
errCodecSelferOnlyMapOrArrayEncodeToStruct1977 = errors.New(`only encoded map or array can be decoded into a struct`)
)
type codecSelfer1977 struct{}
func codecSelfer1977False() bool { return false }
func codecSelfer1977True() bool { return true }
func init() {
if codec1978.GenVersion != 20 {
_, file, _, _ := runtime.Caller(0)
ver := strconv.FormatInt(int64(codec1978.GenVersion), 10)
panic(errors.New("codecgen version mismatch: current: 20, need " + ver + ". Re-generate file: " + file))
}
}
func (x *User) CodecEncodeSelf(e *codec1978.Encoder) {
var h codecSelfer1977
z, r := codec1978.GenHelper().Encoder(e)
_, _, _ = h, z, r
if x == nil {
r.EncodeNil()
} else {
yy2arr2 := z.EncBasicHandle().StructToArray
_ = yy2arr2
const yyr2 bool = false // struct tag has 'toArray'
var yyq2 = [1]bool{ // should field at this index be written?
!(x.MaybeEmpty.IsCodecEmpty()), // MaybeEmpty
}
_ = yyq2
if yyr2 || yy2arr2 {
z.EncWriteArrayStart(1)
z.EncWriteArrayElem()
if yyq2[0] {
yy4 := &x.MaybeEmpty
if yyxt5 := z.Extension(yy4); yyxt5 != nil {
z.EncExtension(yy4, yyxt5)
} else {
z.EncFallback(yy4)
}
} else {
r.EncodeNil()
}
z.EncWriteArrayEnd()
} else {
var yynn2 int
for _, b := range yyq2 {
if b {
yynn2++
}
}
z.EncWriteMapStart(yynn2)
yynn2 = 0
if yyq2[0] {
z.EncWriteMapElemKey()
if z.IsJSONHandle() {
z.WriteStr("\"MaybeEmpty\"")
} else {
r.EncodeString(`MaybeEmpty`)
}
z.EncWriteMapElemValue()
yy6 := &x.MaybeEmpty
if yyxt7 := z.Extension(yy6); yyxt7 != nil {
z.EncExtension(yy6, yyxt7)
} else {
z.EncFallback(yy6)
}
}
z.EncWriteMapEnd()
}
}
}
func (x *User) CodecDecodeSelf(d *codec1978.Decoder) {
var h codecSelfer1977
z, r := codec1978.GenHelper().Decoder(d)
_, _, _ = h, z, r
yyct2 := r.ContainerType()
if yyct2 == codecSelferValueTypeNil1977 {
*(x) = User{}
} else if yyct2 == codecSelferValueTypeMap1977 {
yyl2 := z.DecReadMapStart()
if yyl2 == 0 {
} else {
x.codecDecodeSelfFromMap(yyl2, d)
}
z.DecReadMapEnd()
} else if yyct2 == codecSelferValueTypeArray1977 {
yyl2 := z.DecReadArrayStart()
if yyl2 != 0 {
x.codecDecodeSelfFromArray(yyl2, d)
}
z.DecReadArrayEnd()
} else {
panic(errCodecSelferOnlyMapOrArrayEncodeToStruct1977)
}
}
func (x *User) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) {
var h codecSelfer1977
z, r := codec1978.GenHelper().Decoder(d)
_, _, _ = h, z, r
var yyhl3 bool = l >= 0
for yyj3 := 0; ; yyj3++ {
if yyhl3 {
if yyj3 >= l {
break
}
} else {
if z.DecCheckBreak() {
break
}
}
z.DecReadMapElemKey()
yys3 := z.StringView(r.DecodeStringAsBytes())
z.DecReadMapElemValue()
switch yys3 {
case "MaybeEmpty":
if yyxt5 := z.Extension(x.MaybeEmpty); yyxt5 != nil {
z.DecExtension(&x.MaybeEmpty, yyxt5)
} else {
z.DecFallback(&x.MaybeEmpty, false)
}
default:
z.DecStructFieldNotFound(-1, yys3)
} // end switch yys3
} // end for yyj3
}
func (x *User) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) {
var h codecSelfer1977
z, r := codec1978.GenHelper().Decoder(d)
_, _, _ = h, z, r
var yyj6 int
var yyb6 bool
var yyhl6 bool = l >= 0
yyj6++
if yyhl6 {
yyb6 = yyj6 > l
} else {
yyb6 = z.DecCheckBreak()
}
if yyb6 {
z.DecReadArrayEnd()
return
}
z.DecReadArrayElem()
if yyxt8 := z.Extension(x.MaybeEmpty); yyxt8 != nil {
z.DecExtension(&x.MaybeEmpty, yyxt8)
} else {
z.DecFallback(&x.MaybeEmpty, false)
}
for {
yyj6++
if yyhl6 {
yyb6 = yyj6 > l
} else {
yyb6 = z.DecCheckBreak()
}
if yyb6 {
break
}
z.DecReadArrayElem()
z.DecStructFieldNotFound(yyj6-1, "")
}
}
func (x *User) IsCodecEmpty() bool {
return !(!(x.MaybeEmpty.IsCodecEmpty()) && true)
}
func (x *S) IsCodecEmpty() bool {
return !(x.A != "" && x.B != "" && true)
}
I sent a pull request that should fix this issue, please merge ASAP if correct, this is a serious issue I think
Would be great to get this in.
Hi, I hope this bug is not a user error this time ;-)
I have a test case failing with the current codecgen (the same code was working before updating the package). Minimal reproduction:
The following test passes without codecgen and fails with code generation for the User type (codecgen -d 1977 -o user_codecgen.go -r User user.go):