Skip to content

Protoc plugin for generating field mask utilities in Go

License

Notifications You must be signed in to change notification settings

TheThingsIndustries/protoc-gen-go-fieldmask

Repository files navigation

protoc-gen-go-fieldmask

Protoc plugin for generating fieldmask-aware methods for proto messages in Go

Background

The Things Stack works a lot with fieldmasks. This plugin generates methods that help us work with those field masks:

  • A FieldPaths method that lets us get the full list of field paths supported by the message (and its sub-messages).
    For a specific message: (thethings.fieldmask.message) = { field_paths: true }
    For the entire file: option (thethings.fieldmask.file) = { field_paths_all: true }
  • A NormalizeFieldPaths method that lets us normalize a list of field paths for the message.
    For a specific message: (thethings.fieldmask.message) = { field_path_normalizer: true }
    For the entire file: option (thethings.fieldmask.file) = { field_path_normalizer_all: true }
  • A SetFields method that lets us set fields specified by such a field mask from a source struct into a destination struct.
    For a specific message: (thethings.fieldmask.message) = { field_setter: true }
    For the entire file: option (thethings.fieldmask.file) = { field_setters_all: true }

Usage in Proto Code

syntax = "proto3";

import "github.com/TheThingsIndustries/protoc-gen-go-fieldmask/annotations.proto";

package thethings.fieldmask.example;

option go_package = "github.com/TheThingsIndustries/protoc-gen-go-fieldmask/example";

option (thethings.fieldmask.file) = {
  field_paths_all: true,             // Generate FieldPaths methods for everything in the file.
  field_path_normalizer_all: true,   // Generate field path normalizers for everything in the file.
  field_setters_all: true,           // Generate field setters for everything in the file.
};

message SomeMessage {
  string some_field = 1;
  string other_field = 2;
}

message MessageWithoutFieldPathsMethod {
  option (thethings.fieldmask.message) = { field_paths: false };

  string some_field = 1;
}

message MessageWithoutFieldSetter {
  option (thethings.fieldmask.message) = { field_setter: false };

  string some_field = 1;
}

message MessageWithoutFieldPathNormalizer {
  option (thethings.fieldmask.message) = { field_path_normalizer: false };

  string some_field = 1;
}

Generating Go Code

$ protoc -I ./path/to -I . \
  --go_opt=paths=source_relative --go_out=./path/to \
  --go-fieldmask_opt=paths=source_relative --go-fieldmask_out=./path/to \
  ./path/to/*.proto

Usage in Go Code

dst := &SomeMessage{
  SomeField: "some value",
  OtherField: "other value",
}

src := &SomeMessage{
  SomeField: "new value",
  OtherField: "skipped value",
}

var src, dst *SomeMessage

normalizedPaths, err := dst.NormalizeFieldPaths("some_field")
if err != nil {
  return err
}

if err = dst.SetFields(src, normalizedPaths); err != nil {
  return err
}

Contributing

We do not accept external issues with feature requests. This plugin only supports what we actually use ourselves at The Things Industries.

We do not accept external pull requests with new features, but everyone is free to fork it and add features in their own fork.

We do accept issues with bug reports and pull requests with bug fixes.

About

Protoc plugin for generating field mask utilities in Go

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •