google-code-export / protobuf

Automatically exported from code.google.com/p/protobuf
Other
1 stars 1 forks source link

Default values are not assumed to be filled in. #249

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Create a protocol buffer file with a required field that has a default value.
2. Compile this protocol buffer, and attempt to make a new protocol buffer via 
the builder, i.e. newBuilder().build()
3. A runtime exception will be thrown(Java), not sure what happens in other 
languages.

What is the expected output? What do you see instead?
Even if no required fields are explicitly set when creating the protocol 
buffer, since the fields have default values you should not have to set the 
values of the fields.  Instead, an exception is thrown because the fields, 
while they have a default value, have not explicitly been set in user-level 
code.

What version of the product are you using? On what operating system?
2.3.0, Linux(Ubuntu)

Please provide any additional information below.
Example:
message Information{
required string text = 1 [default = "hello"];
}

//pseudo-code below
main(){
Information protocol = Information.newBuilder().setText("google").build(); 
//works
Information protocol = Information.newBuilder().build(); //required fields are 
not set, an exception is raised.
}

Original issue reported on code.google.com by osfan6...@gmail.com on 8 Dec 2010 at 8:54

GoogleCodeExporter commented 9 years ago
This is a common point of confusion. required means a field must be explicitly 
set. "default" allows you to specify the value you get if the field is not 
explicitly set, and is orthogonal to required and optional.

Original comment by jas...@google.com on 8 Dec 2010 at 8:59

GoogleCodeExporter commented 9 years ago
Ah.  Well I haven't seen any information which ever said that; the 
documentation is rather lacking in that regard.

It would be nice to have this as an option though.  The amount of code required 
is rather trivial.

Original comment by osfan6...@gmail.com on 9 Dec 2010 at 2:00

GoogleCodeExporter commented 9 years ago
The behavior and documentation seem clear to me: "required" means the user must 
set it to something (i.e. it is required).  Why would making your field 
"optional" not meet your needs?

Original comment by mdpo...@troilus.org on 9 Dec 2010 at 5:23

GoogleCodeExporter commented 9 years ago
We're using protocol buffers to store user settings, so we want some fields to 
be required(for data validation purposes).  However, when we first generate the 
data we want there to be some default value for these settings, so that we can 
have default settings already filled in automatically.  

I could be wrong, but I think that even if I made the field 'optional', and 
immediately built the protocol buffer, no information would be set by default.

Or, to put it another way:
When making a protocol buffer, you don't always want ALL fields to be set, 
however some fields MUST have a  value.  If no user-value is defined, then the 
default value is used for that field.  For example, if you use a JOptionPane to 
show the user some information, you don't always want to give the user OK and 
Cancel buttons, because they're not relevant.  However, you always have a 
Component and a Message as parameters.  If nothing else is provided, then the 
defaults for the other settings(icon, title, ok/cancel) buttons are set to the 
default(none).  

Original comment by osfan6...@gmail.com on 9 Dec 2010 at 5:48

GoogleCodeExporter commented 9 years ago
It sounds like there is still some confusion over the meaning of "set."

It is always legal to access a field from a protobuf, whether it is explicitly 
set or not.  Using a default value with option, it is true that no information 
would be "set" by default, but I don't think you care: the default value 
provides a way of specifying what value is returned when the value is not 
explicitly set.
e.g.:

message MyProto {
  optional string foo = 1 [ default = "some value" ];
}

MyProto bar;
assert(!bar.has_foo());
assert(bar.foo() == "some value");

The above assertions succeed. The value foo is not explicitly set but accessing 
the field returns the default. This sounds like what you want.

If you change the field to required, then that means when serializing and 
parsing messages, that field must be explicitly set. It sounds like the data 
validation you have depends on the use-case - you should really do such 
validation at the application level, rather than using the required mechanism. 
In fact, many people (myself included) advocate not using required at all.

If you want to continue this discussion let's do so on the groups mailing list: 
protobuf@googlegroups.com

Original comment by jas...@google.com on 9 Dec 2010 at 8:24