-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
support one-ofs in body #570
support one-ofs in body #570
Conversation
Hey @jhump, sorry for the very slow response on this. Let me give you an update on the state of affairs around here. I have a PR that I'm going to be submitting soon that is the beginning of the breaking change window for a 2.0 release. As such I've been focusing on getting that done and not really tending to the PR queue. Sorry about that. This looks like a really good PR to have included and I don't mind at all that it doesn't completely solve the recursive form of the problem -- the perfect is the enemy of the good after all. One thing I noticed is that you've hit a bug in our CI system. I am curious. Do you think you could rebase this PR after that commit and see if the CI system blows up? I would have expected this to fail since you changed the template which should make the examples directory (which is a dir of goldens) not match. To fix this, you can run Thanks so much for your hard work! |
Friendliest of pings |
a0a10b5
to
2bed8fd
Compare
Looks like this has already been fixed for path params but is still broken for the body. The current code produces Go code that can't compile if a oneof is specified as the body. I think I see how to address that. |
2bed8fd
to
f2d5146
Compare
@@ -207,6 +207,7 @@ var ( | |||
var protoReq {{.Method.RequestType.GoType .Method.Service.File.GoPkg.Path}} | |||
var metadata runtime.ServerMetadata | |||
{{if .Body}} | |||
{{.Body.AssignableExprPrep "protoReq"}} | |||
if err := marshaler.NewDecoder(req.Body).Decode(&{{.Body.AssignableExpr "protoReq"}}); err != nil && err != io.EOF { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what generated bad code. The AssignableExpr
would have emitted the prep statements, which would get incorrectly inlined in the call to Decode
. By splitting out the prep statements, it now generates working code.
// AssignableExprPrep returns preparation statements for an assignable expression to assign a value | ||
// to the target field. The go expression of the method request object is "msgExpr". This is only | ||
// needed for field paths that contain oneofs. Otherwise, an empty string is returned. | ||
func (p FieldPath) AssignableExprPrep(msgExpr string) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I essentially forked AssignableExpr
, with this method preserving just the preparations
and the other only emitting the last line, the actual field ref.
@achew22, PTAL |
The build breakage was bad timing - I pushed just after protobuf merged their dev branch to master. I will rebase this PR after #636 lands, to see if I can get the tests to go green. |
@yugui Have you seen this? |
f2d5146
to
578d2a7
Compare
6740b64
to
26d004c
Compare
Codecov Report
@@ Coverage Diff @@
## master #570 +/- ##
==========================================
- Coverage 58.88% 58.44% -0.44%
==========================================
Files 30 30
Lines 2853 2871 +18
==========================================
- Hits 1680 1678 -2
- Misses 1010 1030 +20
Partials 163 163
Continue to review full report at Codecov.
|
Code looks LGTM. My only comment is that I'd like a test case that demonstrates oneof population from body. |
Bump, need a rebase and a test case please. |
@johanbrandhorst, sorry, I've been busy, and we've since re-formulated our proto to not actually need this feature. So, if this seems like a valuable contribution, someone else will have to take it over. |
I was curious if this was something that might be accepted as a patch, and (if so) if I'm on the right track.
I must admit, I don't really understand how the
FieldPath
stuff really works. I mean, I think I see how it's supposed to work. But it looks like actually using nested elements (e.g.foo.bar.baz
) would always result in nil dereference panic since the actual request's fields have zero values. So, in this example, fieldprotoReq.Foo
, presumably a pointer to message struct, would be nil, and thus unmarshaling code would traverse a nil pointer trying to compute&protoReq.Foo.Bar.Baz
(even if it were just one level of nesting:&protoReq.Foo.Bar
).So, in this patch, I didn't really bother examining the entire path for oneofs and only look at the first field. Does that seem sane?
BTW, the whole reason I was exploring this patch is to support an API idiom like so: