From a0d00241a3aad1df807210a9403af0b814c26ee8 Mon Sep 17 00:00:00 2001 From: zoncoen Date: Thu, 25 Jan 2024 19:04:22 +0900 Subject: [PATCH] feat(extractor/protobuf): add extractor for protobuf --- extractor/protobuf/.gitignore | 1 + extractor/protobuf/Makefile | 49 +++ extractor/protobuf/example_protobuf_test.go | 32 ++ extractor/protobuf/go.mod | 15 + extractor/protobuf/go.sum | 8 + extractor/protobuf/protobuf.go | 84 +++++ extractor/protobuf/protobuf_test.go | 141 ++++++++ extractor/protobuf/testdata/gen/go.mod | 5 + extractor/protobuf/testdata/gen/go.sum | 6 + .../protobuf/testdata/gen/testpb/testpb.pb.go | 322 ++++++++++++++++++ .../testdata/proto/testpb/testpb.proto | 19 ++ 11 files changed, 682 insertions(+) create mode 100644 extractor/protobuf/.gitignore create mode 100644 extractor/protobuf/Makefile create mode 100644 extractor/protobuf/example_protobuf_test.go create mode 100644 extractor/protobuf/go.mod create mode 100644 extractor/protobuf/go.sum create mode 100644 extractor/protobuf/protobuf.go create mode 100644 extractor/protobuf/protobuf_test.go create mode 100644 extractor/protobuf/testdata/gen/go.mod create mode 100644 extractor/protobuf/testdata/gen/go.sum create mode 100644 extractor/protobuf/testdata/gen/testpb/testpb.pb.go create mode 100644 extractor/protobuf/testdata/proto/testpb/testpb.proto diff --git a/extractor/protobuf/.gitignore b/extractor/protobuf/.gitignore new file mode 100644 index 0000000..5e56e04 --- /dev/null +++ b/extractor/protobuf/.gitignore @@ -0,0 +1 @@ +/bin diff --git a/extractor/protobuf/Makefile b/extractor/protobuf/Makefile new file mode 100644 index 0000000..ce4b914 --- /dev/null +++ b/extractor/protobuf/Makefile @@ -0,0 +1,49 @@ +export + +.DEFAULT_GOAL := generate + +UNAME_OS := $(shell uname -s) +UNAME_ARCH := $(shell uname -m) + +BIN_DIR := $(CURDIR)/bin +PROTO_DIR := $(CURDIR)/testdata/proto +GEN_PB_DIR := $(CURDIR)/testdata/gen +GOBIN := $(BIN_DIR) +PATH := $(GOBIN):$(PATH) + +$(BIN_DIR): + @mkdir -p $(BIN_DIR) + +PROTOC := $(BIN_DIR)/protoc +PROTOC_VERSION := 25.1 +PROTOC_OS := $(UNAME_OS) +ifeq "$(UNAME_OS)" "Darwin" + PROTOC_OS = osx +endif +PROTOC_ARCH := $(UNAME_ARCH) +ifeq "$(UNAME_ARCH)" "arm64" + PROTOC_ARCH = aarch_64 +endif +PROTOC_ZIP := protoc-$(PROTOC_VERSION)-$(PROTOC_OS)-$(PROTOC_ARCH).zip +$(PROTOC): | $(BIN_DIR) + @curl -sSOL \ + "https://github.com/protocolbuffers/protobuf/releases/download/v$(PROTOC_VERSION)/$(PROTOC_ZIP)" + @unzip -j -o $(PROTOC_ZIP) -d $(BIN_DIR) bin/protoc + @unzip -o $(PROTOC_ZIP) -d $(BIN_DIR) "include/*" + @rm -f $(PROTOC_ZIP) + +PROTOC_GEN_GO := $(BIN_DIR)/protoc-gen-go +$(PROTOC_GEN_GO): | $(BIN_DIR) + @go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.32.0 + +PROTOC_GEN_GO_GRPC := $(BIN_DIR)/protoc-gen-go-grpc +$(PROTOC_GEN_GO_GRPC): | $(BIN_DIR) + @go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 + +PROTOC_OPTION := -I$(PROTO_DIR) +PROTOC_GO_OPTION := --plugin=${PROTOC_GEN_GO} --go_out=$(GEN_PB_DIR) --go_opt=paths=source_relative +PROTOC_GO_GRPC_OPTION := --go-grpc_out=require_unimplemented_servers=false:$(GEN_PB_DIR) --go-grpc_opt=paths=source_relative +.PHONY: generate +generate: $(PROTOC) $(PROTOC_GEN_GO) $(PROTOC_GEN_GO_GRPC) + @mkdir -p $(GEN_PB_DIR) + @find $(PROTO_DIR) -name '*.proto' | xargs -P8 protoc $(PROTOC_OPTION) $(PROTOC_GO_OPTION) $(PROTOC_GO_GRPC_OPTION) diff --git a/extractor/protobuf/example_protobuf_test.go b/extractor/protobuf/example_protobuf_test.go new file mode 100644 index 0000000..50fc426 --- /dev/null +++ b/extractor/protobuf/example_protobuf_test.go @@ -0,0 +1,32 @@ +package protobuf_test + +import ( + "fmt" + "log" + + "github.com/zoncoen/query-go" + + protobufextractor "github.com/zoncoen/query-go/extractor/protobuf" + testpb "github.com/zoncoen/query-go/extractor/protobuf/testdata/gen/testpb" +) + +func ExampleExtractFunc() { + v := testpb.OneofMessage{ + Value: &testpb.OneofMessage_B_{ + B: &testpb.OneofMessage_B{ + BarValue: "yyy", + }, + }, + } + q := query.New( + query.CustomExtractFunc(protobufextractor.ExtractFunc()), + query.CustomIsInlineStructFieldFunc(protobufextractor.OneofIsInlineStructFieldFunc()), + ).Key("B").Key("bar_value") + got, err := q.Extract(v) + if err != nil { + log.Fatal(err) + } + fmt.Println(got) + // Output: + // yyy +} diff --git a/extractor/protobuf/go.mod b/extractor/protobuf/go.mod new file mode 100644 index 0000000..9d5f7fa --- /dev/null +++ b/extractor/protobuf/go.mod @@ -0,0 +1,15 @@ +module github.com/zoncoen/query-go/extractor/protobuf + +go 1.21.6 + +require ( + github.com/zoncoen/query-go v1.3.0 + github.com/zoncoen/query-go/extractor/protobuf/testdata/gen v0.0.0-00010101000000-000000000000 +) + +replace github.com/zoncoen/query-go/extractor/protobuf/testdata/gen => ./testdata/gen/ + +require ( + github.com/pkg/errors v0.9.1 // indirect + google.golang.org/protobuf v1.32.0 // indirect +) diff --git a/extractor/protobuf/go.sum b/extractor/protobuf/go.sum new file mode 100644 index 0000000..c154539 --- /dev/null +++ b/extractor/protobuf/go.sum @@ -0,0 +1,8 @@ +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/zoncoen/query-go v1.3.0 h1:wL5e3jxP1l3mMueyrsnj7KOtAvSe1JNzW1FaLhD5rsQ= +github.com/zoncoen/query-go v1.3.0/go.mod h1:rbLi2EwarQtEJ5cNg9LFmAnleihBLsQSc1ow7vA8nms= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= diff --git a/extractor/protobuf/protobuf.go b/extractor/protobuf/protobuf.go new file mode 100644 index 0000000..cde0d1b --- /dev/null +++ b/extractor/protobuf/protobuf.go @@ -0,0 +1,84 @@ +package protobuf + +import ( + "context" + "reflect" + "strings" + + "github.com/zoncoen/query-go" +) + +// ExtractFunc is a function for query.CustomExtractFunc option to extract values by protobuf struct tag. +func ExtractFunc() func(query.ExtractFunc) query.ExtractFunc { + return func(f query.ExtractFunc) query.ExtractFunc { + return func(in reflect.Value) (reflect.Value, bool) { + v := in + for { + if v.IsValid() { + if k := v.Kind(); k == reflect.Interface || k == reflect.Pointer { + v = v.Elem() + continue + } + } + break + } + switch v.Kind() { + case reflect.Struct: + for i := 0; i < v.Type().NumField(); i++ { + field := v.Type().FieldByIndex([]int{i}) + if s := field.Tag.Get("protobuf"); s != "" { + if v, found := f(reflect.ValueOf(&keyExtractor{v})); found { + return v, true + } + } + } + } + return f(in) + } + } +} + +type keyExtractor struct { + v reflect.Value +} + +// ExtractByKey implements KeyExtractorContext interface. +func (e *keyExtractor) ExtractByKey(ctx context.Context, key string) (any, bool) { + ci := query.IsCaseInsensitive(ctx) + if ci { + key = strings.ToLower(key) + } + switch e.v.Kind() { + case reflect.Struct: + for i := 0; i < e.v.Type().NumField(); i++ { + if s := e.v.Type().FieldByIndex([]int{i}).Tag.Get("protobuf"); s != "" { + for _, opt := range strings.Split(s, ",") { + kv := strings.Split(opt, "=") + if len(kv) == 2 { + k, v := kv[0], kv[1] + if k == "name" { + if ci { + v = strings.ToLower(v) + } + if v == key { + var resp any + if field := e.v.Field(i); field.CanInterface() { + resp = field.Interface() + } + return resp, true + } + } + } + } + } + } + } + return nil, false +} + +// OneofIsInlineStructFieldFunc is a function for query.CustomIsInlineStructFieldFunc option to enable extracting values even if the oneof field name is omitted. +func OneofIsInlineStructFieldFunc() func(reflect.StructField) bool { + return func(f reflect.StructField) bool { + return f.Tag.Get("protobuf_oneof") != "" + } +} diff --git a/extractor/protobuf/protobuf_test.go b/extractor/protobuf/protobuf_test.go new file mode 100644 index 0000000..c3cdeac --- /dev/null +++ b/extractor/protobuf/protobuf_test.go @@ -0,0 +1,141 @@ +package protobuf + +import ( + "strings" + "testing" + + "github.com/zoncoen/query-go" + testpb "github.com/zoncoen/query-go/extractor/protobuf/testdata/gen/testpb" +) + +func TestExtractFunc(t *testing.T) { + t.Run("success", func(t *testing.T) { + tests := map[string]struct { + query *query.Query + v any + expect any + }{ + "by field name": { + query: query.New( + query.CustomExtractFunc(ExtractFunc()), + ).Key("Value").Key("B").Key("BarValue"), + v: testpb.OneofMessage{ + Value: &testpb.OneofMessage_B_{ + B: &testpb.OneofMessage_B{ + BarValue: "yyy", + }, + }, + }, + expect: "yyy", + }, + "by struct tag": { + query: query.New( + query.CustomExtractFunc(ExtractFunc()), + ).Key("Value").Key("B").Key("bar_value"), + v: testpb.OneofMessage{ + Value: &testpb.OneofMessage_B_{ + B: &testpb.OneofMessage_B{ + BarValue: "yyy", + }, + }, + }, + expect: "yyy", + }, + "by struct tag (case insensitive)": { + query: query.New( + query.CaseInsensitive(), + query.CustomExtractFunc(ExtractFunc()), + ).Key("Value").Key("B").Key("BAR_VALUE"), + v: testpb.OneofMessage{ + Value: &testpb.OneofMessage_B_{ + B: &testpb.OneofMessage_B{ + BarValue: "yyy", + }, + }, + }, + expect: "yyy", + }, + } + for name, test := range tests { + test := test + t.Run(name, func(t *testing.T) { + got, err := test.query.Extract(test.v) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + if got != test.expect { + t.Errorf("expect %v but got %v", test.expect, got) + } + }) + } + }) + t.Run("failure", func(t *testing.T) { + tests := map[string]struct { + query *query.Query + v any + expect string + }{ + "not found": { + query: query.New( + query.CustomExtractFunc(ExtractFunc()), + ).Key("Value").Key("B").Key("BAR_VALUE"), + v: testpb.OneofMessage{ + Value: &testpb.OneofMessage_B_{ + B: &testpb.OneofMessage_B{ + BarValue: "yyy", + }, + }, + }, + expect: `".Value.B.BAR_VALUE" not found`, + }, + } + for name, test := range tests { + test := test + t.Run(name, func(t *testing.T) { + _, err := test.query.Extract(test.v) + if err == nil { + t.Fatal("no error") + } + if got := err.Error(); !strings.Contains(got, test.expect) { + t.Errorf("expect %v but got %v", test.expect, got) + } + }) + } + }) +} + +func TestOneofIsInlineStructFieldFunc(t *testing.T) { + t.Run("success", func(t *testing.T) { + tests := map[string]struct { + query *query.Query + v any + expect any + }{ + "omit .Value": { + query: query.New( + query.CustomIsInlineStructFieldFunc(OneofIsInlineStructFieldFunc()), + ).Key("B").Key("BarValue"), + v: testpb.OneofMessage{ + Value: &testpb.OneofMessage_B_{ + B: &testpb.OneofMessage_B{ + BarValue: "yyy", + }, + }, + }, + expect: "yyy", + }, + } + for name, test := range tests { + test := test + t.Run(name, func(t *testing.T) { + got, err := test.query.Extract(test.v) + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + if got != test.expect { + t.Errorf("expect %v but got %v", test.expect, got) + } + }) + } + }) +} diff --git a/extractor/protobuf/testdata/gen/go.mod b/extractor/protobuf/testdata/gen/go.mod new file mode 100644 index 0000000..f03d51c --- /dev/null +++ b/extractor/protobuf/testdata/gen/go.mod @@ -0,0 +1,5 @@ +module github.com/zoncoen/query-go/extractor/protobuf/testdata/gen + +go 1.21.6 + +require google.golang.org/protobuf v1.32.0 diff --git a/extractor/protobuf/testdata/gen/go.sum b/extractor/protobuf/testdata/gen/go.sum new file mode 100644 index 0000000..5361bc7 --- /dev/null +++ b/extractor/protobuf/testdata/gen/go.sum @@ -0,0 +1,6 @@ +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= diff --git a/extractor/protobuf/testdata/gen/testpb/testpb.pb.go b/extractor/protobuf/testdata/gen/testpb/testpb.pb.go new file mode 100644 index 0000000..119839b --- /dev/null +++ b/extractor/protobuf/testdata/gen/testpb/testpb.pb.go @@ -0,0 +1,322 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.32.0 +// protoc v4.25.1 +// source: testpb/testpb.proto + +package testpb + +import ( + 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 OneofMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Value: + // + // *OneofMessage_A_ + // *OneofMessage_B_ + Value isOneofMessage_Value `protobuf_oneof:"value"` +} + +func (x *OneofMessage) Reset() { + *x = OneofMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_testpb_testpb_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OneofMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OneofMessage) ProtoMessage() {} + +func (x *OneofMessage) ProtoReflect() protoreflect.Message { + mi := &file_testpb_testpb_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 OneofMessage.ProtoReflect.Descriptor instead. +func (*OneofMessage) Descriptor() ([]byte, []int) { + return file_testpb_testpb_proto_rawDescGZIP(), []int{0} +} + +func (m *OneofMessage) GetValue() isOneofMessage_Value { + if m != nil { + return m.Value + } + return nil +} + +func (x *OneofMessage) GetA() *OneofMessage_A { + if x, ok := x.GetValue().(*OneofMessage_A_); ok { + return x.A + } + return nil +} + +func (x *OneofMessage) GetB() *OneofMessage_B { + if x, ok := x.GetValue().(*OneofMessage_B_); ok { + return x.B + } + return nil +} + +type isOneofMessage_Value interface { + isOneofMessage_Value() +} + +type OneofMessage_A_ struct { + A *OneofMessage_A `protobuf:"bytes,1,opt,name=a,proto3,oneof"` +} + +type OneofMessage_B_ struct { + B *OneofMessage_B `protobuf:"bytes,2,opt,name=b,proto3,oneof"` +} + +func (*OneofMessage_A_) isOneofMessage_Value() {} + +func (*OneofMessage_B_) isOneofMessage_Value() {} + +type OneofMessage_A struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FooValue string `protobuf:"bytes,1,opt,name=foo_value,json=fooValue,proto3" json:"foo_value,omitempty"` +} + +func (x *OneofMessage_A) Reset() { + *x = OneofMessage_A{} + if protoimpl.UnsafeEnabled { + mi := &file_testpb_testpb_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OneofMessage_A) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OneofMessage_A) ProtoMessage() {} + +func (x *OneofMessage_A) ProtoReflect() protoreflect.Message { + mi := &file_testpb_testpb_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 OneofMessage_A.ProtoReflect.Descriptor instead. +func (*OneofMessage_A) Descriptor() ([]byte, []int) { + return file_testpb_testpb_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *OneofMessage_A) GetFooValue() string { + if x != nil { + return x.FooValue + } + return "" +} + +type OneofMessage_B struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BarValue string `protobuf:"bytes,1,opt,name=bar_value,json=barValue,proto3" json:"bar_value,omitempty"` +} + +func (x *OneofMessage_B) Reset() { + *x = OneofMessage_B{} + if protoimpl.UnsafeEnabled { + mi := &file_testpb_testpb_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OneofMessage_B) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OneofMessage_B) ProtoMessage() {} + +func (x *OneofMessage_B) ProtoReflect() protoreflect.Message { + mi := &file_testpb_testpb_proto_msgTypes[2] + 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 OneofMessage_B.ProtoReflect.Descriptor instead. +func (*OneofMessage_B) Descriptor() ([]byte, []int) { + return file_testpb_testpb_proto_rawDescGZIP(), []int{0, 1} +} + +func (x *OneofMessage_B) GetBarValue() string { + if x != nil { + return x.BarValue + } + return "" +} + +var File_testpb_testpb_proto protoreflect.FileDescriptor + +var file_testpb_testpb_proto_rawDesc = []byte{ + 0x0a, 0x13, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2d, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x7a, 0x6f, 0x6e, 0x63, 0x6f, 0x65, 0x6e, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x67, + 0x6f, 0x2e, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x22, 0xf9, 0x01, 0x0a, 0x0c, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x4d, 0x0a, 0x01, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x3d, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x7a, 0x6f, + 0x6e, 0x63, 0x6f, 0x65, 0x6e, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x67, 0x6f, 0x2e, 0x65, 0x78, + 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x41, 0x48, + 0x00, 0x52, 0x01, 0x61, 0x12, 0x4d, 0x0a, 0x01, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x3d, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x7a, 0x6f, 0x6e, + 0x63, 0x6f, 0x65, 0x6e, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x67, 0x6f, 0x2e, 0x65, 0x78, 0x74, + 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x42, 0x48, 0x00, + 0x52, 0x01, 0x62, 0x1a, 0x20, 0x0a, 0x01, 0x41, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x6f, 0x6f, 0x5f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x6f, 0x6f, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x20, 0x0a, 0x01, 0x42, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x61, + 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, + 0x61, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x42, 0x4b, 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x7a, + 0x6f, 0x6e, 0x63, 0x6f, 0x65, 0x6e, 0x2f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2d, 0x67, 0x6f, 0x2f, + 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x67, 0x65, 0x6e, 0x2f, + 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x3b, 0x74, 0x65, 0x73, 0x74, 0x70, 0x62, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_testpb_testpb_proto_rawDescOnce sync.Once + file_testpb_testpb_proto_rawDescData = file_testpb_testpb_proto_rawDesc +) + +func file_testpb_testpb_proto_rawDescGZIP() []byte { + file_testpb_testpb_proto_rawDescOnce.Do(func() { + file_testpb_testpb_proto_rawDescData = protoimpl.X.CompressGZIP(file_testpb_testpb_proto_rawDescData) + }) + return file_testpb_testpb_proto_rawDescData +} + +var file_testpb_testpb_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_testpb_testpb_proto_goTypes = []interface{}{ + (*OneofMessage)(nil), // 0: com.github.zoncoen.querygo.extractor.protobuf.OneofMessage + (*OneofMessage_A)(nil), // 1: com.github.zoncoen.querygo.extractor.protobuf.OneofMessage.A + (*OneofMessage_B)(nil), // 2: com.github.zoncoen.querygo.extractor.protobuf.OneofMessage.B +} +var file_testpb_testpb_proto_depIdxs = []int32{ + 1, // 0: com.github.zoncoen.querygo.extractor.protobuf.OneofMessage.a:type_name -> com.github.zoncoen.querygo.extractor.protobuf.OneofMessage.A + 2, // 1: com.github.zoncoen.querygo.extractor.protobuf.OneofMessage.b:type_name -> com.github.zoncoen.querygo.extractor.protobuf.OneofMessage.B + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_testpb_testpb_proto_init() } +func file_testpb_testpb_proto_init() { + if File_testpb_testpb_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_testpb_testpb_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OneofMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_testpb_testpb_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OneofMessage_A); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_testpb_testpb_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OneofMessage_B); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_testpb_testpb_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*OneofMessage_A_)(nil), + (*OneofMessage_B_)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_testpb_testpb_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_testpb_testpb_proto_goTypes, + DependencyIndexes: file_testpb_testpb_proto_depIdxs, + MessageInfos: file_testpb_testpb_proto_msgTypes, + }.Build() + File_testpb_testpb_proto = out.File + file_testpb_testpb_proto_rawDesc = nil + file_testpb_testpb_proto_goTypes = nil + file_testpb_testpb_proto_depIdxs = nil +} diff --git a/extractor/protobuf/testdata/proto/testpb/testpb.proto b/extractor/protobuf/testdata/proto/testpb/testpb.proto new file mode 100644 index 0000000..060476b --- /dev/null +++ b/extractor/protobuf/testdata/proto/testpb/testpb.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package com.github.zoncoen.querygo.extractor.protobuf; + + +option go_package = "github.com/zoncoen/query-go/extractor/protobuf/testdata/gen/testpb;testpb"; + +message OneofMessage { + oneof value { + A a = 1; + B b = 2; + } + message A { + string foo_value = 1; + } + message B { + string bar_value = 1; + } +}