Skip to content
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

Correctly support proto3 optional fields in commonjs+dts .d.ts output #1184

Merged
merged 3 commits into from
Jan 28, 2022
Merged

Correctly support proto3 optional fields in commonjs+dts .d.ts output #1184

merged 3 commits into from
Jan 28, 2022

Conversation

mattnathan
Copy link
Contributor

Fixes #1072

@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Jan 10, 2022

CLA Signed

The committers are authorized under a signed CLA.

@mattnathan
Copy link
Contributor Author

I think this is correct, I'm not entirely sure how to build or test it. Guidance would be greatly appreciated.

@mattnathan mattnathan marked this pull request as ready for review January 10, 2022 15:28
@mattnathan
Copy link
Contributor Author

I've managed to build (via bazel) and test this locally against some proto files I have with optional fields and it correctly outputs hasXxx and clearXxx methods for those fields in the .d.ts files.

Copy link
Collaborator

@sampajano sampajano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mattnathan Hi Matt! Thanks so much for working on this fix (and apologize for the delay)!! The change (logic) looks great to me! 😃

Lemme look a little bit into what are some good ways to unit test it. (If not i'd say just merge it anyways since it's probably low risk :D)

@stanley-cheung Lemme know if you have some ideas on how you would test this change too! Thanks! :)

Comment on lines 828 to 829
if ((field->type() == FieldDescriptor::TYPE_MESSAGE || field->has_optional_keyword()) &&
!field->is_repeated() && !field->is_map()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: i'd probably prefer to maybe rewrite the logic as follows:

(field->has_optional_keyword() ||
    (field->type() == FieldDescriptor::TYPE_MESSAGE && 
        !field->is_repeated() &&
        !field->is_map())

Probably doesn't make a huge difference, but it seems to make a little bit more sense to me.. :P

WDYT? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure.

The semantics of the two conditions is only the same when you factor in the proto3 language spec disallowing optional on map or repeated fields.

I read it as when the field is a message or optional, but not when repeated or a map as opposed to when the field is optional (which implies it's not repeated or a map), or it's a message but not repeated or a map.

I'll leave the final decision up to you though :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The semantics of the two conditions is only the same when you factor in the proto3 language spec disallowing optional on map or repeated fields.

Yeah i think that was my exactly concern.. -- that optional is mutually exclusive with repeated and map so i don't think they should be in a AND relationship.. :)

I read it as when the field is a message or optional, but not when repeated or a map as opposed to when the field is optional (which implies it's not repeated or a map), or it's a message but not repeated or a map.

Yeah right.. although i felt that's a little long-winded.. (and i had some challenge understanding that too) 😅

Where i was thinking as: when the field is optional, or a message that is not repeated or a map.

I feel the latter is simpler and easier to reason. :)

If you are ok both ways, do you mind making the change? Thanks! :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change has been made

Not sure what the process is around resolving conversations, so I'll leave this thread here

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the change! I guess it doesn't hurt to just leave them open here :D

printer->Print(
vars, "get$js_oneof_name$Case(): $class_name$.$js_oneof_name$Case;\n");
printer->Print("\n");
if (!oneof->is_synthetic()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw nice job finding the is_synthetic() API!😃

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, you forget what it's like to find docs via Google instead of using your IDE 😂

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes right.. 😄

@mattnathan
Copy link
Contributor Author

Sorry for any delays in responses, UK based over here

@sampajano
Copy link
Collaborator

sampajano commented Jan 28, 2022

Sorry for any delays in responses, UK based over here

Np at all! That's almost no delay at all (compared it taking 16 days for me to review 😂)..

Thanks again for the contribution and being patient with the review! :)

(I will cut a release very soon (maybe today or latest next week) which contains this fix. Thanks! :))

@sampajano sampajano merged commit eb313c1 into grpc:master Jan 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

.d.ts typescript definition doesn't match js with proto3 optional fields
3 participants