-
Notifications
You must be signed in to change notification settings - Fork 80
Generated code
ScalaBuff generates a single top-level object with some useful methods for each proto file that has the same name (only CamelCased) as that proto file itself by default; this can be overriden by the top-level java_outer_classname
option, like so:
option java_outer_classname = "MyClass";
All the generated case classes, companion objects and the top-level object will be placed in package that was declared in the input proto file. If the java_package
top-level option is used, then the object will be placed in that package instead:
option java_package = "com.author.project";
For each Message found in the input proto file, a final, immutable case class and a companion object are generated; the case class has a constructor allowing users to set all available fields at construction time; however, you don't have to set any of the fields to construct a proper Message. Unlike the Java generated classes, required fields are always counted as set and required fields are initialized to their default values if not initialized by the user in the constructor. This means that the Message is always in an initialized and ready to be serialized state. Optional fields must be wrapped in an Option
, and repeated fields must be Vector
s of the appropriate type.
The generated messages can be optimized either for speed (default) or small code size, by setting the optimize_for
top-level option:
option optimize_for = SPEED; // default
option optimize_for = CODE_SIZE;
If optimizing for code size, methods may require more time and/or memory to complete, but the generated classes will be smaller.
Since Message classes are immutable, each "mutator" operation returns a new Message instance. Therefore, it is more efficient to set all needed fields in the constructor than call setter methods.
A default instance of each message is provided, accessed by either defaultInstance
or getDefaultInstance
. It has all fields (including required fields) set to their default values, and is identical to simply constructing a new message with no fields set.
Each field contained in the input proto file is a val
in the generated case class, which means it is immutable and can be accessed by simply using it as a normal class field. Additionally, each optional field has a corresponding getOptionalField
method, which returns the field itself instead of the field wrapped in Option
; optional Enum types don't have such methods as they don't have a default value.
Field names are CamelCased, so my_field in the proto file becomes myField. In addition, each field has its own field number integer constant in the companion object, which is upper cased and has _FIELD_NUMBER
appended to the constant name.
Fields cannot be mutated directly, so mutator methods are defined for each optional and repeated field, each of which returns a new instance which is identical in every way, except for the mutated field. Also, copy() may be used, but for optional and repeated fields it's easier to use the generated setters.
Since any field can be updated and a new instance acquired via the case class copy()
method, there are no traditional Java-style setters; however, each optional field receives its own setField method, so that you don't need to wrap the optional field in a Some, as would be required in the copy()
method.
If trying to access a required field that has not been manually initialized (whether in the constructor or via a setter mutator), the default value for that field is returned. Uninitialized optional fields have None as their value, so if you want their default value, call getOptionalField instead of accessing them directly.
Additionally, it's possible to clear a required or optional field to its default value by calling clearField; it will return a new instance with the specified field reset to its default value. Note that the message is still fully initialized even if a field is cleared.
Each repeated field has a number of methods:
-
setField(index, value)
: Returns a new instance that has the repeated field mutated so that the specifiedindex
is set tovalue
. -
addField(value)
: Returns a new instance that has the repeated field mutated so thatvalue
is added. -
addAllField(value1, value2, ...)
: Returns a new instance that has the repeated field mutated so that all the specifiedvalues
are added. -
addAllField(collection)
: Returns a new instance that has the repeated field mutated so that all the values in the specifiedcollection
are added;collection
must be a subtype ofTraversableOnce
.
Instead of Scala's default Enumeration
s, ScalaBuff generates classes that extend from an adaptation of Viktor Klang's Enum class (it can be found in the hr.sandrogrzicic.scalabuff.runtime
package). The type of an enumeration value is EnumerationName.EnumVal
which has fields for the field number and the value name. In addition to the EnumVals, each enumeration value also has its own field number integer constant inside the enumeration object, which is upper cased and has _VALUE
appended to the constant name.
A valueOf(number) method is provided which returns an EnumVal satisfying the specified field number, as well as an internalGetValueMap class that has the findValueByNumber(number) method with identical behavior as the valueOf(number) method.
ScalaBuff currently doesn't support extensions.
ScalaBuff currently doesn't support groups.
ScalaBuff currently doesn't support services.