protostuff-compiler
protostuff-compiler copied to clipboard
Custom default values for fields
I have this message:
message SomeMessage {
message SomeInnerMessage {
optional string someField = 1 [default = "some_value"];
optional string someOtherField = 2 [default = "some_other_value"];
required string parameter1 = 3;
required string parameter2 = 4;
}
...
}
Compiler generates this code:
...
public static final class SomeInnerMessage
implements io.protostuff.Message<Request> {
private static final Request DEFAULT_INSTANCE = newBuilder().build();
private String someField;
private String someOtherField;
private String parameter1;
private String parameter2;
private boolean __merge_lock = false;
private int __bitField0;
private SomeInnerMessage() {
this.someField = "";
this.someOtherField = "";
this.parameter1 = "";
this.parameter2 = "";
}
...
}
...
There are neither default initializers for fields someField, someOtherField for private constructor nor for SomeInnerMessage.Builder private constructor. How to generate classes with default fields values?
Actually it does. However, fields are not initialized in constructor directly.
There are 3 ways to create a message:
- Use
Message.getDefaultInstance()- this one will be initialized with private constructor without parameters. - Use
Message.newBuilder().build()- this one will be initialized with builder'sbuild()method. - Use
ProtobufIOUtil.mergeFrom(...)- this one will be initialized by schema, when it will finish reading all the data from input.
Please check full source of the generated class. It is similar to classes generated by google's protoc, but adjusted to work with protostuff library.
If you are not sure - I recommend you to write a unit test to double-check that there is default value, something like https://github.com/protostuff/protostuff-compiler/blob/master/protostuff-it/src/test/java/io/protostuff/it/java/ScalarTest.java or https://github.com/protostuff/protostuff-compiler/blob/master/protostuff-it/src/test/java/io/protostuff/it/java/MessageTest.java.
The default values are (zero values, -1 for enums, and empty strings), but these are not the ones that one would like to have.
The Message.getDefaultInstance() and Message.newBuilder().build() ways not generates default values from .proto file. ProtobufIOUtil.mergeFrom(...) methods requires source with initialized fields. In the above tests, you initialize each field manually. I have this example message:
message LogoutClient {
message Request {
optional string path = 1 [default = "/logout"];
optional string method = 2 [default = "delete"];
}
message Response {
}
}
And generated code for this message. There are no default values ("/logout" and "delete" for fields path and method respectively) for fields in the Builder's and Message's constructors.
Can I create an object instance without having other initialized messages objects with default fields values from field's extensions default in the .proto file as from code that protoc generates? Or CLI has limited functionality?
Sorry, I misinterpreted issue description.
You are right, custom default values are not supported. protostuff-generator ignores values for default option.
I cannot say when I can implement support for custom default values, as currently I'm quite busy with https://github.com/protostuff/protobuf-jetbrains-plugin.
If you are willing to help, I will gladly accept pull request.