Socket
Socket
Sign inDemoInstall

github.com/searKing/golang/tools/cmd/protoc-gen-go-tag

Package Overview
Dependencies
Alerts
File Explorer
Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

github.com/searKing/golang/tools/cmd/protoc-gen-go-tag


Version published
Created
Source

Build Status GoDoc Report card Sourcegraph

protoc-gen-go-tag

Generates Go code using a package as a tag rewriter that enhanced protoc-gen-go.

protoc-gen-go-tag Generates Go code using a package as a tag rewriter that enhanced protoc-gen-go.

The file xxx.pb.go is modified by protoc-gen-go based on xxx.proto. It has helpful defaults designed for use with protobuf with custom struct tags.

For example, given this snippet,

apply this proto file

syntax = "proto3";

package pb;

//import "google/protobuf/descriptor.proto";
import "github.com/searKing/golang/tools/protoc-gen-go-tag/tag/tag.proto";

message Http{
  string protocol = 1;
  string version = 2[json_name = "Url", (google.protobuf.field_tag) = {struct_tag: "validate:\"gte=0,lte=130\""}];;
  Url url = 3[json_name = "Url", (google.protobuf.field_tag) = {struct_tag: "json:\"url_tag,omitempty\""}];
  message Url {
    string scheme = 1[json_name = "Scheme", (google.protobuf.field_tag) = {struct_tag: "json:\"schema_tag,omitempty\""}];
    //  string scheme = 1[json_name = "Scheme"];
  }
}

running this command

# https://github.com/searKing/golang/blob/master/tools/protoc-gen-go-tag/tag/tag.proto
# `tag.proto` needs to be on the `protoc` include path 
protoc -I . --go-tag_out=paths=source_relative:. *.proto

in the same directory will create the file pill.pb.go, containing

// Code generated by protoc-gen-go-tag. DO NOT EDIT.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.27.1
// 	protoc        v3.17.3
// source: example.proto

package pb

import (
  _ "github.com/searKing/golang/tools/protoc-gen-go-tag/tag"
  protoreflect "google.golang.org/protobuf/reflect/protoreflect"
  protoimpl "google.golang.org/protobuf/runtime/protoimpl"
  reflect "reflect"
  sync "sync"
)

const (
  // Verify that this generated code is sufficiently up-to-date.
  _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  // Verify that runtime/protoimpl is sufficiently up-to-date.
  _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

type Http struct {
  state         protoimpl.MessageState
  sizeCache     protoimpl.SizeCache
  unknownFields protoimpl.UnknownFields

  Protocol string `protobuf:"bytes,1,opt,name=protocol,proto3" json:"protocol,omitempty" validate:"oneof=http https"`
  // version_default is the same as version_update
  VersionDefault string    `protobuf:"bytes,2,opt,name=version_default,json=VersionDefault,proto3" json:"version_with_default,omitempty" validate:"gte=0,lte=130"`
  VersionUpdate  string    `protobuf:"bytes,3,opt,name=version_update,json=VersionUpdate,proto3" json:"version_with_update,omitempty" validate:"gte=0,lte=130"`
  VersionReplace string    `protobuf:"bytes,4,opt,name=version_replace,json=VersionReplace,proto3" json:"version_with_replace" validate:"gte=0,lte=130"`
  Url            *Http_Url `protobuf:"bytes,5,opt,name=url,json=Url,proto3" json:"url_tag,omitempty"`
}

func (x *Http) Reset() {
  *x = Http{}
  if protoimpl.UnsafeEnabled {
    mi := &file_example_proto_msgTypes[0]
    ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
    ms.StoreMessageInfo(mi)
  }
}

func (x *Http) String() string {
  return protoimpl.X.MessageStringOf(x)
}

func (*Http) ProtoMessage() {}

func (x *Http) ProtoReflect() protoreflect.Message {
  mi := &file_example_proto_msgTypes[0]
  if protoimpl.UnsafeEnabled && x != nil {
    ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
    if ms.LoadMessageInfo() == nil {
      ms.StoreMessageInfo(mi)
    }
    return ms
  }
  return mi.MessageOf(x)
}

// Deprecated: Use Http.ProtoReflect.Descriptor instead.
func (*Http) Descriptor() ([]byte, []int) {
  return file_example_proto_rawDescGZIP(), []int{0}
}

func (x *Http) GetProtocol() string {
  if x != nil {
    return x.Protocol
  }
  return ""
}

func (x *Http) GetVersionDefault() string {
  if x != nil {
    return x.VersionDefault
  }
  return ""
}

func (x *Http) GetVersionUpdate() string {
  if x != nil {
    return x.VersionUpdate
  }
  return ""
}

func (x *Http) GetVersionReplace() string {
  if x != nil {
    return x.VersionReplace
  }
  return ""
}

func (x *Http) GetUrl() *Http_Url {
  if x != nil {
    return x.Url
  }
  return nil
}

type Http_Url struct {
  state         protoimpl.MessageState
  sizeCache     protoimpl.SizeCache
  unknownFields protoimpl.UnknownFields

  Scheme string `protobuf:"bytes,1,opt,name=scheme,json=Scheme,proto3" json:"schema_tag,omitempty"` //  string scheme = 1[json_name = "Scheme"];
}

func (x *Http_Url) Reset() {
  *x = Http_Url{}
  if protoimpl.UnsafeEnabled {
    mi := &file_example_proto_msgTypes[1]
    ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
    ms.StoreMessageInfo(mi)
  }
}

func (x *Http_Url) String() string {
  return protoimpl.X.MessageStringOf(x)
}

func (*Http_Url) ProtoMessage() {}

func (x *Http_Url) ProtoReflect() protoreflect.Message {
  mi := &file_example_proto_msgTypes[1]
  if protoimpl.UnsafeEnabled && x != nil {
    ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
    if ms.LoadMessageInfo() == nil {
      ms.StoreMessageInfo(mi)
    }
    return ms
  }
  return mi.MessageOf(x)
}

// Deprecated: Use Http_Url.ProtoReflect.Descriptor instead.
func (*Http_Url) Descriptor() ([]byte, []int) {
  return file_example_proto_rawDescGZIP(), []int{0, 0}
}

func (x *Http_Url) GetScheme() string {
  if x != nil {
    return x.Scheme
  }
  return ""
}

var File_example_proto protoreflect.FileDescriptor

var file_example_proto_rawDesc = []byte{
  0x0a, 0x0d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
  0x02, 0x70, 0x62, 0x1a, 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
  0x73, 0x65, 0x61, 0x72, 0x4b, 0x69, 0x6e, 0x67, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f,
  0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e,
  0x2d, 0x67, 0x6f, 0x2d, 0x74, 0x61, 0x67, 0x2f, 0x74, 0x61, 0x67, 0x2f, 0x74, 0x61, 0x67, 0x2e,
  0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf5, 0x03, 0x0a, 0x04, 0x48, 0x74, 0x74, 0x70, 0x12, 0x3d,
  0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
  0x42, 0x21, 0xc2, 0xde, 0x1f, 0x1d, 0x0a, 0x1b, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65,
  0x3a, 0x22, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x3d, 0x68, 0x74, 0x74, 0x70, 0x20, 0x68, 0x74, 0x74,
  0x70, 0x73, 0x22, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x63, 0x0a,
  0x0f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74,
  0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x3a, 0xc2, 0xde, 0x1f, 0x36, 0x0a, 0x34, 0x76, 0x61,
  0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x22, 0x67, 0x74, 0x65, 0x3d, 0x30, 0x2c, 0x6c, 0x74,
  0x65, 0x3d, 0x31, 0x33, 0x30, 0x22, 0x20, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x76, 0x65, 0x72,
  0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c,
  0x74, 0x22, 0x52, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75,
  0x6c, 0x74, 0x12, 0x60, 0x0a, 0x0e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x70,
  0x64, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x39, 0xc2, 0xde, 0x1f, 0x35,
  0x0a, 0x33, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x22, 0x67, 0x74, 0x65, 0x3d,
  0x30, 0x2c, 0x6c, 0x74, 0x65, 0x3d, 0x31, 0x33, 0x30, 0x22, 0x20, 0x6a, 0x73, 0x6f, 0x6e, 0x3a,
  0x22, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x75, 0x70,
  0x64, 0x61, 0x74, 0x65, 0x22, 0x52, 0x0d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x55, 0x70,
  0x64, 0x61, 0x74, 0x65, 0x12, 0x65, 0x0a, 0x0f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f,
  0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x3c, 0xc2,
  0xde, 0x1f, 0x38, 0x0a, 0x34, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x22, 0x67,
  0x74, 0x65, 0x3d, 0x30, 0x2c, 0x6c, 0x74, 0x65, 0x3d, 0x31, 0x33, 0x30, 0x22, 0x20, 0x6a, 0x73,
  0x6f, 0x6e, 0x3a, 0x22, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x77, 0x69, 0x74, 0x68,
  0x5f, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x22, 0x10, 0x01, 0x52, 0x0e, 0x56, 0x65, 0x72,
  0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x12, 0x3e, 0x0a, 0x03, 0x75,
  0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x62, 0x2e, 0x48, 0x74,
  0x74, 0x70, 0x2e, 0x55, 0x72, 0x6c, 0x42, 0x1e, 0xc2, 0xde, 0x1f, 0x1a, 0x0a, 0x18, 0x6a, 0x73,
  0x6f, 0x6e, 0x3a, 0x22, 0x75, 0x72, 0x6c, 0x5f, 0x74, 0x61, 0x67, 0x2c, 0x6f, 0x6d, 0x69, 0x74,
  0x65, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x52, 0x03, 0x55, 0x72, 0x6c, 0x1a, 0x40, 0x0a, 0x03, 0x55,
  0x72, 0x6c, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,
  0x28, 0x09, 0x42, 0x21, 0xc2, 0xde, 0x1f, 0x1d, 0x0a, 0x1b, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x22,
  0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x74, 0x61, 0x67, 0x2c, 0x6f, 0x6d, 0x69, 0x74, 0x65,
  0x6d, 0x70, 0x74, 0x79, 0x22, 0x52, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x42, 0x40, 0x5a,
  0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x65, 0x61, 0x72,
  0x4b, 0x69, 0x6e, 0x67, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x74, 0x6f, 0x6f, 0x6c,
  0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2d,
  0x74, 0x61, 0x67, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x3b, 0x70, 0x62, 0x62,
  0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
  file_example_proto_rawDescOnce sync.Once
  file_example_proto_rawDescData = file_example_proto_rawDesc
)

func file_example_proto_rawDescGZIP() []byte {
  file_example_proto_rawDescOnce.Do(func() {
    file_example_proto_rawDescData = protoimpl.X.CompressGZIP(file_example_proto_rawDescData)
  })
  return file_example_proto_rawDescData
}

var file_example_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_example_proto_goTypes = []interface{}{
  (*Http)(nil),     // 0: pb.Http
  (*Http_Url)(nil), // 1: pb.Http.Url
}
var file_example_proto_depIdxs = []int32{
  1, // 0: pb.Http.url:type_name -> pb.Http.Url
  1, // [1:1] is the sub-list for method output_type
  1, // [1:1] is the sub-list for method input_type
  1, // [1:1] is the sub-list for extension type_name
  1, // [1:1] is the sub-list for extension extendee
  0, // [0:1] is the sub-list for field type_name
}

func init() { file_example_proto_init() }
func file_example_proto_init() {
  if File_example_proto != nil {
    return
  }
  if !protoimpl.UnsafeEnabled {
    file_example_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
      switch v := v.(*Http); i {
      case 0:
        return &v.state
      case 1:
        return &v.sizeCache
      case 2:
        return &v.unknownFields
      default:
        return nil
      }
    }
    file_example_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
      switch v := v.(*Http_Url); i {
      case 0:
        return &v.state
      case 1:
        return &v.sizeCache
      case 2:
        return &v.unknownFields
      default:
        return nil
      }
    }
  }
  type x struct{}
  out := protoimpl.TypeBuilder{
    File: protoimpl.DescBuilder{
      GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
      RawDescriptor: file_example_proto_rawDesc,
      NumEnums:      0,
      NumMessages:   2,
      NumExtensions: 0,
      NumServices:   0,
    },
    GoTypes:           file_example_proto_goTypes,
    DependencyIndexes: file_example_proto_depIdxs,
    MessageInfos:      file_example_proto_msgTypes,
  }.Build()
  File_example_proto = out.File
  file_example_proto_rawDesc = nil
  file_example_proto_goTypes = nil
  file_example_proto_depIdxs = nil
}

Download/Install

The easiest way to install is to run go get install github.com/searKing/golang/tools/protoc-gen-go-tag . You can also manually git clone the repository to $GOPATH/src/github.com/searKing/golang/tools/protoc-gen-go-tag .

protoc-gen-go-tag: program not found or is not executable

The protoc compiler expects to find plugins named proto-gen-xxx on the execution $PATH. So first:

export PATH=${PATH}:$(go env GOPATH)/bin

xxx.proto: Tried to write the same file twice.

  • The protoc-gen-go-tag rewrites *.pb.go by proto-gen-go already. So use protoc-gen-go-tag instead of protoc-gen-go
  • protoc-gen-go is installed by go get install google.golang.org/protobuf/cmd/protoc-gen-go
  • Basically the magical incantation (apart from includes) is the --go-tag_out. That triggers the protoc-gen-go-tag plugin to generate *.pb.go. That's it :)

If you use protoc-gen-go installed by go get install github.com/golang/protobuf/protoc-gen-go

  • github.com/golang/protobuf has been superseded by the google.golang.org/protobuf module
  • install protoc-gen-go-tag by go get github.com/searKing/golang/tools/protoc-gen-go-tag@e27209892e58d3df53c587f1feefb6290af17d85
  • protoc -I . --go_out=paths=source_relative:. --go-tag_out=paths=source_relative:. *.proto
  • *.pb.go generated by protoc-gen-go will be rewritten by protoc-gen-go-tag

trick: embedded tag.proto into your proto directly, avoid include the tag.proto

  • Step 1 replace import "github.com/searKing/golang/tools/protoc-gen-go-tag/tag/tag.proto"; with code in the tag.proto
  • Step 2 replace google.protobuf.field_tag with field_tag
syntax = "proto3";

package pb;

// import "github.com/searKing/golang/tools/protoc-gen-go-tag/tag/tag.proto";
import "google/protobuf/descriptor.proto";
extend google.protobuf.FieldOptions {
  FieldTag field_tag = 65000;
}
message FieldTag {
  // struct tag.
  string struct_tag = 1;// custom struct tag
  UpdateStrategy update_strategy = 2;// update strategy

  enum UpdateStrategy {
    update = 0;// use custom struct tag to update struct tag generated by proto
    replace = 1;// use custom struct tag to replace struct tag generated by proto
  }
}

message Http{
  string protocol = 1;
  string version = 2[json_name = "Url", (field_tag) = {struct_tag: "validate:\"gte=0,lte=130\""}];;
  Url url = 3[json_name = "Url", (field_tag) = {struct_tag: "json:\"url_tag,omitempty\""}];
  message Url {
    string scheme = 1[json_name = "Scheme", (field_tag) = {struct_tag: "json:\"schema_tag,omitempty\""}];
    //  string scheme = 1[json_name = "Scheme"];
  }
}

Inspiring projects

FAQs

Package last updated on 12 Oct 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc