Skip to content
/ puregen Public

Define your data structures and services once, then generate consistent, type-safe code across multiple languages and platforms.

License

Notifications You must be signed in to change notification settings

nnanto/puregen

Repository files navigation

puregen - Protobuf Code Generator

puregen is a protobuf plugin that generates simple, dependency-minimal code for Go, Java, and Python from .proto files. The generated code focuses on simplicity and uses built-in language features rather than heavy dependencies.

puregen is ideal for projects that need simple, readable generated code without heavy protobuf runtime dependencies, with the flexibility to use any transport mechanism (HTTP, gRPC, message queues, etc.).

Comparison with Standard Generators

Feature puregen protoc-gen-go protoc-gen-java
Dependencies Minimal protobuf runtime protobuf runtime
Code size Small Large Large
JSON support Built-in Requires jsonpb Requires additional libs
Transport abstraction Pluggable gRPC only gRPC only
Customization Easy Complex Complex
Learning curve Low Medium Medium

Features

  • Multi-language support: Generate code for Go, Java, and Python
  • Minimal dependencies: Uses only built-in libraries and standard patterns
  • Simple data structures: Generated classes/structs are easy to understand and modify
  • JSON serialization: Built-in JSON marshaling/unmarshaling support
  • Service interfaces: Clean interface definitions for RPC services
  • Comprehensive directive support: Customize code generation with puregen:generate and puregen:metadata directives for default values, enum types, HTTP routing, database mapping, validation, UI configuration, etc. See details
  • Client generation: Ready-to-use clients with pluggable transport. See details

Installation

Prerequisites

Build the Plugin

Pre-built Binaries (Recommended)

You can download pre-built binaries for your platform from the releases page.

curl -L https://github.com/nnanto/puregen/releases/download/latest/protoc-gen-puregen-linux-amd64.tar.gz | tar -xz
          sudo mv protoc-gen-puregen-* /usr/local/bin/protoc-gen-puregen

# Or for macOS
curl -L https://github.com/nnanto/puregen/releases/download/latest/protoc-gen-puregen-darwin-amd64.tar.gz | tar -xz
sudo mv protoc-gen-puregen-* /usr/local/bin/protoc-gen-puregen

# Run the generator
protoc --puregen_out=./examples/generated --puregen_opt=language=python examples/proto/*.proto

From Source

# Clone the repository
git clone https://github.com/nnanto/puregen
cd puregen

# Build the plugin
go build -o protoc-gen-puregen ./cmd/protoc-gen-puregen

# Make it available in your PATH (optional)
sudo mv protoc-gen-puregen /usr/local/bin/

Usage

Basic Generation

Generate code for all supported languages:

protoc --puregen_out=./generated --puregen_opt=language=all user.proto

Generate code for a specific language:

# Go only
protoc --puregen_out=./generated --puregen_opt=language=go user.proto

# Java only
protoc --puregen_out=./generated --puregen_opt=language=java user.proto

# Python only
protoc --puregen_out=./generated --puregen_opt=language=python user.proto

Example Proto File

syntax = "proto3";

package example.v1;

option go_package = "github.com/nnanto/puregen/examples/proto/gen/go";
option java_package = "com.example.proto.v1";

// User represents a user in the system
// puregen:metadata: {"table": "users", "cache": "true"}
message User {
  int32 id = 1;
  // puregen:generate: {"value": "Anonymous"}
  string name = 2;
  string email = 3;
  // Default to active status
  // puregen:generate: {"value": "true"}
  bool is_active = 4;
  UserProfile profile = 5;
  UserStatus status = 6;
}

// UserProfile contains additional user information
message UserProfile {
  // Default bio for new users
  // puregen:generate: {"value": "No bio provided"}
  string bio = 1;
  string avatar_url = 2;
  int64 created_at = 3;
}

// Status enum with integer generation
// puregen:generate: {"enumType": "int"}
// puregen:metadata: {"validation": "required", "default": "ACTIVE"}
enum UserStatus {
  USER_STATUS_UNKNOWN = 0;
  USER_STATUS_ACTIVE = 1;
  USER_STATUS_INACTIVE = 2;
}

// CreateUserRequest is the request message for creating a user
message CreateUserRequest {
  string name = 1;
  string email = 2;
  UserProfile profile = 3;
}

message CreateUserResponse {
  User user = 1;
  string message = 2;
}

message GetUserRequest {
  int32 id = 1;
}

message GetUserResponse {
  User user = 1;
}

service UserService {
  // CreateUser creates a new user
  // puregen:metadata {"method":"POST", "path":"/users"}
  rpc CreateUser(CreateUserRequest) returns (CreateUserResponse);

  // GetUser retrieves a user by ID
  // puregen:metadata {"method":"GET", "path":"/users/{id}"}
  rpc GetUser(GetUserRequest) returns (GetUserResponse);
}

Using the Generated Code

As Models Only

Simple data structures with validation and serialization

As Server Implementation

Service implementations with HTTP endpoints

As Client with Custom Transport

Client libraries with pluggable transport

You can define custom transports for different protocols (HTTP, gRPC, etc.) by implementing the Transport interface in each language. Example: Name-Based Routing Transport

Generated Code Features

Go

  • Struct definitions with JSON tags
  • Constructor functions (NewMessageName())
  • Validation methods
  • JSON serialization (ToJSON(), FromJSON())
  • Service interfaces with default implementations
  • Clients with pluggable Transport interface

Java

  • POJO classes with Jackson annotations
  • Builder pattern support
  • Getters and setters
  • JSON serialization methods
  • Service interfaces with default implementations
  • Clients with generic Transport interface

Python

  • Dataclasses with type hints
  • JSON serialization support
  • Validation methods
  • Service abstract base classes
  • Clients with abstract Transport base class

Testing the Plugin

Test with the provided example:

# Generate code for the example proto file
cd examples
protoc --puregen_out=./generated --puregen_opt=language=all proto/user.proto

# Check the generated files
ls -la generated/

Development

Project Structure

├── cmd/protoc-gen-puregen/   # Main plugin entry point
├── internal/generator/         # Code generation logic
│   ├── go.go                  # Go code generator
│   ├── java.go                # Java code generator
│   └── python.go              # Python code generator
├── examples/                   # Example proto files and usage
└── README.md

Adding New Language Support

  1. Create a new generator file in internal/generator/
  2. Implement the GenerateXXXFile function
  3. Add the language option to the main plugin

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Submit a pull request

License

MIT License - see LICENSE file for details.

About

Define your data structures and services once, then generate consistent, type-safe code across multiple languages and platforms.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published