Skip to content

jsonpb: emit null value for oneof field with 'nil-interface' value #582

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from

Conversation

marusama
Copy link

@marusama marusama commented Apr 4, 2018

example proto:

message test {
    oneof roadIdNil {
        int32 roadId = 12;
    }
}

go code:

var roadId *proto.Test_RoadIdNil
test.RoadIdNil = roadId                // now RoadIdNil is not nil, but contains "nil" Interface  

will produce json:

{
    "roadId": null
}

instead of panic:
2018/04/04 18:07:28 http: panic serving [::1]:62625: reflect: call of reflect.Value.Field on zero Value goroutine 6 [running]: net/http.(*conn).serve.func1(0xc42009e8c0) /usr/local/Cellar/go/1.10.1/libexec/src/net/http/server.go:1726 +0xd0 panic(0x13e9e60, 0xc4202ab420) /usr/local/Cellar/go/1.10.1/libexec/src/runtime/panic.go:502 +0x229 reflect.Value.Field(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14c9c40) /usr/local/Cellar/go/1.10.1/libexec/src/reflect/value.go:782 +0x11b soap/vendor/github.com/golang/protobuf/jsonpb.(*Marshaler).marshalObject(0xc420095bc0, 0xc420171910, 0x14c6b20, 0xc4200ac480, 0x0, 0x0, 0x0, 0x0, 0xc420170870, 0x8) /Users/btstsyrendylykov/go/src/soap/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go:297 +0x58d soap/vendor/github.com/golang/protobuf/jsonpb.(*Marshaler).marshalValue(0xc420095bc0, 0xc420171910, 0xc4202e5cc0, 0x146a3c0, 0xc420184130, 0x196, 0x0, 0x0, 0x0, 0x8) /Users/btstsyrendylykov/go/src/soap/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go:525 +0xbe5 soap/vendor/github.com/golang/protobuf/jsonpb.(*Marshaler).marshalValue(0xc420095bc0, 0xc420171910, 0xc4202e5cc0, 0x13bb940, 0xc4202743c0, 0x197, 0x0, 0x0, 0xc420170b60, 0xc4202e5cc0) /Users/btstsyrendylykov/go/src/soap/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go:476 +0x1125 soap/vendor/github.com/golang/protobuf/jsonpb.(*Marshaler).marshalField(0xc420095bc0, 0xc420171910, 0xc4202e5cc0, 0x13bb940, 0xc4202743c0, 0x197, 0x0, 0x0, 0x0, 0xc420189c38) /Users/btstsyrendylykov/go/src/soap/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go:446 +0x10b soap/vendor/github.com/golang/protobuf/jsonpb.(*Marshaler).marshalObject(0xc420095bc0, 0xc420171910, 0x14c6ae0, 0xc4202743c0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8) /Users/btstsyrendylykov/go/src/soap/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go:304 +0x494 soap/vendor/github.com/golang/protobuf/jsonpb.(*Marshaler).marshalValue(0xc420095bc0, 0xc420171910, 0xc4202ce280, 0x1420960, 0xc42000e1e8, 0x196, 0x0, 0x0, 0xc420171300, 0xc4202ce280) /Users/btstsyrendylykov/go/src/soap/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go:525 +0xbe5 soap/vendor/github.com/golang/protobuf/jsonpb.(*Marshaler).marshalField(0xc420095bc0, 0xc420171910, 0xc4202ce280, 0x1420960, 0xc42000e1e8, 0x196, 0x0, 0x0, 0x0, 0xc420189358) /Users/btstsyrendylykov/go/src/soap/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go:446 +0x10b soap/vendor/github.com/golang/protobuf/jsonpb.(*Marshaler).marshalObject(0xc420095bc0, 0xc420171910, 0x14c6aa0, 0xc42000e1e8, 0x0, 0x0, 0x0, 0x0, 0xc420171930, 0x1012478) /Users/btstsyrendylykov/go/src/soap/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go:304 +0x494 soap/vendor/github.com/golang/protobuf/jsonpb.(*Marshaler).Marshal(0xc420095bc0, 0x14c0a20, 0xc4201bea80, 0x14c6aa0, 0xc42000e1e8, 0x14c6aa0, 0x1430c80) /Users/btstsyrendylykov/go/src/soap/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go:122 +0x9d soap/vendor/github.com/golang/protobuf/jsonpb.(*Marshaler).MarshalToString(0xc420095bc0, 0x14c6aa0, 0xc42000e1e8, 0x14c6aa0, 0xc42000e1e8, 0x14208c0, 0xc42000e1e8) /Users/btstsyrendylykov/go/src/soap/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go:128 +0x6e

example proto:
message test {
    oneof roadIdNil {
        int32 roadId = 12;
    }
}

go code:
```
var roadId *proto.Test_RoadIdNil
test.RoadIdNil = roadId
```
will produce json:
{
    "roadId": null
}
instead of panic
@marusama
Copy link
Author

marusama commented Apr 4, 2018

@dsnet I recreated PR from dev branch, and yes, it looks like #478

@marusama
Copy link
Author

marusama commented Apr 4, 2018

With my PR we will have three options:
if oneof field is

  • nil -> no field in resulting JSON
  • nil-interface -> "field": null in JSON (now it panics)
  • filled value -> "field": "value"

I think it is more convenient

@marusama
Copy link
Author

marusama commented Apr 5, 2018

I've added second commit 04e8c55 for the same behavior on unmarchal json:
if json field is

  • absent -> oneof field will be nil
  • "field": null -> oneof field = nil-interface (now it has default value, that's seemd wrong for me)
  • "field": "value" -> oneof field with "value"

so it's pretty simple to recognize if field absent or null

@dsnet dsnet added the jsonpb label May 11, 2018
@dsnet dsnet removed the jsonpb label Jul 10, 2019
@dsnet
Copy link
Member

dsnet commented Aug 9, 2019

The v2 re-implementation has logic for handling the situation when a nil wrapper type is set. Closing this as no longer relevant.

@dsnet dsnet closed this Aug 9, 2019
@golang golang locked and limited conversation to collaborators Jun 26, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants