{"id":18765851,"url":"https://github.com/yeqown/protoc-gen-fieldmask","last_synced_at":"2025-04-13T05:28:30.474Z","repository":{"id":40474790,"uuid":"450012846","full_name":"yeqown/protoc-gen-fieldmask","owner":"yeqown","description":"Generate FieldMask utility functions for protobuf","archived":false,"fork":false,"pushed_at":"2023-01-08T12:30:40.000Z","size":675,"stargazers_count":36,"open_issues_count":2,"forks_count":9,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-26T22:11:33.086Z","etag":null,"topics":["fieldmask","go","grpc","plugin","protobuf","protoc","protoc-gen-fieldmask","protocol-buffers"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yeqown.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-01-20T08:24:17.000Z","updated_at":"2024-12-24T07:09:15.000Z","dependencies_parsed_at":"2023-02-08T05:45:30.983Z","dependency_job_id":null,"html_url":"https://github.com/yeqown/protoc-gen-fieldmask","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeqown%2Fprotoc-gen-fieldmask","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeqown%2Fprotoc-gen-fieldmask/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeqown%2Fprotoc-gen-fieldmask/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeqown%2Fprotoc-gen-fieldmask/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yeqown","download_url":"https://codeload.github.com/yeqown/protoc-gen-fieldmask/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248668786,"owners_count":21142740,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fieldmask","go","grpc","plugin","protobuf","protoc","protoc-gen-fieldmask","protocol-buffers"],"created_at":"2024-11-07T18:37:06.824Z","updated_at":"2025-04-13T05:28:30.427Z","avatar_url":"https://github.com/yeqown.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# protoc-gen-fieldmask\n\n\u003cimg src=\"./assets/intro.svg\" width=\"100%\"/\u003e\n\n![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/yeqown/protoc-gen-fieldmask)\n![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/yeqown/protoc-gen-fieldmask)\n[![License](https://img.shields.io/badge/license-MIT-green)](./LICENSE)\n\nGenerate [FieldMask](https://pkg.go.dev/google.golang.org/protobuf/types/known/fieldmaskpb) utilities for protobuf, \nsupport [Go](https://golang.org), maybe more programing languages later. FieldMask is a protobuf message type, \nit's used to represent a set of fields those should be contained in response, and sent to `Client`. \nIt looks like `grapgql` but only takes effect on the server inside calls.\n\nTo help developer to avoid repeating codes to deal with `FieldMask` message, this plugin generates a set of utilities to \ndeal with `FieldMask` message.\n\n**1. Masking gRPC response case**\n\n\u003cimg src=\"./assets/fieldmask-case1.jpg\" width=\"100%\" align=\"center\"\u003e\n\u003cbr /\u003e\n\n**2. Incremental update case**\n\n\u003cimg src=\"./assets/fieldmask-case2.jpg\" width=\"100%\" align=\"center\"\u003e\n\n### Features\n\n- [x] support field option in `in` message\n- [x] generates `Mask_$field` to `in` message type which declare in `in.FieldMask` option.\n- [x] generate `FieldMask_Filter` and `FieldMask_Prune` to `in` message, quickly apply field mask.  \n- [x] generates `Masked_$field` to `$out_FieldMask` support quickly judge field masking. \n- [x] support mask `in` fields in `incremental updating` case.\n\n### Installation\n\n```sh\ngo install github.com/yeqown/protoc-gen-fieldmask@latest\n```\n\n### Examples\n\n- [Masking gRPC response fields](./examples/grpc-masked-response/README.md)\n- [Incremental updating](examples/grpc-incremental-update/README.md) \n\n### Usage guide\n\n```sh\nprotoc \\\n\t-I. \\\n\t-I$YOUR_PROTO_PATH \\\n\t--go_out=paths=source_relative:. \\\n\t--fieldmask_out=paths=source_relative,lang=go:. \\\n\texample.proto\n```\n\n### Generated Preview\n\n1. coding proto file [user.proto](./examples/pb/user.proto)：\n\n```protobuf\nsyntax = \"proto3\";\n\nimport \"google/protobuf/field_mask.proto\";\n\nmessage UserInfoRequest {\n  string user_id = 1;\n  google.protobuf.FieldMask field_mask = 2 [\n    // generate MaskIn_XXX and MaskedIn_XXX, xxx are fields in in message (UserInfoRequest). \n    (fieldmask.option.Option).in = {gen: true},\n    // generate MaskOut_XXX and MaskedOut_XXX, xxx are fields in out message (UserInfoResponse).\n    // Notice that: \n    // 1. you must set message to out message name, and in and out message should in a same proto file.\n    // 2. if out message is not specified, it will not generated correctly. \n    (fieldmask.option.Option).out = {gen: true, message:\"UserInfoResponse\"}\n  ];\n}\n\nmessage Address {\n  string country = 1;\n  string province = 2;\n}\n\nmessage UserInfoResponse {\n  string user_id = 1;\n  string name = 2;\n  string email = 3;\n  Address address = 4;\n}\n```\n\n2. generated [user.pb.go](./examples/pb/user.pb.go), [user.pb.fm.go](./examples/pb/user.pb.fm.go)：\n\n```sh\ncd examples \u0026\u0026 make gen-pb\n\n# or generate them manually\ncd examples\nprotoc \\\n        -I./pb \\\n        -I../proto \\\n        --go_out=paths=source_relative:./pb \\\n        --fieldmask_out=paths=source_relative,lang=go:./pb \\\n        ./pb/user.proto\n```\n\n3. sample usage codes, on the one hand, to minimize changes to existing code, \nyou just omit fields by field mask like this:\n\n```go\nfunc main() {\n  req := \u0026normal.UserInfoRequest{\n    UserId:    \"123123\",\n    FieldMask: nil,\n  }\n  \n  // enable field mask on specific fields.\n  req.MaskOut_Email()\n  req.MaskOut_Name()\n  \n  \n  filter := req.FieldMask_Filter()\n  // or use prune mode, so clear fields those are masked. \n  // prune := req.FieldMask_Prune()\n  \n  resp := \u0026normal.UserInfoResponse{\n    UserId: \"69781\",\n    Name:   \"yeqown\",\n    Email:  \"yeqown@gmail.com\",\n    Address: \u0026normal.Address{\n      Country:  \"China\",\n      Province: \"Sichuan\",\n    },\n  }\n  \n  // makes filter or prune effect on resp.\n  prune.Mask(resp)\n}\n```\n\non the other hand, you can take FieldMask effect before the `resp` has been filled, \nso that you can ignore unnecessary calculating or remote calls:\n\n```go\nfunc main() {\n  req := \u0026normal.UserInfoRequest{\n    UserId:    \"123123\",\n    FieldMask: nil,\n  }\n  \n  // enable field mask on specific fields.\n  req.MaskOut_Email()\n  req.MaskOut_Name()\n  \n  filter := req.FieldMask_Filter()\n  resp := new(normal.UserInfoResponse)\n  if filter.Masked_Email() {\n    resp.Email = \"yeqown@gmail.com\"\n  }\n  if filter.Masked_Name() {\n    resp.Name = \"yeqown\"\n  }\n}\n```\n\n### How to debug\n\n- prepare a `debugdata`\n- install `protoc-gen-debug`: `go install github.com/lyft/protoc-gen-star/protoc-gen-debug@latest`\n- compile target proto file with `protoc-gen-debug`:\n\n    ```sh\n    protoc \\\n      -I=./examples/pb \\\n      -I=./proto \\\n      --plugin=protoc-gen-debug=${debug_path} \\\n      --debug_out=\"./internal/module/debugdata:.\" \\\n      ./examples/pb/user.proto\n    ```\n- debug [Test_ForDebug](./internal/module/fieldmask_test.go#L46) test suite\n  in [internal/module/fieldmask_test.go](./internal/module/fieldmask_test.go)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyeqown%2Fprotoc-gen-fieldmask","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyeqown%2Fprotoc-gen-fieldmask","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyeqown%2Fprotoc-gen-fieldmask/lists"}