-
Notifications
You must be signed in to change notification settings - Fork 15.5k
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
JavaScript: Use strings for 64-bit ints to preserve precision #1832
Conversation
Thanks for your pull request. The automated tests will run as soon as one of the admins verifies this change is ok to test. |
Thanks for the fix. This is an issue we need to address, but it's not 100% clear what the right way forward is. Converting from string to integer all the time could be annoying. There is a js_type option in descriptor.proto (https://github.com/google/protobuf/blob/master/src/google/protobuf/descriptor.proto#L484) but we don't currently respect it. There is a slightly different version of that option internally. We need to figure out which direction to go with this. Additionally, since we're released 3.0 as GA, we need changes to start being backward-compatible. That means providing a migration path for a non-backward-compatible change like this. We would probably need to introduce it as an option that initially defaults to false, then flip it to defaulting to true, then remove it. |
Well, to be fair, you just stick a The js_type option needs to be present in the .proto file, right? In that case, it's not a good solution for those who are using existing .proto files. We could add an option to Another option is to return a string only if it would lose precision otherwise. But I don't like this solution because it would make the returned type unpredictable. And it would also be technically non-backward-compatible too (although the code it would break is kinda already broken anyway). |
True. It may be better for this option to default to string. Then people can set the option on fields where it is safe to return integer (because the field is expected to always be less than 2^54).
I agree, I think the return type should be consistent. |
Makes sense. The commit I just pushed reverts to the old behavior if |
Any update on this? |
Any solution or workaround on this issue? |
Thanks for your pull request. The automated tests will run as soon as one of the admins verifies this change is ok for us to run on our infrastructure. |
@seishun Thanks for the update. Our current thinking is that we may need to preserve the current default (int64s as JavaScript numbers) for the sake of backward compatibility. We released 3.0 as GA and we try not to break existing code or workflows. We should definitely be able to add support for |
I see. Could this be added as an option to
This is correct, and I guess it's the same for most users. Having to modify or pre-process a lot of existing .proto files because of a specific protobuf implementation might be annoying. And I believe it should generally be up to the implementation to decide how to represent protobuf types, not the .proto file. |
Yes, that seems like a possibility. I agree it would also be a better default in the long term.
I can see that argument. I think the argument for allowing this to be set in the The best example of this is timestamps that are in milliseconds or microseconds. |
Done, the representation of int64s in case of The tests now fail because I'm not sure how to test an option. It seems there is no existing infrastructure for testing options. I can just revert the changes in tests for now.
I agree about the use case for |
Does anyone know the status of this problem with respect to v3.2.1? I'm having precision issues and resorted to a sed trick to rewrite all instances of readInt64/writeInt64 to readInt64String/writeInt64String in the generated JS file. This works, but isn't ideal. I added the field option (ex. Thanks! |
Can one of the admins verify this patch? |
Hi there, any updates? |
Sorry for the delay. Just returned from a month-long vacation. |
Hey there - is this still planned to go ahead? We have some int64s which are losing precision and having the |
Can one of the admins verify this patch? |
The support of js_type option has been added to the Google internal codebase. It will be exported to the open source repo later. By then one can specify the JS type of a 64-bit integer field to be string in the generated code. The default JS type will be still number. |
Using the js_type option requires modifying the .proto file so it's not really a solution as explained here. |
Agreed with @seishun. We're hoping to set the behaviour for all of our protos and ideally want to avoid having to add the annotation to every int64 field we have. |
I'd like to throw in a vote for releasing the field option so there is at least 1 option in the near term. Thanks for the support on this. |
For everyone who is interested in this, please help create an issue (or comment on an existing issue) instead. This is a significant semantic change and we need to carefully implement and rollout the change in both google internally and opensource. It's not something we can accept in a pull request. |
Currently the following happens:
This fixes it by representing 64-bit ints as decimal strings: