Overview

This page describes Java code generated by protostuff-compiler.

Compiler Invocation

Command Line

Maven Projects

Ant Projects

Gradle Projects

General Rules

  1. Fields cannot be set to null. If you call a setter with value = null, then it throws NullPointerException.
  2. All methods that return collection types never return null.

Compiler Options

Packages

The generated class is placed in a Java package based on the java_package option. If the option is omitted, the package declaration is used instead.

For example, if the .proto file contains:

package foo.bar;

Then the resulting Java class will be placed in Java package foo.bar. However, if the .proto file also contains a java_package option, like so:

package foo.bar;
option java_package = "com.example.foo.bar";

Then the class is placed in the com.example.foo.bar package instead. The java_package option is provided because normal .proto package declarations are not expected to start with a backwards domain name.

Messages

Given a simple message declaration:

message Foo {}

The protostuff-compiler generates a class called Foo, which implements the Message interface. The class is declared final; no further subclassing is allowed.

The Message interface defines single method:

public Schema<T> cachedSchema();

It returns a Schema instance for this class.

Generated Foo class defines the following static methods:

  • public static Foo.Builder newBuilder() - creates a new builder instance (described below).
  • public static Schema<SimpleMessage> getSchema() - returns Schema instance for this class, same as non-static method cachedSchema().

Builders

Classes generated by protostuff-compiler are effectively immutable. It is not possible to change message after it is constructed.

To construct a message object, you need to use a builder. Each message class has its own builder class. In our Foo example, the protostuff compiler generates a nested class Foo.Builder which can be used to build a Foo.

Foo has static method to obtain the builder instance - newBuilder().

Methods that modify the contents of a builder – including field setters – always return a reference to the builder (i.e. they “return this;”). This allows multiple method calls to be chained together in one line.

For example:

builder.mergeFrom(obj)
    .setFoo(1)
    .setBar("abc")
    .clearBaz();

Nested Types

A message can be declared inside another message. For example:

message Foo { 
    message Bar { 
    } 
}

In this case, the compiler simply generates Bar as a static nested class inside Foo.

Fields

Protostuff compiler generates a set of accessor methods for each field defined within the message in the .proto file.

Method names always use camel-case naming, even if the field name in the .proto file uses lower-case with underscores (as it should). The case-conversion works as follows:

  1. For each underscore in the name, the underscore is removed, and the following letter is capitalized.
  2. If the name will have a prefix attached (e.g. “get”), the first letter is capitalized. Otherwise, it is lower-cased.

Thus, the field foo_bar_baz becomes fooBarBaz. If prefixed with get, it would be getFooBarBaz.

Singular Fields

For any of these field definitions:

optional int32 foo = 1;
required int32 foo = 1;

The compiler will generate the following accessor methods in the message class:

  • boolean hasFoo(): Returns true if the field is set.
  • int getFoo(): Returns the current value of the field. If the field is not set, returns the default value.

The compiler will generate the following methods only in the message’s builder:

  • Builder setFoo(int value): Sets the value of the field. After calling this, hasFoo() will return true and getFoo() will return value.
  • Builder clearFoo(): Clears the value of the field. After calling this, hasFoo() will return false and getFoo() will return the default value.

For other simple field types, the corresponding Java type is chosen according to the scalar value types table. For message and enum types, the value type is replaced with the message or enum class.

Repeated Fields

For this field definition:

repeated int32 foo = 1;

The compiler will generate the following accessor methods in both the message class and its builder:

  • int getFooCount(): Returns the number of elements currently in the field.
  • int getFoo(int index): Returns the element at the given zero-based index. List<Integer> getFooList(): Returns the entire field as a list. If the field is not set, returns an empty list. The returned list is immutable for message classes and unmodifiable for message builder classes.

The compiler will generate the following methods only in the message’s builder:

  • Builder setFoo(int index, int value): Sets the value of the element at the given zero-based index.
  • Builder addFoo(int value): Appends a new element to the field with the given value.
  • Builder addAllFoo(Iterable<? extends Integer> value): Appends all elements in the given Iterable to the field.
  • Builder clearFoo(): Removes all elements from the field. After calling this, getFooCount() will return zero.

For other simple field types, the corresponding Java type is chosen according to the scalar value types table. For message and enum types, the type is the message or enum class.

Oneof Fields

For this oneof field definition:

oneof oneof_name {
    int32 foo = 1;
    ...
}

The compiler will generate the following accessor methods in both the message class and its builder:

  • boolean hasFoo(): Returns true if the oneof case is FOO.
  • int getFoo(): Returns the current value of oneof_name if the oneof case is FOO. Otherwise, returns the default value of this field.

The compiler will generate the following methods only in the message’s builder:

  • Builder setFoo(int value): Sets oneof_name to this value and sets the oneof case to FOO. After calling this, hasFoo() will return true, getFoo() will return value and getOneofNameCase() will return FOO.
  • Builder clearOneofName(): Sets oneof_name to null and the oneof case to ONEOF_NAME_NOT_SET. After calling this, hasFoo() will return false, getFoo() will return the default value and getOneofNameCase() will return ONEOF_NAME_NOT_SET.

For other simple field types, the corresponding Java type is chosen according to the scalar value types table. For message and enum types, the value type is replaced with the message or enum class.

Map Fields

For this map field definition:

map<int32, int32> weight = 1;

The compiler will generate the following accessor methods:

  • Map<Integer, Integer> getWeightMap(): Returns an unmodifiable Map.
  • Integer getWeight(Integer key): Returns a value mapped to given key if it exists. If mapping does not exist than returns null.

The compiler will generate the following methods for constructing new message:

  • MessageT putWeight(Integer key, Integer value): Adds a mapping for given key and value pair.
  • MessageT putAllWeight(Map<Integer, Integer> map): Adds all mappings from the given map.

Oneof

Enumerations

Extensions

Extensions are not supported.

Services