Comments (5)
It would be relatively easy to add this kind of type-specific defaults, but just adding it straight off would also mean that it would be impossible to see if an optional message is not present. The (C++, Java, Python) classes generated from google's protobuf all have a has_xyz()
method for each field, so there it is possible to tell. For gpb, one corresponding approach could be to add similar has_xyz
fields, but I would not like that at all: doubling the record/map size, decreasing performance. I have not found a way that both looks nice, makes it possible to see if optional fields are present or not, and does not decrease performance, but ideas are welcome, of course, but until then, I'm not about to add type-specific defaults.
from gpb.
The ruby gem I have used for protobuf related things handles this by creating two methods with different semantics. So for optional uint32 age
it would generate two methods like this:
decoded.name # => 0
decoded.name! # => nil
The method name with the bang appended gives you the semantics where you can see the nil
and the method without the bang follows the protobuf specification.
Not sure if that is helpful or not, but after using that gem in production for several years I still find this to be a good tradeoff.
from gpb.
Thanks @mmmries, this is good food for thought. Continuing along those lines, but for gpb, there could be some alternatives:
- make two record fields for every optional proto message field, one which has the value
undefined | value()
as it is in gpb today, and the other which has the default (or type default) value. But I'm not very keen on adding extra fields to the record, mostly for performance reasons, so another idea is to: - generate a function
default_<Msg>_<field>()
for for every such optional field, or perhaps to: - generate a function
defaultify/1
which would take a message, and set the default value for every non-set optional field (recursively), so one could callX:defaultify(X:decode_msg(Bin))
.
@yizhenfei, could you describe your use case a bit, for me to get a better understanding? If a use case is only to simply retrieve a default value specified in the proto file, then the generated introspection function might perhaps(?) provide what you need already:
If you have a proto file like this:
message m1 {
optional uint32 f2 = 2 [default=333];
}
then gpb will generate a function like this:
find_msg_def(m1) ->
[#field{name = f2, fnum = 2, rnum = 2, type = uint32,
occurrence = optional, opts = [{default, 333}]}];
from gpb.
- what should be the default value for an optional ENUM type ?
- what should be the default value for an optional field that is also a protocol buffer ?
- for performance reasons, it might make sense to have undefined's. If you have a message with 200 optional fields, if for example you write them to a database and read them back, having undefined for all of them would save a lot of space : if we typecast undefined to each field's underlying type (assuming we find a way to do that - see my previous two questions !) then we will write in the db some default values - so when we read them back we WILL interpret them as valid fields and we WILL try to encode them into a protocol buffer. So, for encoding, "optional uint32 bla = 2;" encoded as 0 takes some bytes (or thereabout) whereas encoded as undefined takes close to 0 bits (since the protocol buffer encoder has to encode has_bla = NO).
Please don't typecast undefined's - pretty please, with a cherry on top ?
from gpb.
@ionuthristodorescu, Good points. I'm going to close this as won't fix.
At the moment, it looks like the need for getting type-specific default values does not warrant the effort, but should things change, it is always possible to add this later on, for example by generating a defaultify(Msg)
function, or perhaps similar. In any case, the current behaviour of decoding unset optional fields to undefined
will not be changed.
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.