Prutal

Protobuf’s non-generated code serialisation library

Abstraction

Starting from v0.13.0, Kitex will use its own Prutal implementation to replace Protobuf’s protoc and protoc-gen-go for code generation and serialisation.

Kitex will no longer need to install protoc, protoc-gen-go. New users will not be aware of the change.

Prutal is compatible with the existing Protobuf in terms of serialisation, and generates code that is very compact, has no extra code, and has better serialisation performance than the official one.

Technically Prutal and Frugal are similar to the use of struct tags and efficient reflection to achieve serialisation, and does not rely on redundant generation code.

Currently open source, the specific implementation and subsequent benchmark data can be viewed: https://github.com/cloudwego/prutal

Using Advices

Initially, it is not recommended that users use Prutal directly, and currently only promises forward and backward compatibility with Prutal integration in Kitex.

If you find any problems while using Kitex, you can fallback to Protobuf using the environment variable KITEX_TOOL_USE_PROTOC

KITEX_TOOL_USE_PROTOC=1 kitex --version

In the future, Kitex will deprecate the protoc implementation.

It is recommended that if you encounter problems with usage, you can provide feedback to help improve it.

Kitex Tool Updates

Since protoc is no longer used as the default code generation tool, the following arguments will be deprecated:

--protobuf

--protobuf-plugin

These two arguments are mainly used for passthrough to protoc, and are not actually used by Kitex itself. If they are still specified, an error will be reported:

[ERROR] invalid value ‘xxx’ for flag -protobuf: flag is deprecated
[ERROR] invalid value ‘xxx’ for flag -protobuf-plugin: flag is deprecated

Users can call protoc and related plugins for code generation if they want. Instead of relying on Kitex to call protoc.

Due to the complexity of generating paths in older protoc implementations, the following arguments do not work in older implementations:

-gen-path

which defaults to kitex_gen, has been fixed in the new Prutal.

Prutal and Protobuf compatibility issues

Kitex uses Prutal to generate code by default.

If the user does Marshal / Unmarshal directly from the protobuf library, the new Kitex will generate code with a compile-time error:

cannot use &YourRequest{} (value of type *YourRequest) as protoreflect.ProtoMessage value in argument to proto.Marshal: *YourRequest does not implement protoreflect.ProtoMessage (missing method ProtoReflect)

This is because the Protobuf library is strongly bound to the Protobuf generation code, and Protobuf needs to generate a lot of binary data to assist its reflection implementation.

It is recommended to use the github.com/cloudwego/prutal package directly.

// MarshalAppend appends the protobuf encoding of v to b and returns the new bytes
func MarshalAppend(b []byte, v interface{}) ([]byte, error)

// Unmarshal parses the protobuf-encoded data and stores the result in the value pointed to by v.
func Unmarshal(b []byte, v interface{}) error

Prutal is compatible with Protobuf generated code. So even if the original code was generated by the official Protobuf, you can use Prutal to serialise it for better performance.

Since Protobuf is complex and has a lot of features, Prutal can’t guarantee 100% compatibility, so if you find any problems, please feel free to pull an issue.

Feedback to us

If you have any questions, you can submit an issue to Prutal for feedback.