Jprotobuf Generate .proto
Introduction
Jprotobuf provides a simplified way to use Google Protocol Buffers with equivalent performance. With jprotobuf, you do not need to learn proto file operations or syntax. You can define field types directly with Java annotations.
This module enhances jprotobuf in the following ways:
- Multiple objects can be generated into the same
.protofile. - You can omit jprotobuf field annotations for further simplification.
How to Install
This is an optional module. Add it to pom.xml when needed.
see https://central.sonatype.com/artifact/com.iohao.net/extension-jprotobuf
<dependency>
<groupId>com.iohao.net</groupId>
<artifactId>extension-jprotobuf</artifactId>
<version>${ionet.version}</version>
</dependency>
How to Generate .proto
Via Utility Class
Add the package names to scan. The default output directory for .proto files is target/proto.
void test1() {
GenerateFileKit.generate("com.iohao.example.sdk.logic.data");
}
Via ProtoGenerateFile
- code 3: specify the proto output directory. If omitted, the default is
target/proto. - code 4: add the package names to scan.
- code 6: generate the
.protofile.
void test2() {
var protoGenerateFile = new ProtoGenerateFile()
.setGenerateFolder(path)
.addProtoPackage("com.iohao.example.sdk.logic.data");
protoGenerateFile.generate();
}
Multi-Module On-Demand Generation
- code 6: specify the proto output directory. If omitted, the default is
target/proto. - code 7~9: add the package names to scan.
- code 10: generate the
.protofile.
void test2() {
String generateFolder = "/Users/join/gitme/game/MyGames/proto";
var protoPackageList = List.of("com.iohao.happy.robot", "com.iohao.happy.email");
var protoGenerateFile = new ProtoGenerateFile()
.setGenerateFolder(generateFolder)
.addProtoPackage(protoPackageList)
.addProtoPackage("com.iohao.happy.common.provide.proto");
protoGenerateFile.generate();
}
ProtoFileMerge Annotation
The ProtoFileMerge annotation has two attributes:
- fileName: specifies the
.protofile name. - filePackage: specifies the
.protopackage name.
You must add this annotation to a class to generate it into a .proto file.
Usage Example
We now define three classes, also called protocol data classes, for communication between the client and server.
Data Protocol Classes
Protocol data classes require two annotations:
- ProtobufClass: marks a class as a protocol data class.
- ProtoFileMerge: provides metadata required for
.protogeneration.
public interface TempProtoFile {
String fileName = "common.proto";
String filePackage = "pb.common";
}
/**
* MyFood
*/
@ProtobufClass
@FieldDefaults(level = AccessLevel.PUBLIC)
@ProtoFileMerge(fileName = TempProtoFile.fileName, filePackage = TempProtoFile.filePackage)
public class Food {
/** id */
int id;
/** food name */
String foodName;
}
/**
* My Cat
*/
@ProtobufClass
@FieldDefaults(level = AccessLevel.PUBLIC)
@ProtoFileMerge(fileName = TempProtoFile.fileName, filePackage = TempProtoFile.filePackage)
public class Cat {
/** id */
int id;
/** cat name */
String catName;
/** the food */
Food food;
/** the animalType */
AnimalTypeEnum animalType;
}
@ProtobufClass
@ProtoFileMerge(fileName = TempProtoFile.fileName, filePackage = TempProtoFile.filePackage)
public enum AnimalTypeEnum implements EnumReadable {
/** the cat */
cat(0),
/** the tiger */
tiger(10),
;
final int value;
AnimalTypeEnum(int value) {
this.value = value;
}
@Override
public int value() {
return this.value;
}
}
Generated .proto File
The protocol data is generated into common.proto as shown below.
The structures in common.proto contain comments generated from the Java classes above, keeping the code and documentation aligned.
syntax = "proto3";
package pb.common;
// TestAnimalTypeEnum
enum AnimalTypeEnum {
// the cat
cat = 0;
// the tiger
tiger = 10;
}
// MyCat
message Cat {
// id
int32 id = 1;
// cat name
string cat_name = 2;
// the food
Food food = 3;
// the animalType
AnimalTypeEnum animal_type = 4;
}
// MyFood
message Food {
// id
int32 id = 1;
// food name
string food_name = 2;
}
Enum
Default Enum Values
Enum values start from 0 by default.
/**
* The AnimalType
*/
@ProtobufClass
@ProtoFileMerge(fileName = MyProtoFile.fileName, filePackage = MyProtoFile.filePackage)
public enum AnimalType {
/** the bird */
BIRD,
/** the cat */
CAT;
}
/**
* The Animal
*/
@ProtobufClass
@FieldDefaults(level = AccessLevel.PUBLIC)
@ProtoFileMerge(fileName = MyProtoFile.fileName, filePackage = MyProtoFile.filePackage)
public class Animal {
/** id */
int id;
/** AnimalType */
AnimalType animalType;
}
syntax = "proto3";
package common;
// The Animal
message Animal {
// id
int32 id = 1;
// AnimalType
AnimalType animal_type = 2;
}
// The AnimalType
enum AnimalType {
// the bird
BIRD = 0;
// the cat
CAT = 1;
}
Custom Enum Values
Custom enum values require implementing the EnumReadable interface.
@ProtobufClass
@ProtoFileMerge(fileName = TempProtoFile.fileName, filePackage = TempProtoFile.filePackage)
public enum AnimalTypeEnum implements EnumReadable {
/** the cat */
cat(0),
/** the tiger */
tiger(10),
;
final int value;
AnimalTypeEnum(int value) {
this.value = value;
}
@Override
public int value() {
return this.value;
}
}
syntax = "proto3";
package common;
// TestAnimalTypeEnum
enum AnimalTypeEnum {
// the cat
cat = 0;
// the tiger
tiger = 10;
}
Field Naming Style
Generated .proto field names use UnderScoreCase by default.
syntax = "proto3";
package common;
// food
message Food {
// id
sint32 id = 1;
// food name
string food_name = 2;
}
Developers can also customize the generated naming style, as shown below, to use the same names as Java fields.
ProtoGenerateSetting.setFieldNameFunction(FieldNameGenerate::getFieldName);
syntax = "proto3";
// MyFood
message Food {
// id
int32 id = 1;
// food name
string foodName = 2;
}
Notes and Considerations
Protocol data classes require two annotations:
- ProtobufClass: marks a class as a protocol data class.
- ProtoFileMerge: provides metadata required for
.protogeneration.
@ProtobufClass
@ProtoFileMerge(fileName = TempProtoFile.fileName, filePackage = TempProtoFile.filePackage)
public class Food {
...
}
Supported types: See https://github.com/jhunters/jprotobuf/blob/master/Document.md