Comments (9)
This is a consequence of the way map support is currently implemented: a generic mapping that will be rendered into either record syntax or map syntax. So, since optional fields are always present in records, having the value undefined
if not set, this is currently inherited to maps too. But I think you're right, now with maps, we have one more option: to allow non-set optional fields to be missing altogether. It also nicely solves the issue with an enum having a symbol that is the text undefined
. This has never been handled very well, but with maps, it could. So I'm definitely in favour of fixing this, and will take a look at it.
I'm also thinking about backwards compatibility, whether we should still allow non-set optional fields to be present and have the value undefined
, like in records, but I think I'm against it. It will break backwards compatibility, but on the other hand, map support is still flagged as an area that is settling down, so perhaps with deprecation and a transition period.
from gpb.
Cool, thanks for the information. :) Yeah, I agree that it would be cleanest to disallow using undefined
to declare non-set optional fields, as a long-term solution. Your idea to deprecate that kind of usage and set up a transition period sounds reasonable to me.
from gpb.
I thought some more about it: to keep symmetry between encoding and decoding, this would also mean that on decoding, if the field is not in the binary to decode, then it should be omitted from the decoded result. This means also decoding and merging needs to change accordingly, in the addition to encoding and verification that was already identified. The new (erlang-)internal representation of an unset optional field would be that it is omitted from the map, rather than present and with the value undefined
.
At first, I thought it would be enough to let the encoder just accept both undefined
and the field not being present in the map, but that is no good if one wants decoding to be symmetric, so I think the internal representation really must change. (This is also better in the long run, as discussed previously.) But this means it is a non backwards compatible change, so I think there must first be an option, and on some later announced date or version, we can change the default value of the option.
Since also decoding and merging need to change it'll take some more time, so I'll merge the #28 to master meanwhile, and this will make it into some later release.
from gpb.
Sounds good to me. :)
from gpb.
I thought maybe I should give some update on the progress of this. I have code on a branch. I think think it works, but I faced two issues that has made it slow:
First thing is that the code ended up looking just too ugly, I'll have to dig into it again to try to reduce it into some kind of maintainable state, trying to avoid a case explosion. I have ideas for improvements, that I think are promising, but haven't had much time lately to dive into it.
Second thing is that the maps are getting to a point where they are needing tests. Up until about now, what-ever works with records has surely worked with maps too, since it was only a rendering issue, whether to render a record field update or a map update at generation time, but I think now that it is time for more proper unit testing. The thing here, though, is that I want the unit tests to work out of the box also with a pre-17 Erlang, so will have to invent something to that end.
from gpb.
Sounds good, thanks for the update!
from gpb.
Finally, the code's in better shape, and I've pushed the branch to github, unset-opt-fields-in-maps-omitted
, in case you would want to take it out for a spin. Sorry about the delay.
This introduces a new option {maps_unset_optional, omitted | present_undefined}
(same on the command line, but with dash instead of as a tuple. Default is present_undefined
, but setting it to omitted
will make the generated code behave like in this issue.
In case nothing bad surfaces, I'll merge it to master and push within a few days.
from gpb.
Thanks! I quickly tested out the new branch and everything seems to work as expected. :)
from gpb.
Thanks for quick feedback! Merged into 3.18.0. Closing
from gpb.
Related Issues (20)
- There are many deficiencies HOT 6
- Hitting `no case clause matching: :group_end` in Elixir app using Exprotobuf/gpb HOT 8
- Add preprocessor check around no_underspec? HOT 3
- Optional added back to proto3 HOT 3
- Outdated example HOT 3
- Unset `google.protobuf.StringValue` map values are decoded as empty strings instead of empty values HOT 3
- proposal for performance improvements HOT 9
- Performance improvement for encoding protos with unchanged data HOT 7
- -spec for enum generated code is incorrect HOT 3
- For gpb 5: Drop support for Erlang versions before 19
- How can i call gpb from my rebar.config? HOT 2
- [enhancement] support for gpb text format HOT 1
- I think the generated file is too big HOT 7
- -mapfields-as-maps and -json possible incompability HOT 2
- Trying to ecode a float into a uint64 field results in a badarith exception instead of gpb_type_error HOT 2
- Enums are not defined as macros HOT 7
- Fix for warning on float 0.0 HOT 5
- to_json encodes `uint64` as an integer instead of a string HOT 1
- Add a @generated tag HOT 1
- Excessive File Size in Generated Protobuf Files HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from gpb.