├── LICENSE ├── Makefile ├── README.md ├── fixtures ├── TestEnumStruct.ts ├── TestMessage.ts ├── TestNativeEnumStruct.ts ├── TestOneOfStruct.ts ├── TestProto3Message.ts ├── TestProtoStruct.ts └── proto3message.json ├── generator.go ├── generator_proto2_test.go ├── generator_proto3_test.go ├── go.mod ├── go.sum ├── internal └── test │ ├── proto2_test.pb.go │ ├── proto2_test.proto │ ├── proto3_test.pb.go │ └── proto3_test.proto └── pbts.go /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2017 Ping Wong 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | compile: 2 | PATH=$$PWD/local/bin:$$PATH \ 3 | protoc --go_out=. --go_opt=paths=source_relative \ 4 | internal/test/proto2_test.proto \ 5 | internal/test/proto3_test.proto 6 | 7 | prepare: 8 | mkdir -p local/bin 9 | GOBIN=$$PWD/local/bin go install google.golang.org/protobuf/cmd/protoc-gen-go 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pbts 2 | 3 | `pbts` is a simple `pb.go` to `.ts` converter. It converts the `protoc` generated Golang 4 | definitions for protobuf messages into a Typescript abstract class. 5 | 6 | The motivation for `pbts` is to be able to easily - 7 | 8 | 1. define APIs using protobufs, 9 | 2. implement the API server using Golang, and 10 | 3. implement frontend client in Typescript. 11 | 12 | The types generated by `protoc` and `pbts` respectively will ensure that (<pedantic>some</pedantic>) 13 | breaking API changes will cause compile time errors. 14 | 15 | ## Notes 16 | 17 | - a `copy` function is generated to copy data between instances. 18 | - following protobuf conventions, `int64` types are serialized as strings. 19 | - proto maps and oneofs are supported 20 | - the types generated will be satisfied by json generated with `protojson.MarshalOption{EmitDefaultValues: true}` 21 | 22 | ## Example Usage 23 | 24 | ``` 25 | # main.go 26 | 27 | writer, _ := os.OpenFile("api.ts", ...) 28 | g := pbts.NewGenerator(writer) 29 | g.RegisterMany( 30 | &MyFirstStruct{}, 31 | &MySecondStruct{}, 32 | ) 33 | g.Write() 34 | ``` 35 | 36 | ## Example Output 37 | 38 | Import the generated classes into your Typescript project for fun and profit. 39 | 40 | ``` 41 | type TestStruct struct { 42 | Field *string `protobuf:"bytes,1,opt,name=field" json:"field,omitempty"` 43 | FieldInt *int64 `protobuf:"varint,6,opt,name=field_int,json=fieldInt" json:"field_int,omitempty"` 44 | Metadata map[string]int32 `protobuf:"bytes,11,rep,name=metadata" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` 45 | Tags []string `protobuf:"bytes,12,rep,name=tags" json:"tags,omitempty"` 46 | } 47 | ``` 48 | 49 | ``` 50 | # api.ts 51 | 52 | export abstract class MyFirstStruct { 53 | field?: string; 54 | fieldInt?: string; 55 | metadata: { [key: string]: number; }; 56 | tags: string[]; 57 | static copy(from: MyFirstStruct, to?: MyFirstStruct): MyFirstStruct { 58 | if (to) { 59 | to.field = from.field; 60 | to.fieldInt = from.fieldInt; 61 | to.metadata = from.metadata; 62 | to.tags = from.tags; 63 | return to; 64 | } 65 | return {...from}; 66 | } 67 | } 68 | 69 | ... 70 | ``` 71 | 72 | ## Enums 73 | 74 | `pbts` supports two enum modes: native enums and string literal types: 75 | 76 | Default: 77 | 78 | ``` 79 | export type TestEnum = 'bar' | 'foo' | 'unknown'; 80 | ``` 81 | 82 | By setting `g.NativeEnums = true`: 83 | 84 | ``` 85 | export enum TestEnum { 86 | Bar = "bar", 87 | Foo = "foo", 88 | Unknown = "unknown", 89 | } 90 | ``` 91 | -------------------------------------------------------------------------------- /fixtures/TestEnumStruct.ts: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT! This file is generated automatically by pbts (github.com/octavore/pbts) 2 | 3 | export interface TestEnumStruct { 4 | enumField?: TestEnumStruct_TestEnum; 5 | } 6 | 7 | export abstract class TestEnumStruct { 8 | static copy(from: TestEnumStruct, to?: TestEnumStruct): TestEnumStruct { 9 | if (to) { 10 | to.enumField = from.enumField; 11 | return to; 12 | } 13 | return {...from}; 14 | } 15 | } 16 | 17 | export type TestEnumStruct_TestEnum = 'bar' | 'foo' | 'unknown'; 18 | -------------------------------------------------------------------------------- /fixtures/TestMessage.ts: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT! This file is generated automatically by pbts (github.com/octavore/pbts) 2 | 3 | export interface TestMessage { 4 | strField?: string; 5 | int32Field?: number; 6 | int64Field?: string; 7 | strList: string[]; 8 | metadata: {[key: string]: string}; 9 | } 10 | 11 | export abstract class TestMessage { 12 | static copy(from: TestMessage, to?: TestMessage): TestMessage { 13 | if (to) { 14 | to.strField = from.strField; 15 | to.int32Field = from.int32Field; 16 | to.int64Field = from.int64Field; 17 | to.strList = from.strList.slice(); 18 | to.metadata = from.metadata; 19 | return to; 20 | } 21 | return {...from}; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /fixtures/TestNativeEnumStruct.ts: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT! This file is generated automatically by pbts (github.com/octavore/pbts) 2 | 3 | export interface TestEnumStruct { 4 | enumField?: TestEnumStruct_TestEnum; 5 | } 6 | 7 | export abstract class TestEnumStruct { 8 | static copy(from: TestEnumStruct, to?: TestEnumStruct): TestEnumStruct { 9 | if (to) { 10 | to.enumField = from.enumField; 11 | return to; 12 | } 13 | return {...from}; 14 | } 15 | } 16 | 17 | export enum TestEnumStruct_TestEnum { 18 | Bar = "bar", 19 | Foo = "foo", 20 | Unknown = "unknown", 21 | } 22 | -------------------------------------------------------------------------------- /fixtures/TestOneOfStruct.ts: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT! This file is generated automatically by pbts (github.com/octavore/pbts) 2 | 3 | export interface TestOneofStruct { 4 | stock?: TestOneofStruct_Stock; // oneof:TestOneofStruct_instrument 5 | currency?: TestOneofStruct_Currency; // oneof:TestOneofStruct_instrument 6 | strField?: string; // oneof:TestOneofStruct_instrument 7 | } 8 | 9 | export abstract class TestOneofStruct { 10 | static copy(from: TestOneofStruct, to?: TestOneofStruct): TestOneofStruct { 11 | if (to) { 12 | to.stock = from.stock ? TestOneofStruct_Stock.copy(from.stock) : undefined; 13 | to.currency = from.currency ? TestOneofStruct_Currency.copy(from.currency) : undefined; 14 | to.strField = from.strField; 15 | return to; 16 | } 17 | return { 18 | ...from, 19 | stock: from.stock ? TestOneofStruct_Stock.copy(from.stock) : undefined, 20 | currency: from.currency ? TestOneofStruct_Currency.copy(from.currency) : undefined, 21 | }; 22 | } 23 | } 24 | 25 | export interface TestOneofStruct_Stock { 26 | name?: string; 27 | } 28 | 29 | export abstract class TestOneofStruct_Stock { 30 | static copy(from: TestOneofStruct_Stock, to?: TestOneofStruct_Stock): TestOneofStruct_Stock { 31 | if (to) { 32 | to.name = from.name; 33 | return to; 34 | } 35 | return {...from}; 36 | } 37 | } 38 | 39 | export interface TestOneofStruct_Currency { 40 | country?: string; 41 | shortCode?: string; 42 | } 43 | 44 | export abstract class TestOneofStruct_Currency { 45 | static copy(from: TestOneofStruct_Currency, to?: TestOneofStruct_Currency): TestOneofStruct_Currency { 46 | if (to) { 47 | to.country = from.country; 48 | to.shortCode = from.shortCode; 49 | return to; 50 | } 51 | return {...from}; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /fixtures/TestProto3Message.ts: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT! This file is generated automatically by pbts (github.com/octavore/pbts) 2 | 3 | export interface TestProto3Message { 4 | strField: string; 5 | optStrField?: string; 6 | int32Field: number; 7 | int64Field: string; 8 | strList: string[]; 9 | nested?: TestProto3NestedMessage; 10 | nestedList: TestProto3NestedMessage[]; 11 | metadata: {[key: string]: string}; 12 | } 13 | 14 | export abstract class TestProto3Message { 15 | static copy(from: TestProto3Message, to?: TestProto3Message): TestProto3Message { 16 | if (to) { 17 | to.strField = from.strField; 18 | to.optStrField = from.optStrField; 19 | to.int32Field = from.int32Field; 20 | to.int64Field = from.int64Field; 21 | to.strList = from.strList.slice(); 22 | to.nested = from.nested ? TestProto3NestedMessage.copy(from.nested) : undefined; 23 | to.nestedList = from.nestedList.slice(); 24 | to.metadata = from.metadata; 25 | return to; 26 | } 27 | return { 28 | ...from, 29 | nested: from.nested ? TestProto3NestedMessage.copy(from.nested) : undefined, 30 | nestedList: from.nestedList.slice(), 31 | }; 32 | } 33 | } 34 | 35 | export interface TestProto3NestedMessage { 36 | strField: string; 37 | } 38 | 39 | export abstract class TestProto3NestedMessage { 40 | static copy(from: TestProto3NestedMessage, to?: TestProto3NestedMessage): TestProto3NestedMessage { 41 | if (to) { 42 | to.strField = from.strField; 43 | return to; 44 | } 45 | return {...from}; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /fixtures/TestProtoStruct.ts: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT! This file is generated automatically by pbts (github.com/octavore/pbts) 2 | 3 | export interface Struct { 4 | fields: {[key: string]: any}; 5 | } 6 | 7 | export abstract class Struct { 8 | static copy(from: Struct, to?: Struct): Struct { 9 | if (to) { 10 | to.fields = from.fields; 11 | return to; 12 | } 13 | return {...from}; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /fixtures/proto3message.json: -------------------------------------------------------------------------------- 1 | { 2 | "strField": "", 3 | "int32Field": 0, 4 | "int64Field": "0", 5 | "strList": [], 6 | "nestedList": [], 7 | "metadata": {} 8 | } 9 | -------------------------------------------------------------------------------- /generator.go: -------------------------------------------------------------------------------- 1 | package pbts 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "strings" 7 | 8 | "sort" 9 | 10 | "github.com/iancoleman/strcase" 11 | "google.golang.org/protobuf/proto" 12 | "google.golang.org/protobuf/reflect/protoreflect" 13 | "google.golang.org/protobuf/types/known/anypb" 14 | "google.golang.org/protobuf/types/known/structpb" 15 | ) 16 | 17 | const filePreamble = "// DO NOT EDIT! This file is generated automatically by pbts (github.com/octavore/pbts)" 18 | 19 | func NewGenerator(w io.Writer) *Generator { 20 | return &Generator{out: w} 21 | } 22 | 23 | type Generator struct { 24 | models []protoreflect.MessageDescriptor 25 | indirectModels []protoreflect.MessageDescriptor 26 | enums []protoreflect.EnumDescriptor 27 | out io.Writer 28 | 29 | NativeEnums bool 30 | } 31 | 32 | func (g *Generator) RegisterMany(l ...proto.Message) { 33 | for _, m := range l { 34 | g.Register(m) 35 | } 36 | } 37 | 38 | func (g *Generator) Register(msg proto.Message) { 39 | g.RegisterDescriptor(msg.ProtoReflect().Descriptor()) 40 | } 41 | 42 | func (g *Generator) RegisterDescriptor(msgDesc protoreflect.MessageDescriptor) { 43 | g.models = append(g.models, msgDesc) 44 | 45 | for i := 0; i < msgDesc.Messages().Len(); i++ { 46 | m := msgDesc.Messages().Get(i) 47 | if m.IsMapEntry() { 48 | continue 49 | } 50 | g.indirectModels = append(g.indirectModels, m) 51 | } 52 | } 53 | 54 | func (g *Generator) Write() { 55 | g.p(0, filePreamble) 56 | for _, m := range g.models { 57 | g.p(0, "") 58 | g.convert(m) 59 | } 60 | for _, m := range g.indirectModels { 61 | g.p(0, "") 62 | g.convert(m) 63 | } 64 | 65 | // write enums 66 | g.writeEnums() 67 | } 68 | 69 | func (g *Generator) p(indent int, s string, args ...any) { 70 | spaces := strings.Repeat(" ", indent) 71 | fmt.Fprintf(g.out, spaces+s+"\n", args...) 72 | } 73 | 74 | func (g *Generator) convertEnum(e protoreflect.EnumDescriptor) { 75 | enumValues := e.Values() 76 | if g.NativeEnums { 77 | enums := []string{} 78 | for i := 0; i < enumValues.Len(); i++ { 79 | enum := enumValues.Get(i) 80 | enums = append(enums, fmt.Sprintf("%s", enum.Name())) 81 | } 82 | sort.Strings(enums) 83 | g.p(0, "export enum %s {", nameWithParent(e)) 84 | for _, e := range enums { 85 | g.p(2, "%s = \"%s\",", strcase.ToCamel(e), e) 86 | } 87 | g.p(0, "}") 88 | return 89 | } 90 | 91 | enums := []string{} 92 | for i := 0; i < enumValues.Len(); i++ { 93 | enum := enumValues.Get(i) 94 | enums = append(enums, fmt.Sprintf("'%s'", enum.Name())) 95 | } 96 | 97 | sort.Strings(enums) 98 | g.p(0, "export type %s = %s;", nameWithParent(e), strings.Join(enums, " | ")) 99 | } 100 | 101 | func (g *Generator) writeEnums() { 102 | sort.Slice(g.enums, func(i, j int) bool { 103 | return g.enums[i].Name() < g.enums[j].Name() 104 | }) 105 | for _, enum := range g.enums { 106 | g.p(0, "") 107 | g.convertEnum(enum) 108 | } 109 | } 110 | 111 | // subconvertFields take a go Type and converts all the fields 112 | // for that Type as Typescript fields. i.e. `myField?: aTypeScriptType`. 113 | // Returns the list of field names. 114 | func (g *Generator) subconvertFields(v protoreflect.FieldDescriptors) []annotatedField { 115 | fields := []annotatedField{} 116 | for j := 0; j < v.Len(); j++ { 117 | fieldDesc := v.Get(j) 118 | name := fieldDesc.JSONName() 119 | typ, builtin := g.fieldToBaseType(fieldDesc) 120 | if typ != "" { 121 | field := annotatedField{name: name, required: !fieldDesc.HasPresence(), repeated: fieldDesc.IsList()} 122 | if !builtin { 123 | field.tsType = typ 124 | } 125 | fields = append(fields, field) 126 | 127 | comment := "" 128 | if fieldDesc.ContainingOneof() != nil && !fieldDesc.HasOptionalKeyword() { 129 | comment = fmt.Sprintf(" // oneof:%s", nameWithParent(fieldDesc.ContainingOneof())) 130 | } 131 | if fieldDesc.HasPresence() { 132 | g.p(2, "%s?: %s;%s", name, typ, comment) 133 | } else { 134 | g.p(2, "%s: %s;%s", name, typ, comment) 135 | } 136 | } else { 137 | g.p(2, "// skipped field: "+name) 138 | } 139 | } 140 | return fields 141 | } 142 | 143 | func (g *Generator) convert(msg protoreflect.MessageDescriptor) { 144 | className := nameWithParent(msg) 145 | g.p(0, "export interface %s {", className) 146 | fields := g.subconvertFields(msg.Fields()) 147 | g.p(0, "}\n") 148 | g.p(0, "export abstract class %s {", className) 149 | g.generateCopyFunction(className, fields) 150 | g.p(0, "}") 151 | } 152 | 153 | func (g *Generator) fieldToBaseType(f protoreflect.FieldDescriptor) (string, bool) { 154 | // 1. builtin kinds 155 | builtin := "" 156 | switch f.Kind() { 157 | case protoreflect.BoolKind: 158 | builtin = "boolean" 159 | case protoreflect.StringKind: 160 | builtin = "string" 161 | case protoreflect.Int32Kind, 162 | protoreflect.Sint32Kind, 163 | protoreflect.Uint32Kind, 164 | protoreflect.FloatKind: 165 | builtin = "number" 166 | 167 | case protoreflect.Int64Kind, 168 | protoreflect.Sint64Kind, 169 | protoreflect.Uint64Kind: 170 | builtin = "string" 171 | } 172 | if builtin != "" { 173 | if f.Cardinality() == protoreflect.Repeated { 174 | builtin += "[]" 175 | } 176 | return builtin, true 177 | } 178 | // case protoreflect.Sfixed32Kind: 179 | // case protoreflect.Fixed32Kind: 180 | // case protoreflect.Sfixed64Kind: 181 | // case protoreflect.Fixed64Kind: 182 | // case protoreflect.DoubleKind: 183 | // case protoreflect.BytesKind: 184 | 185 | // 2. enum kinds 186 | if f.Kind() == protoreflect.EnumKind { 187 | g.enums = append(g.enums, f.Enum()) 188 | return nameWithParent(f.Enum()), true 189 | } 190 | 191 | // 3. message kinds 192 | if f.Kind() == protoreflect.MessageKind { 193 | if f.Message() == (&structpb.Value{}).ProtoReflect().Descriptor() { 194 | return "any", true 195 | } 196 | if f.Message() == (&anypb.Any{}).ProtoReflect().Descriptor() { 197 | return "any", true 198 | } 199 | if f.IsMap() { 200 | k, _ := g.fieldToBaseType(f.MapKey()) 201 | v, _ := g.fieldToBaseType(f.MapValue()) 202 | return fmt.Sprintf("{[key: %s]: %s}", k, v), true 203 | } 204 | if f.Cardinality() == protoreflect.Repeated { 205 | return nameWithParent(f.Message()) + "[]", false 206 | } 207 | return nameWithParent(f.Message()), false 208 | } 209 | 210 | return "", true 211 | } 212 | 213 | func nameWithParent(e protoreflect.Descriptor) string { 214 | name := e.Name() 215 | _, isFileParent := e.Parent().(protoreflect.FileDescriptor) 216 | if e.Parent() != nil && !isFileParent { 217 | return string(e.Parent().Name() + "_" + name) 218 | } 219 | return string(name) 220 | } 221 | 222 | type annotatedField struct { 223 | name string 224 | tsType string 225 | required bool 226 | repeated bool 227 | } 228 | 229 | func (a *annotatedField) generateCopiedValue() string { 230 | if a.repeated { 231 | return fmt.Sprintf("from.%s.slice()", a.name) 232 | } 233 | if a.tsType == "" || a.required { 234 | return fmt.Sprintf("from.%s", a.name) 235 | } 236 | return fmt.Sprintf("from.%s ? %s.copy(from.%s) : undefined", a.name, a.tsType, a.name) 237 | } 238 | 239 | func (g *Generator) generateCopyFunction(class string, fields []annotatedField) { 240 | g.p(2, "static copy(from: %s, to?: %s): %s {", class, class, class) 241 | g.p(4, "if (to) {") 242 | for _, field := range fields { 243 | g.p(6, "to.%s = %s;", field.name, field.generateCopiedValue()) 244 | } 245 | g.p(6, "return to;") 246 | g.p(4, "}") 247 | 248 | explicitCopy := []string{} 249 | for _, field := range fields { 250 | if field.tsType != "" { 251 | explicitCopy = append(explicitCopy, 252 | fmt.Sprintf("%s: %s,", field.name, field.generateCopiedValue())) 253 | } 254 | } 255 | if len(explicitCopy) == 0 { 256 | g.p(4, "return {...from};") 257 | } else { 258 | g.p(4, "return {") 259 | g.p(6, "...from,") 260 | for _, l := range explicitCopy { 261 | g.p(6, l) 262 | } 263 | g.p(4, "};") 264 | } 265 | g.p(2, "}") 266 | } 267 | -------------------------------------------------------------------------------- /generator_proto2_test.go: -------------------------------------------------------------------------------- 1 | package pbts 2 | 3 | import ( 4 | "bytes" 5 | "embed" 6 | "testing" 7 | 8 | "github.com/octavore/pbts/v2/internal/test" 9 | "github.com/stretchr/testify/assert" 10 | "google.golang.org/protobuf/types/known/structpb" 11 | ) 12 | 13 | //go:embed fixtures 14 | var fixtures embed.FS 15 | 16 | func loadFixture(name string) string { 17 | data, err := fixtures.ReadFile("fixtures/" + name) 18 | if err != nil { 19 | panic(err) 20 | } 21 | return string(data) 22 | } 23 | 24 | func TestOutput(t *testing.T) { 25 | buf := &bytes.Buffer{} 26 | g := NewGenerator(buf) 27 | g.RegisterMany(&test.TestMessage{}) 28 | g.Write() 29 | 30 | expected := loadFixture("TestMessage.ts") 31 | assert.Equal(t, expected, buf.String()) 32 | } 33 | 34 | func TestEnumOutput(t *testing.T) { 35 | buf := &bytes.Buffer{} 36 | g := NewGenerator(buf) 37 | g.RegisterMany(&test.TestEnumStruct{}) 38 | g.Write() 39 | 40 | expected := loadFixture("TestEnumStruct.ts") 41 | assert.Equal(t, expected, buf.String()) 42 | } 43 | 44 | func TestNativeEnumOutput(t *testing.T) { 45 | buf := &bytes.Buffer{} 46 | g := NewGenerator(buf) 47 | g.NativeEnums = true 48 | g.RegisterMany(&test.TestEnumStruct{}) 49 | g.Write() 50 | 51 | expected := loadFixture("TestNativeEnumStruct.ts") 52 | assert.Equal(t, expected, buf.String()) 53 | } 54 | 55 | func TestNewProtoStructOutput(t *testing.T) { 56 | buf := &bytes.Buffer{} 57 | g := NewGenerator(buf) 58 | g.NativeEnums = true 59 | g.RegisterMany(&structpb.Struct{}) 60 | g.Write() 61 | 62 | expected := loadFixture("TestProtoStruct.ts") 63 | assert.Equal(t, expected, buf.String()) 64 | } 65 | 66 | func TestOneofOutput(t *testing.T) { 67 | buf := &bytes.Buffer{} 68 | g := NewGenerator(buf) 69 | g.RegisterMany(&test.TestOneofStruct{}) 70 | g.Write() 71 | 72 | expected := loadFixture("TestOneOfStruct.ts") 73 | assert.Equal(t, expected, buf.String()) 74 | } 75 | -------------------------------------------------------------------------------- /generator_proto3_test.go: -------------------------------------------------------------------------------- 1 | package pbts 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/octavore/pbts/v2/internal/test" 8 | "github.com/stretchr/testify/assert" 9 | "google.golang.org/protobuf/encoding/protojson" 10 | ) 11 | 12 | func TestProto3Message(t *testing.T) { 13 | buf := &bytes.Buffer{} 14 | g := NewGenerator(buf) 15 | g.RegisterMany( 16 | &test.TestProto3Message{}, 17 | &test.TestProto3NestedMessage{}, 18 | ) 19 | g.Write() 20 | 21 | expected := loadFixture("TestProto3Message.ts") 22 | assert.Equal(t, expected, buf.String()) 23 | } 24 | 25 | func TestProtoJSON(t *testing.T) { 26 | j := &protojson.MarshalOptions{ 27 | EmitDefaultValues: true, 28 | } 29 | data, _ := j.Marshal(&test.TestProto3Message{}) 30 | // unfortunately EmitDefaultValues will output [] and {} for 31 | // empty lists and maps respectively and `optional repeated`/`optional map` is not supported 32 | expected := loadFixture("proto3message.json") 33 | assert.JSONEq(t, expected, string(data)) 34 | } 35 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/octavore/pbts/v2 2 | 3 | go 1.21 4 | 5 | require ( 6 | github.com/iancoleman/strcase v0.3.0 7 | github.com/stretchr/testify v1.8.4 8 | google.golang.org/protobuf v1.32.0 9 | ) 10 | 11 | require ( 12 | github.com/davecgh/go-spew v1.1.1 // indirect 13 | github.com/pmezard/go-difflib v1.0.0 // indirect 14 | gopkg.in/yaml.v3 v3.0.1 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 4 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 5 | github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= 6 | github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= 7 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 8 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 9 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= 10 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 11 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 12 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 13 | google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= 14 | google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 15 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 16 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 17 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 18 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 19 | -------------------------------------------------------------------------------- /internal/test/proto2_test.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.32.0 4 | // protoc v4.25.2 5 | // source: internal/test/proto2_test.proto 6 | 7 | package test 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | structpb "google.golang.org/protobuf/types/known/structpb" 13 | reflect "reflect" 14 | sync "sync" 15 | ) 16 | 17 | const ( 18 | // Verify that this generated code is sufficiently up-to-date. 19 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 20 | // Verify that runtime/protoimpl is sufficiently up-to-date. 21 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 22 | ) 23 | 24 | type TestEnumStruct_TestEnum int32 25 | 26 | const ( 27 | TestEnumStruct_unknown TestEnumStruct_TestEnum = 0 28 | TestEnumStruct_foo TestEnumStruct_TestEnum = 1 29 | TestEnumStruct_bar TestEnumStruct_TestEnum = 2 30 | ) 31 | 32 | // Enum value maps for TestEnumStruct_TestEnum. 33 | var ( 34 | TestEnumStruct_TestEnum_name = map[int32]string{ 35 | 0: "unknown", 36 | 1: "foo", 37 | 2: "bar", 38 | } 39 | TestEnumStruct_TestEnum_value = map[string]int32{ 40 | "unknown": 0, 41 | "foo": 1, 42 | "bar": 2, 43 | } 44 | ) 45 | 46 | func (x TestEnumStruct_TestEnum) Enum() *TestEnumStruct_TestEnum { 47 | p := new(TestEnumStruct_TestEnum) 48 | *p = x 49 | return p 50 | } 51 | 52 | func (x TestEnumStruct_TestEnum) String() string { 53 | return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) 54 | } 55 | 56 | func (TestEnumStruct_TestEnum) Descriptor() protoreflect.EnumDescriptor { 57 | return file_internal_test_proto2_test_proto_enumTypes[0].Descriptor() 58 | } 59 | 60 | func (TestEnumStruct_TestEnum) Type() protoreflect.EnumType { 61 | return &file_internal_test_proto2_test_proto_enumTypes[0] 62 | } 63 | 64 | func (x TestEnumStruct_TestEnum) Number() protoreflect.EnumNumber { 65 | return protoreflect.EnumNumber(x) 66 | } 67 | 68 | // Deprecated: Do not use. 69 | func (x *TestEnumStruct_TestEnum) UnmarshalJSON(b []byte) error { 70 | num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) 71 | if err != nil { 72 | return err 73 | } 74 | *x = TestEnumStruct_TestEnum(num) 75 | return nil 76 | } 77 | 78 | // Deprecated: Use TestEnumStruct_TestEnum.Descriptor instead. 79 | func (TestEnumStruct_TestEnum) EnumDescriptor() ([]byte, []int) { 80 | return file_internal_test_proto2_test_proto_rawDescGZIP(), []int{4, 0} 81 | } 82 | 83 | type TestMessage struct { 84 | state protoimpl.MessageState 85 | sizeCache protoimpl.SizeCache 86 | unknownFields protoimpl.UnknownFields 87 | 88 | StrField *string `protobuf:"bytes,1,opt,name=str_field,json=strField" json:"str_field,omitempty"` 89 | Int32Field *int32 `protobuf:"varint,2,opt,name=int32_field,json=int32Field" json:"int32_field,omitempty"` 90 | Int64Field *int64 `protobuf:"varint,3,opt,name=int64_field,json=int64Field" json:"int64_field,omitempty"` 91 | StrList []string `protobuf:"bytes,4,rep,name=str_list,json=strList" json:"str_list,omitempty"` 92 | Metadata map[string]int64 `protobuf:"bytes,10,rep,name=metadata" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` 93 | } 94 | 95 | func (x *TestMessage) Reset() { 96 | *x = TestMessage{} 97 | if protoimpl.UnsafeEnabled { 98 | mi := &file_internal_test_proto2_test_proto_msgTypes[0] 99 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 100 | ms.StoreMessageInfo(mi) 101 | } 102 | } 103 | 104 | func (x *TestMessage) String() string { 105 | return protoimpl.X.MessageStringOf(x) 106 | } 107 | 108 | func (*TestMessage) ProtoMessage() {} 109 | 110 | func (x *TestMessage) ProtoReflect() protoreflect.Message { 111 | mi := &file_internal_test_proto2_test_proto_msgTypes[0] 112 | if protoimpl.UnsafeEnabled && x != nil { 113 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 114 | if ms.LoadMessageInfo() == nil { 115 | ms.StoreMessageInfo(mi) 116 | } 117 | return ms 118 | } 119 | return mi.MessageOf(x) 120 | } 121 | 122 | // Deprecated: Use TestMessage.ProtoReflect.Descriptor instead. 123 | func (*TestMessage) Descriptor() ([]byte, []int) { 124 | return file_internal_test_proto2_test_proto_rawDescGZIP(), []int{0} 125 | } 126 | 127 | func (x *TestMessage) GetStrField() string { 128 | if x != nil && x.StrField != nil { 129 | return *x.StrField 130 | } 131 | return "" 132 | } 133 | 134 | func (x *TestMessage) GetInt32Field() int32 { 135 | if x != nil && x.Int32Field != nil { 136 | return *x.Int32Field 137 | } 138 | return 0 139 | } 140 | 141 | func (x *TestMessage) GetInt64Field() int64 { 142 | if x != nil && x.Int64Field != nil { 143 | return *x.Int64Field 144 | } 145 | return 0 146 | } 147 | 148 | func (x *TestMessage) GetStrList() []string { 149 | if x != nil { 150 | return x.StrList 151 | } 152 | return nil 153 | } 154 | 155 | func (x *TestMessage) GetMetadata() map[string]int64 { 156 | if x != nil { 157 | return x.Metadata 158 | } 159 | return nil 160 | } 161 | 162 | type TestNestedMessage struct { 163 | state protoimpl.MessageState 164 | sizeCache protoimpl.SizeCache 165 | unknownFields protoimpl.UnknownFields 166 | 167 | StrField *string `protobuf:"bytes,1,opt,name=str_field,json=strField" json:"str_field,omitempty"` 168 | } 169 | 170 | func (x *TestNestedMessage) Reset() { 171 | *x = TestNestedMessage{} 172 | if protoimpl.UnsafeEnabled { 173 | mi := &file_internal_test_proto2_test_proto_msgTypes[1] 174 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 175 | ms.StoreMessageInfo(mi) 176 | } 177 | } 178 | 179 | func (x *TestNestedMessage) String() string { 180 | return protoimpl.X.MessageStringOf(x) 181 | } 182 | 183 | func (*TestNestedMessage) ProtoMessage() {} 184 | 185 | func (x *TestNestedMessage) ProtoReflect() protoreflect.Message { 186 | mi := &file_internal_test_proto2_test_proto_msgTypes[1] 187 | if protoimpl.UnsafeEnabled && x != nil { 188 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 189 | if ms.LoadMessageInfo() == nil { 190 | ms.StoreMessageInfo(mi) 191 | } 192 | return ms 193 | } 194 | return mi.MessageOf(x) 195 | } 196 | 197 | // Deprecated: Use TestNestedMessage.ProtoReflect.Descriptor instead. 198 | func (*TestNestedMessage) Descriptor() ([]byte, []int) { 199 | return file_internal_test_proto2_test_proto_rawDescGZIP(), []int{1} 200 | } 201 | 202 | func (x *TestNestedMessage) GetStrField() string { 203 | if x != nil && x.StrField != nil { 204 | return *x.StrField 205 | } 206 | return "" 207 | } 208 | 209 | type Filter struct { 210 | state protoimpl.MessageState 211 | sizeCache protoimpl.SizeCache 212 | unknownFields protoimpl.UnknownFields 213 | 214 | Id *string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` 215 | Kind *string `protobuf:"bytes,2,opt,name=kind" json:"kind,omitempty"` 216 | Op *string `protobuf:"bytes,3,opt,name=op" json:"op,omitempty"` 217 | } 218 | 219 | func (x *Filter) Reset() { 220 | *x = Filter{} 221 | if protoimpl.UnsafeEnabled { 222 | mi := &file_internal_test_proto2_test_proto_msgTypes[2] 223 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 224 | ms.StoreMessageInfo(mi) 225 | } 226 | } 227 | 228 | func (x *Filter) String() string { 229 | return protoimpl.X.MessageStringOf(x) 230 | } 231 | 232 | func (*Filter) ProtoMessage() {} 233 | 234 | func (x *Filter) ProtoReflect() protoreflect.Message { 235 | mi := &file_internal_test_proto2_test_proto_msgTypes[2] 236 | if protoimpl.UnsafeEnabled && x != nil { 237 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 238 | if ms.LoadMessageInfo() == nil { 239 | ms.StoreMessageInfo(mi) 240 | } 241 | return ms 242 | } 243 | return mi.MessageOf(x) 244 | } 245 | 246 | // Deprecated: Use Filter.ProtoReflect.Descriptor instead. 247 | func (*Filter) Descriptor() ([]byte, []int) { 248 | return file_internal_test_proto2_test_proto_rawDescGZIP(), []int{2} 249 | } 250 | 251 | func (x *Filter) GetId() string { 252 | if x != nil && x.Id != nil { 253 | return *x.Id 254 | } 255 | return "" 256 | } 257 | 258 | func (x *Filter) GetKind() string { 259 | if x != nil && x.Kind != nil { 260 | return *x.Kind 261 | } 262 | return "" 263 | } 264 | 265 | func (x *Filter) GetOp() string { 266 | if x != nil && x.Op != nil { 267 | return *x.Op 268 | } 269 | return "" 270 | } 271 | 272 | type TestGoogleStruct struct { 273 | state protoimpl.MessageState 274 | sizeCache protoimpl.SizeCache 275 | unknownFields protoimpl.UnknownFields 276 | 277 | StructField *structpb.Struct `protobuf:"bytes,1,opt,name=struct_field,json=structField" json:"struct_field,omitempty"` 278 | } 279 | 280 | func (x *TestGoogleStruct) Reset() { 281 | *x = TestGoogleStruct{} 282 | if protoimpl.UnsafeEnabled { 283 | mi := &file_internal_test_proto2_test_proto_msgTypes[3] 284 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 285 | ms.StoreMessageInfo(mi) 286 | } 287 | } 288 | 289 | func (x *TestGoogleStruct) String() string { 290 | return protoimpl.X.MessageStringOf(x) 291 | } 292 | 293 | func (*TestGoogleStruct) ProtoMessage() {} 294 | 295 | func (x *TestGoogleStruct) ProtoReflect() protoreflect.Message { 296 | mi := &file_internal_test_proto2_test_proto_msgTypes[3] 297 | if protoimpl.UnsafeEnabled && x != nil { 298 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 299 | if ms.LoadMessageInfo() == nil { 300 | ms.StoreMessageInfo(mi) 301 | } 302 | return ms 303 | } 304 | return mi.MessageOf(x) 305 | } 306 | 307 | // Deprecated: Use TestGoogleStruct.ProtoReflect.Descriptor instead. 308 | func (*TestGoogleStruct) Descriptor() ([]byte, []int) { 309 | return file_internal_test_proto2_test_proto_rawDescGZIP(), []int{3} 310 | } 311 | 312 | func (x *TestGoogleStruct) GetStructField() *structpb.Struct { 313 | if x != nil { 314 | return x.StructField 315 | } 316 | return nil 317 | } 318 | 319 | type TestEnumStruct struct { 320 | state protoimpl.MessageState 321 | sizeCache protoimpl.SizeCache 322 | unknownFields protoimpl.UnknownFields 323 | 324 | EnumField *TestEnumStruct_TestEnum `protobuf:"varint,1,opt,name=enum_field,json=enumField,enum=pbts.TestEnumStruct_TestEnum" json:"enum_field,omitempty"` 325 | } 326 | 327 | func (x *TestEnumStruct) Reset() { 328 | *x = TestEnumStruct{} 329 | if protoimpl.UnsafeEnabled { 330 | mi := &file_internal_test_proto2_test_proto_msgTypes[4] 331 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 332 | ms.StoreMessageInfo(mi) 333 | } 334 | } 335 | 336 | func (x *TestEnumStruct) String() string { 337 | return protoimpl.X.MessageStringOf(x) 338 | } 339 | 340 | func (*TestEnumStruct) ProtoMessage() {} 341 | 342 | func (x *TestEnumStruct) ProtoReflect() protoreflect.Message { 343 | mi := &file_internal_test_proto2_test_proto_msgTypes[4] 344 | if protoimpl.UnsafeEnabled && x != nil { 345 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 346 | if ms.LoadMessageInfo() == nil { 347 | ms.StoreMessageInfo(mi) 348 | } 349 | return ms 350 | } 351 | return mi.MessageOf(x) 352 | } 353 | 354 | // Deprecated: Use TestEnumStruct.ProtoReflect.Descriptor instead. 355 | func (*TestEnumStruct) Descriptor() ([]byte, []int) { 356 | return file_internal_test_proto2_test_proto_rawDescGZIP(), []int{4} 357 | } 358 | 359 | func (x *TestEnumStruct) GetEnumField() TestEnumStruct_TestEnum { 360 | if x != nil && x.EnumField != nil { 361 | return *x.EnumField 362 | } 363 | return TestEnumStruct_unknown 364 | } 365 | 366 | type TestOneofStruct struct { 367 | state protoimpl.MessageState 368 | sizeCache protoimpl.SizeCache 369 | unknownFields protoimpl.UnknownFields 370 | 371 | // Types that are assignable to Instrument: 372 | // 373 | // *TestOneofStruct_Stock_ 374 | // *TestOneofStruct_Currency_ 375 | // *TestOneofStruct_StrField 376 | Instrument isTestOneofStruct_Instrument `protobuf_oneof:"instrument"` 377 | } 378 | 379 | func (x *TestOneofStruct) Reset() { 380 | *x = TestOneofStruct{} 381 | if protoimpl.UnsafeEnabled { 382 | mi := &file_internal_test_proto2_test_proto_msgTypes[5] 383 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 384 | ms.StoreMessageInfo(mi) 385 | } 386 | } 387 | 388 | func (x *TestOneofStruct) String() string { 389 | return protoimpl.X.MessageStringOf(x) 390 | } 391 | 392 | func (*TestOneofStruct) ProtoMessage() {} 393 | 394 | func (x *TestOneofStruct) ProtoReflect() protoreflect.Message { 395 | mi := &file_internal_test_proto2_test_proto_msgTypes[5] 396 | if protoimpl.UnsafeEnabled && x != nil { 397 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 398 | if ms.LoadMessageInfo() == nil { 399 | ms.StoreMessageInfo(mi) 400 | } 401 | return ms 402 | } 403 | return mi.MessageOf(x) 404 | } 405 | 406 | // Deprecated: Use TestOneofStruct.ProtoReflect.Descriptor instead. 407 | func (*TestOneofStruct) Descriptor() ([]byte, []int) { 408 | return file_internal_test_proto2_test_proto_rawDescGZIP(), []int{5} 409 | } 410 | 411 | func (m *TestOneofStruct) GetInstrument() isTestOneofStruct_Instrument { 412 | if m != nil { 413 | return m.Instrument 414 | } 415 | return nil 416 | } 417 | 418 | func (x *TestOneofStruct) GetStock() *TestOneofStruct_Stock { 419 | if x, ok := x.GetInstrument().(*TestOneofStruct_Stock_); ok { 420 | return x.Stock 421 | } 422 | return nil 423 | } 424 | 425 | func (x *TestOneofStruct) GetCurrency() *TestOneofStruct_Currency { 426 | if x, ok := x.GetInstrument().(*TestOneofStruct_Currency_); ok { 427 | return x.Currency 428 | } 429 | return nil 430 | } 431 | 432 | func (x *TestOneofStruct) GetStrField() string { 433 | if x, ok := x.GetInstrument().(*TestOneofStruct_StrField); ok { 434 | return x.StrField 435 | } 436 | return "" 437 | } 438 | 439 | type isTestOneofStruct_Instrument interface { 440 | isTestOneofStruct_Instrument() 441 | } 442 | 443 | type TestOneofStruct_Stock_ struct { 444 | Stock *TestOneofStruct_Stock `protobuf:"bytes,1,opt,name=stock,oneof"` 445 | } 446 | 447 | type TestOneofStruct_Currency_ struct { 448 | Currency *TestOneofStruct_Currency `protobuf:"bytes,2,opt,name=currency,oneof"` 449 | } 450 | 451 | type TestOneofStruct_StrField struct { 452 | StrField string `protobuf:"bytes,3,opt,name=str_field,json=strField,oneof"` 453 | } 454 | 455 | func (*TestOneofStruct_Stock_) isTestOneofStruct_Instrument() {} 456 | 457 | func (*TestOneofStruct_Currency_) isTestOneofStruct_Instrument() {} 458 | 459 | func (*TestOneofStruct_StrField) isTestOneofStruct_Instrument() {} 460 | 461 | type TestOneofStruct_Stock struct { 462 | state protoimpl.MessageState 463 | sizeCache protoimpl.SizeCache 464 | unknownFields protoimpl.UnknownFields 465 | 466 | Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` 467 | } 468 | 469 | func (x *TestOneofStruct_Stock) Reset() { 470 | *x = TestOneofStruct_Stock{} 471 | if protoimpl.UnsafeEnabled { 472 | mi := &file_internal_test_proto2_test_proto_msgTypes[7] 473 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 474 | ms.StoreMessageInfo(mi) 475 | } 476 | } 477 | 478 | func (x *TestOneofStruct_Stock) String() string { 479 | return protoimpl.X.MessageStringOf(x) 480 | } 481 | 482 | func (*TestOneofStruct_Stock) ProtoMessage() {} 483 | 484 | func (x *TestOneofStruct_Stock) ProtoReflect() protoreflect.Message { 485 | mi := &file_internal_test_proto2_test_proto_msgTypes[7] 486 | if protoimpl.UnsafeEnabled && x != nil { 487 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 488 | if ms.LoadMessageInfo() == nil { 489 | ms.StoreMessageInfo(mi) 490 | } 491 | return ms 492 | } 493 | return mi.MessageOf(x) 494 | } 495 | 496 | // Deprecated: Use TestOneofStruct_Stock.ProtoReflect.Descriptor instead. 497 | func (*TestOneofStruct_Stock) Descriptor() ([]byte, []int) { 498 | return file_internal_test_proto2_test_proto_rawDescGZIP(), []int{5, 0} 499 | } 500 | 501 | func (x *TestOneofStruct_Stock) GetName() string { 502 | if x != nil && x.Name != nil { 503 | return *x.Name 504 | } 505 | return "" 506 | } 507 | 508 | type TestOneofStruct_Currency struct { 509 | state protoimpl.MessageState 510 | sizeCache protoimpl.SizeCache 511 | unknownFields protoimpl.UnknownFields 512 | 513 | Country *string `protobuf:"bytes,1,opt,name=country" json:"country,omitempty"` 514 | ShortCode *string `protobuf:"bytes,2,opt,name=short_code,json=shortCode" json:"short_code,omitempty"` 515 | } 516 | 517 | func (x *TestOneofStruct_Currency) Reset() { 518 | *x = TestOneofStruct_Currency{} 519 | if protoimpl.UnsafeEnabled { 520 | mi := &file_internal_test_proto2_test_proto_msgTypes[8] 521 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 522 | ms.StoreMessageInfo(mi) 523 | } 524 | } 525 | 526 | func (x *TestOneofStruct_Currency) String() string { 527 | return protoimpl.X.MessageStringOf(x) 528 | } 529 | 530 | func (*TestOneofStruct_Currency) ProtoMessage() {} 531 | 532 | func (x *TestOneofStruct_Currency) ProtoReflect() protoreflect.Message { 533 | mi := &file_internal_test_proto2_test_proto_msgTypes[8] 534 | if protoimpl.UnsafeEnabled && x != nil { 535 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 536 | if ms.LoadMessageInfo() == nil { 537 | ms.StoreMessageInfo(mi) 538 | } 539 | return ms 540 | } 541 | return mi.MessageOf(x) 542 | } 543 | 544 | // Deprecated: Use TestOneofStruct_Currency.ProtoReflect.Descriptor instead. 545 | func (*TestOneofStruct_Currency) Descriptor() ([]byte, []int) { 546 | return file_internal_test_proto2_test_proto_rawDescGZIP(), []int{5, 1} 547 | } 548 | 549 | func (x *TestOneofStruct_Currency) GetCountry() string { 550 | if x != nil && x.Country != nil { 551 | return *x.Country 552 | } 553 | return "" 554 | } 555 | 556 | func (x *TestOneofStruct_Currency) GetShortCode() string { 557 | if x != nil && x.ShortCode != nil { 558 | return *x.ShortCode 559 | } 560 | return "" 561 | } 562 | 563 | var File_internal_test_proto2_test_proto protoreflect.FileDescriptor 564 | 565 | var file_internal_test_proto2_test_proto_rawDesc = []byte{ 566 | 0x0a, 0x1f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2f, 567 | 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 568 | 0x6f, 0x12, 0x04, 0x70, 0x62, 0x74, 0x73, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 569 | 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 570 | 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x81, 0x02, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 571 | 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x74, 0x72, 0x5f, 0x66, 0x69, 0x65, 572 | 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x72, 0x46, 0x69, 0x65, 573 | 0x6c, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x66, 0x69, 0x65, 0x6c, 574 | 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 575 | 0x65, 0x6c, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x66, 0x69, 0x65, 576 | 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x46, 577 | 0x69, 0x65, 0x6c, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x74, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 578 | 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x74, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 579 | 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0a, 0x20, 0x03, 0x28, 580 | 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x62, 0x74, 0x73, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 581 | 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 582 | 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 583 | 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 584 | 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 585 | 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 586 | 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x30, 0x0a, 0x11, 0x54, 0x65, 0x73, 587 | 0x74, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1b, 588 | 0x0a, 0x09, 0x73, 0x74, 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 589 | 0x09, 0x52, 0x08, 0x73, 0x74, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x3c, 0x0a, 0x06, 0x46, 590 | 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 591 | 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 592 | 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x70, 0x18, 593 | 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x6f, 0x70, 0x22, 0x4e, 0x0a, 0x10, 0x54, 0x65, 0x73, 594 | 0x74, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x3a, 0x0a, 595 | 0x0c, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 596 | 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 597 | 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0b, 0x73, 0x74, 598 | 0x72, 0x75, 0x63, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x79, 0x0a, 0x0e, 0x54, 0x65, 0x73, 599 | 0x74, 0x45, 0x6e, 0x75, 0x6d, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x3c, 0x0a, 0x0a, 0x65, 600 | 0x6e, 0x75, 0x6d, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 601 | 0x1d, 0x2e, 0x70, 0x62, 0x74, 0x73, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x45, 0x6e, 0x75, 0x6d, 0x53, 602 | 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x09, 603 | 0x65, 0x6e, 0x75, 0x6d, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x29, 0x0a, 0x08, 0x54, 0x65, 0x73, 604 | 0x74, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0b, 0x0a, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 605 | 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x62, 606 | 0x61, 0x72, 0x10, 0x02, 0x22, 0x93, 0x02, 0x0a, 0x0f, 0x54, 0x65, 0x73, 0x74, 0x4f, 0x6e, 0x65, 607 | 0x6f, 0x66, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x33, 0x0a, 0x05, 0x73, 0x74, 0x6f, 0x63, 608 | 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x62, 0x74, 0x73, 0x2e, 0x54, 609 | 0x65, 0x73, 0x74, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x53, 610 | 0x74, 0x6f, 0x63, 0x6b, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x12, 0x3c, 0x0a, 611 | 0x08, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 612 | 0x1e, 0x2e, 0x70, 0x62, 0x74, 0x73, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 613 | 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x48, 614 | 0x00, 0x52, 0x08, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x1d, 0x0a, 0x09, 0x73, 615 | 0x74, 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 616 | 0x52, 0x08, 0x73, 0x74, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x1a, 0x1b, 0x0a, 0x05, 0x53, 0x74, 617 | 0x6f, 0x63, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 618 | 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x1a, 0x43, 0x0a, 0x08, 0x43, 0x75, 0x72, 0x72, 0x65, 619 | 0x6e, 0x63, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x01, 620 | 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x1d, 0x0a, 621 | 0x0a, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 622 | 0x09, 0x52, 0x09, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 623 | 0x69, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, 624 | 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x63, 0x74, 0x61, 0x76, 0x6f, 0x72, 625 | 0x65, 0x2f, 0x70, 0x62, 0x74, 0x73, 0x2f, 0x76, 0x32, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 626 | 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 627 | } 628 | 629 | var ( 630 | file_internal_test_proto2_test_proto_rawDescOnce sync.Once 631 | file_internal_test_proto2_test_proto_rawDescData = file_internal_test_proto2_test_proto_rawDesc 632 | ) 633 | 634 | func file_internal_test_proto2_test_proto_rawDescGZIP() []byte { 635 | file_internal_test_proto2_test_proto_rawDescOnce.Do(func() { 636 | file_internal_test_proto2_test_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_test_proto2_test_proto_rawDescData) 637 | }) 638 | return file_internal_test_proto2_test_proto_rawDescData 639 | } 640 | 641 | var file_internal_test_proto2_test_proto_enumTypes = make([]protoimpl.EnumInfo, 1) 642 | var file_internal_test_proto2_test_proto_msgTypes = make([]protoimpl.MessageInfo, 9) 643 | var file_internal_test_proto2_test_proto_goTypes = []interface{}{ 644 | (TestEnumStruct_TestEnum)(0), // 0: pbts.TestEnumStruct.TestEnum 645 | (*TestMessage)(nil), // 1: pbts.TestMessage 646 | (*TestNestedMessage)(nil), // 2: pbts.TestNestedMessage 647 | (*Filter)(nil), // 3: pbts.Filter 648 | (*TestGoogleStruct)(nil), // 4: pbts.TestGoogleStruct 649 | (*TestEnumStruct)(nil), // 5: pbts.TestEnumStruct 650 | (*TestOneofStruct)(nil), // 6: pbts.TestOneofStruct 651 | nil, // 7: pbts.TestMessage.MetadataEntry 652 | (*TestOneofStruct_Stock)(nil), // 8: pbts.TestOneofStruct.Stock 653 | (*TestOneofStruct_Currency)(nil), // 9: pbts.TestOneofStruct.Currency 654 | (*structpb.Struct)(nil), // 10: google.protobuf.Struct 655 | } 656 | var file_internal_test_proto2_test_proto_depIdxs = []int32{ 657 | 7, // 0: pbts.TestMessage.metadata:type_name -> pbts.TestMessage.MetadataEntry 658 | 10, // 1: pbts.TestGoogleStruct.struct_field:type_name -> google.protobuf.Struct 659 | 0, // 2: pbts.TestEnumStruct.enum_field:type_name -> pbts.TestEnumStruct.TestEnum 660 | 8, // 3: pbts.TestOneofStruct.stock:type_name -> pbts.TestOneofStruct.Stock 661 | 9, // 4: pbts.TestOneofStruct.currency:type_name -> pbts.TestOneofStruct.Currency 662 | 5, // [5:5] is the sub-list for method output_type 663 | 5, // [5:5] is the sub-list for method input_type 664 | 5, // [5:5] is the sub-list for extension type_name 665 | 5, // [5:5] is the sub-list for extension extendee 666 | 0, // [0:5] is the sub-list for field type_name 667 | } 668 | 669 | func init() { file_internal_test_proto2_test_proto_init() } 670 | func file_internal_test_proto2_test_proto_init() { 671 | if File_internal_test_proto2_test_proto != nil { 672 | return 673 | } 674 | if !protoimpl.UnsafeEnabled { 675 | file_internal_test_proto2_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 676 | switch v := v.(*TestMessage); i { 677 | case 0: 678 | return &v.state 679 | case 1: 680 | return &v.sizeCache 681 | case 2: 682 | return &v.unknownFields 683 | default: 684 | return nil 685 | } 686 | } 687 | file_internal_test_proto2_test_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 688 | switch v := v.(*TestNestedMessage); i { 689 | case 0: 690 | return &v.state 691 | case 1: 692 | return &v.sizeCache 693 | case 2: 694 | return &v.unknownFields 695 | default: 696 | return nil 697 | } 698 | } 699 | file_internal_test_proto2_test_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { 700 | switch v := v.(*Filter); i { 701 | case 0: 702 | return &v.state 703 | case 1: 704 | return &v.sizeCache 705 | case 2: 706 | return &v.unknownFields 707 | default: 708 | return nil 709 | } 710 | } 711 | file_internal_test_proto2_test_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { 712 | switch v := v.(*TestGoogleStruct); i { 713 | case 0: 714 | return &v.state 715 | case 1: 716 | return &v.sizeCache 717 | case 2: 718 | return &v.unknownFields 719 | default: 720 | return nil 721 | } 722 | } 723 | file_internal_test_proto2_test_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { 724 | switch v := v.(*TestEnumStruct); i { 725 | case 0: 726 | return &v.state 727 | case 1: 728 | return &v.sizeCache 729 | case 2: 730 | return &v.unknownFields 731 | default: 732 | return nil 733 | } 734 | } 735 | file_internal_test_proto2_test_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { 736 | switch v := v.(*TestOneofStruct); i { 737 | case 0: 738 | return &v.state 739 | case 1: 740 | return &v.sizeCache 741 | case 2: 742 | return &v.unknownFields 743 | default: 744 | return nil 745 | } 746 | } 747 | file_internal_test_proto2_test_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { 748 | switch v := v.(*TestOneofStruct_Stock); i { 749 | case 0: 750 | return &v.state 751 | case 1: 752 | return &v.sizeCache 753 | case 2: 754 | return &v.unknownFields 755 | default: 756 | return nil 757 | } 758 | } 759 | file_internal_test_proto2_test_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { 760 | switch v := v.(*TestOneofStruct_Currency); i { 761 | case 0: 762 | return &v.state 763 | case 1: 764 | return &v.sizeCache 765 | case 2: 766 | return &v.unknownFields 767 | default: 768 | return nil 769 | } 770 | } 771 | } 772 | file_internal_test_proto2_test_proto_msgTypes[5].OneofWrappers = []interface{}{ 773 | (*TestOneofStruct_Stock_)(nil), 774 | (*TestOneofStruct_Currency_)(nil), 775 | (*TestOneofStruct_StrField)(nil), 776 | } 777 | type x struct{} 778 | out := protoimpl.TypeBuilder{ 779 | File: protoimpl.DescBuilder{ 780 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 781 | RawDescriptor: file_internal_test_proto2_test_proto_rawDesc, 782 | NumEnums: 1, 783 | NumMessages: 9, 784 | NumExtensions: 0, 785 | NumServices: 0, 786 | }, 787 | GoTypes: file_internal_test_proto2_test_proto_goTypes, 788 | DependencyIndexes: file_internal_test_proto2_test_proto_depIdxs, 789 | EnumInfos: file_internal_test_proto2_test_proto_enumTypes, 790 | MessageInfos: file_internal_test_proto2_test_proto_msgTypes, 791 | }.Build() 792 | File_internal_test_proto2_test_proto = out.File 793 | file_internal_test_proto2_test_proto_rawDesc = nil 794 | file_internal_test_proto2_test_proto_goTypes = nil 795 | file_internal_test_proto2_test_proto_depIdxs = nil 796 | } 797 | -------------------------------------------------------------------------------- /internal/test/proto2_test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | package pbts; 4 | 5 | option go_package = "github.com/octavore/pbts/v2/internal/test"; 6 | 7 | import "google/protobuf/struct.proto"; 8 | 9 | message TestMessage { 10 | optional string str_field = 1; 11 | optional int32 int32_field = 2; 12 | optional int64 int64_field = 3; 13 | repeated string str_list = 4; 14 | map metadata = 10; 15 | } 16 | 17 | message TestNestedMessage { 18 | optional string str_field = 1; 19 | } 20 | 21 | message Filter { 22 | optional string id = 1; 23 | optional string kind = 2; 24 | optional string op = 3; 25 | } 26 | 27 | message TestGoogleStruct { 28 | optional google.protobuf.Struct struct_field = 1; 29 | } 30 | 31 | message TestEnumStruct { 32 | enum TestEnum { 33 | unknown = 0; 34 | foo = 1; 35 | bar = 2; 36 | } 37 | optional TestEnum enum_field = 1; 38 | } 39 | 40 | message TestOneofStruct { 41 | message Stock { 42 | optional string name = 1; 43 | } 44 | message Currency { 45 | optional string country = 1; 46 | optional string short_code = 2; 47 | } 48 | oneof instrument { 49 | Stock stock = 1; 50 | Currency currency = 2; 51 | string str_field = 3; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /internal/test/proto3_test.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.32.0 4 | // protoc v4.25.2 5 | // source: internal/test/proto3_test.proto 6 | 7 | package test 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | structpb "google.golang.org/protobuf/types/known/structpb" 13 | reflect "reflect" 14 | sync "sync" 15 | ) 16 | 17 | const ( 18 | // Verify that this generated code is sufficiently up-to-date. 19 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 20 | // Verify that runtime/protoimpl is sufficiently up-to-date. 21 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 22 | ) 23 | 24 | type TestProto3EnumStruct_TestProto3Enum int32 25 | 26 | const ( 27 | TestProto3EnumStruct_unknown TestProto3EnumStruct_TestProto3Enum = 0 28 | TestProto3EnumStruct_foo TestProto3EnumStruct_TestProto3Enum = 1 29 | TestProto3EnumStruct_bar TestProto3EnumStruct_TestProto3Enum = 2 30 | ) 31 | 32 | // Enum value maps for TestProto3EnumStruct_TestProto3Enum. 33 | var ( 34 | TestProto3EnumStruct_TestProto3Enum_name = map[int32]string{ 35 | 0: "unknown", 36 | 1: "foo", 37 | 2: "bar", 38 | } 39 | TestProto3EnumStruct_TestProto3Enum_value = map[string]int32{ 40 | "unknown": 0, 41 | "foo": 1, 42 | "bar": 2, 43 | } 44 | ) 45 | 46 | func (x TestProto3EnumStruct_TestProto3Enum) Enum() *TestProto3EnumStruct_TestProto3Enum { 47 | p := new(TestProto3EnumStruct_TestProto3Enum) 48 | *p = x 49 | return p 50 | } 51 | 52 | func (x TestProto3EnumStruct_TestProto3Enum) String() string { 53 | return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) 54 | } 55 | 56 | func (TestProto3EnumStruct_TestProto3Enum) Descriptor() protoreflect.EnumDescriptor { 57 | return file_internal_test_proto3_test_proto_enumTypes[0].Descriptor() 58 | } 59 | 60 | func (TestProto3EnumStruct_TestProto3Enum) Type() protoreflect.EnumType { 61 | return &file_internal_test_proto3_test_proto_enumTypes[0] 62 | } 63 | 64 | func (x TestProto3EnumStruct_TestProto3Enum) Number() protoreflect.EnumNumber { 65 | return protoreflect.EnumNumber(x) 66 | } 67 | 68 | // Deprecated: Use TestProto3EnumStruct_TestProto3Enum.Descriptor instead. 69 | func (TestProto3EnumStruct_TestProto3Enum) EnumDescriptor() ([]byte, []int) { 70 | return file_internal_test_proto3_test_proto_rawDescGZIP(), []int{3, 0} 71 | } 72 | 73 | type TestProto3Message struct { 74 | state protoimpl.MessageState 75 | sizeCache protoimpl.SizeCache 76 | unknownFields protoimpl.UnknownFields 77 | 78 | StrField string `protobuf:"bytes,1,opt,name=str_field,json=strField,proto3" json:"str_field,omitempty"` 79 | OptStrField *string `protobuf:"bytes,2,opt,name=opt_str_field,json=optStrField,proto3,oneof" json:"opt_str_field,omitempty"` 80 | Int32Field int32 `protobuf:"varint,3,opt,name=int32_field,json=int32Field,proto3" json:"int32_field,omitempty"` 81 | Int64Field int64 `protobuf:"varint,4,opt,name=int64_field,json=int64Field,proto3" json:"int64_field,omitempty"` 82 | StrList []string `protobuf:"bytes,5,rep,name=str_list,json=strList,proto3" json:"str_list,omitempty"` 83 | Nested *TestProto3NestedMessage `protobuf:"bytes,6,opt,name=nested,proto3" json:"nested,omitempty"` 84 | NestedList []*TestProto3NestedMessage `protobuf:"bytes,7,rep,name=nested_list,json=nestedList,proto3" json:"nested_list,omitempty"` 85 | Metadata map[string]int64 `protobuf:"bytes,10,rep,name=metadata,proto3" json:"metadata,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` 86 | } 87 | 88 | func (x *TestProto3Message) Reset() { 89 | *x = TestProto3Message{} 90 | if protoimpl.UnsafeEnabled { 91 | mi := &file_internal_test_proto3_test_proto_msgTypes[0] 92 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 93 | ms.StoreMessageInfo(mi) 94 | } 95 | } 96 | 97 | func (x *TestProto3Message) String() string { 98 | return protoimpl.X.MessageStringOf(x) 99 | } 100 | 101 | func (*TestProto3Message) ProtoMessage() {} 102 | 103 | func (x *TestProto3Message) ProtoReflect() protoreflect.Message { 104 | mi := &file_internal_test_proto3_test_proto_msgTypes[0] 105 | if protoimpl.UnsafeEnabled && x != nil { 106 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 107 | if ms.LoadMessageInfo() == nil { 108 | ms.StoreMessageInfo(mi) 109 | } 110 | return ms 111 | } 112 | return mi.MessageOf(x) 113 | } 114 | 115 | // Deprecated: Use TestProto3Message.ProtoReflect.Descriptor instead. 116 | func (*TestProto3Message) Descriptor() ([]byte, []int) { 117 | return file_internal_test_proto3_test_proto_rawDescGZIP(), []int{0} 118 | } 119 | 120 | func (x *TestProto3Message) GetStrField() string { 121 | if x != nil { 122 | return x.StrField 123 | } 124 | return "" 125 | } 126 | 127 | func (x *TestProto3Message) GetOptStrField() string { 128 | if x != nil && x.OptStrField != nil { 129 | return *x.OptStrField 130 | } 131 | return "" 132 | } 133 | 134 | func (x *TestProto3Message) GetInt32Field() int32 { 135 | if x != nil { 136 | return x.Int32Field 137 | } 138 | return 0 139 | } 140 | 141 | func (x *TestProto3Message) GetInt64Field() int64 { 142 | if x != nil { 143 | return x.Int64Field 144 | } 145 | return 0 146 | } 147 | 148 | func (x *TestProto3Message) GetStrList() []string { 149 | if x != nil { 150 | return x.StrList 151 | } 152 | return nil 153 | } 154 | 155 | func (x *TestProto3Message) GetNested() *TestProto3NestedMessage { 156 | if x != nil { 157 | return x.Nested 158 | } 159 | return nil 160 | } 161 | 162 | func (x *TestProto3Message) GetNestedList() []*TestProto3NestedMessage { 163 | if x != nil { 164 | return x.NestedList 165 | } 166 | return nil 167 | } 168 | 169 | func (x *TestProto3Message) GetMetadata() map[string]int64 { 170 | if x != nil { 171 | return x.Metadata 172 | } 173 | return nil 174 | } 175 | 176 | type TestProto3NestedMessage struct { 177 | state protoimpl.MessageState 178 | sizeCache protoimpl.SizeCache 179 | unknownFields protoimpl.UnknownFields 180 | 181 | StrField string `protobuf:"bytes,1,opt,name=str_field,json=strField,proto3" json:"str_field,omitempty"` 182 | } 183 | 184 | func (x *TestProto3NestedMessage) Reset() { 185 | *x = TestProto3NestedMessage{} 186 | if protoimpl.UnsafeEnabled { 187 | mi := &file_internal_test_proto3_test_proto_msgTypes[1] 188 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 189 | ms.StoreMessageInfo(mi) 190 | } 191 | } 192 | 193 | func (x *TestProto3NestedMessage) String() string { 194 | return protoimpl.X.MessageStringOf(x) 195 | } 196 | 197 | func (*TestProto3NestedMessage) ProtoMessage() {} 198 | 199 | func (x *TestProto3NestedMessage) ProtoReflect() protoreflect.Message { 200 | mi := &file_internal_test_proto3_test_proto_msgTypes[1] 201 | if protoimpl.UnsafeEnabled && x != nil { 202 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 203 | if ms.LoadMessageInfo() == nil { 204 | ms.StoreMessageInfo(mi) 205 | } 206 | return ms 207 | } 208 | return mi.MessageOf(x) 209 | } 210 | 211 | // Deprecated: Use TestProto3NestedMessage.ProtoReflect.Descriptor instead. 212 | func (*TestProto3NestedMessage) Descriptor() ([]byte, []int) { 213 | return file_internal_test_proto3_test_proto_rawDescGZIP(), []int{1} 214 | } 215 | 216 | func (x *TestProto3NestedMessage) GetStrField() string { 217 | if x != nil { 218 | return x.StrField 219 | } 220 | return "" 221 | } 222 | 223 | type TestProto3GoogleStruct struct { 224 | state protoimpl.MessageState 225 | sizeCache protoimpl.SizeCache 226 | unknownFields protoimpl.UnknownFields 227 | 228 | StructField *structpb.Struct `protobuf:"bytes,1,opt,name=struct_field,json=structField,proto3" json:"struct_field,omitempty"` 229 | } 230 | 231 | func (x *TestProto3GoogleStruct) Reset() { 232 | *x = TestProto3GoogleStruct{} 233 | if protoimpl.UnsafeEnabled { 234 | mi := &file_internal_test_proto3_test_proto_msgTypes[2] 235 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 236 | ms.StoreMessageInfo(mi) 237 | } 238 | } 239 | 240 | func (x *TestProto3GoogleStruct) String() string { 241 | return protoimpl.X.MessageStringOf(x) 242 | } 243 | 244 | func (*TestProto3GoogleStruct) ProtoMessage() {} 245 | 246 | func (x *TestProto3GoogleStruct) ProtoReflect() protoreflect.Message { 247 | mi := &file_internal_test_proto3_test_proto_msgTypes[2] 248 | if protoimpl.UnsafeEnabled && x != nil { 249 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 250 | if ms.LoadMessageInfo() == nil { 251 | ms.StoreMessageInfo(mi) 252 | } 253 | return ms 254 | } 255 | return mi.MessageOf(x) 256 | } 257 | 258 | // Deprecated: Use TestProto3GoogleStruct.ProtoReflect.Descriptor instead. 259 | func (*TestProto3GoogleStruct) Descriptor() ([]byte, []int) { 260 | return file_internal_test_proto3_test_proto_rawDescGZIP(), []int{2} 261 | } 262 | 263 | func (x *TestProto3GoogleStruct) GetStructField() *structpb.Struct { 264 | if x != nil { 265 | return x.StructField 266 | } 267 | return nil 268 | } 269 | 270 | type TestProto3EnumStruct struct { 271 | state protoimpl.MessageState 272 | sizeCache protoimpl.SizeCache 273 | unknownFields protoimpl.UnknownFields 274 | 275 | EnumField TestProto3EnumStruct_TestProto3Enum `protobuf:"varint,1,opt,name=enum_field,json=enumField,proto3,enum=pbts.TestProto3EnumStruct_TestProto3Enum" json:"enum_field,omitempty"` 276 | } 277 | 278 | func (x *TestProto3EnumStruct) Reset() { 279 | *x = TestProto3EnumStruct{} 280 | if protoimpl.UnsafeEnabled { 281 | mi := &file_internal_test_proto3_test_proto_msgTypes[3] 282 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 283 | ms.StoreMessageInfo(mi) 284 | } 285 | } 286 | 287 | func (x *TestProto3EnumStruct) String() string { 288 | return protoimpl.X.MessageStringOf(x) 289 | } 290 | 291 | func (*TestProto3EnumStruct) ProtoMessage() {} 292 | 293 | func (x *TestProto3EnumStruct) ProtoReflect() protoreflect.Message { 294 | mi := &file_internal_test_proto3_test_proto_msgTypes[3] 295 | if protoimpl.UnsafeEnabled && x != nil { 296 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 297 | if ms.LoadMessageInfo() == nil { 298 | ms.StoreMessageInfo(mi) 299 | } 300 | return ms 301 | } 302 | return mi.MessageOf(x) 303 | } 304 | 305 | // Deprecated: Use TestProto3EnumStruct.ProtoReflect.Descriptor instead. 306 | func (*TestProto3EnumStruct) Descriptor() ([]byte, []int) { 307 | return file_internal_test_proto3_test_proto_rawDescGZIP(), []int{3} 308 | } 309 | 310 | func (x *TestProto3EnumStruct) GetEnumField() TestProto3EnumStruct_TestProto3Enum { 311 | if x != nil { 312 | return x.EnumField 313 | } 314 | return TestProto3EnumStruct_unknown 315 | } 316 | 317 | type TestProto3OneOfStruct struct { 318 | state protoimpl.MessageState 319 | sizeCache protoimpl.SizeCache 320 | unknownFields protoimpl.UnknownFields 321 | 322 | // Types that are assignable to Pet: 323 | // 324 | // *TestProto3OneOfStruct_Cat_ 325 | // *TestProto3OneOfStruct_Dog_ 326 | // *TestProto3OneOfStruct_Other 327 | Pet isTestProto3OneOfStruct_Pet `protobuf_oneof:"pet"` 328 | } 329 | 330 | func (x *TestProto3OneOfStruct) Reset() { 331 | *x = TestProto3OneOfStruct{} 332 | if protoimpl.UnsafeEnabled { 333 | mi := &file_internal_test_proto3_test_proto_msgTypes[4] 334 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 335 | ms.StoreMessageInfo(mi) 336 | } 337 | } 338 | 339 | func (x *TestProto3OneOfStruct) String() string { 340 | return protoimpl.X.MessageStringOf(x) 341 | } 342 | 343 | func (*TestProto3OneOfStruct) ProtoMessage() {} 344 | 345 | func (x *TestProto3OneOfStruct) ProtoReflect() protoreflect.Message { 346 | mi := &file_internal_test_proto3_test_proto_msgTypes[4] 347 | if protoimpl.UnsafeEnabled && x != nil { 348 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 349 | if ms.LoadMessageInfo() == nil { 350 | ms.StoreMessageInfo(mi) 351 | } 352 | return ms 353 | } 354 | return mi.MessageOf(x) 355 | } 356 | 357 | // Deprecated: Use TestProto3OneOfStruct.ProtoReflect.Descriptor instead. 358 | func (*TestProto3OneOfStruct) Descriptor() ([]byte, []int) { 359 | return file_internal_test_proto3_test_proto_rawDescGZIP(), []int{4} 360 | } 361 | 362 | func (m *TestProto3OneOfStruct) GetPet() isTestProto3OneOfStruct_Pet { 363 | if m != nil { 364 | return m.Pet 365 | } 366 | return nil 367 | } 368 | 369 | func (x *TestProto3OneOfStruct) GetCat() *TestProto3OneOfStruct_Cat { 370 | if x, ok := x.GetPet().(*TestProto3OneOfStruct_Cat_); ok { 371 | return x.Cat 372 | } 373 | return nil 374 | } 375 | 376 | func (x *TestProto3OneOfStruct) GetDog() *TestProto3OneOfStruct_Dog { 377 | if x, ok := x.GetPet().(*TestProto3OneOfStruct_Dog_); ok { 378 | return x.Dog 379 | } 380 | return nil 381 | } 382 | 383 | func (x *TestProto3OneOfStruct) GetOther() string { 384 | if x, ok := x.GetPet().(*TestProto3OneOfStruct_Other); ok { 385 | return x.Other 386 | } 387 | return "" 388 | } 389 | 390 | type isTestProto3OneOfStruct_Pet interface { 391 | isTestProto3OneOfStruct_Pet() 392 | } 393 | 394 | type TestProto3OneOfStruct_Cat_ struct { 395 | Cat *TestProto3OneOfStruct_Cat `protobuf:"bytes,1,opt,name=cat,proto3,oneof"` 396 | } 397 | 398 | type TestProto3OneOfStruct_Dog_ struct { 399 | Dog *TestProto3OneOfStruct_Dog `protobuf:"bytes,2,opt,name=dog,proto3,oneof"` 400 | } 401 | 402 | type TestProto3OneOfStruct_Other struct { 403 | Other string `protobuf:"bytes,3,opt,name=other,proto3,oneof"` 404 | } 405 | 406 | func (*TestProto3OneOfStruct_Cat_) isTestProto3OneOfStruct_Pet() {} 407 | 408 | func (*TestProto3OneOfStruct_Dog_) isTestProto3OneOfStruct_Pet() {} 409 | 410 | func (*TestProto3OneOfStruct_Other) isTestProto3OneOfStruct_Pet() {} 411 | 412 | type TestProto3OneOfStruct_Cat struct { 413 | state protoimpl.MessageState 414 | sizeCache protoimpl.SizeCache 415 | unknownFields protoimpl.UnknownFields 416 | 417 | Meow string `protobuf:"bytes,1,opt,name=meow,proto3" json:"meow,omitempty"` 418 | } 419 | 420 | func (x *TestProto3OneOfStruct_Cat) Reset() { 421 | *x = TestProto3OneOfStruct_Cat{} 422 | if protoimpl.UnsafeEnabled { 423 | mi := &file_internal_test_proto3_test_proto_msgTypes[6] 424 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 425 | ms.StoreMessageInfo(mi) 426 | } 427 | } 428 | 429 | func (x *TestProto3OneOfStruct_Cat) String() string { 430 | return protoimpl.X.MessageStringOf(x) 431 | } 432 | 433 | func (*TestProto3OneOfStruct_Cat) ProtoMessage() {} 434 | 435 | func (x *TestProto3OneOfStruct_Cat) ProtoReflect() protoreflect.Message { 436 | mi := &file_internal_test_proto3_test_proto_msgTypes[6] 437 | if protoimpl.UnsafeEnabled && x != nil { 438 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 439 | if ms.LoadMessageInfo() == nil { 440 | ms.StoreMessageInfo(mi) 441 | } 442 | return ms 443 | } 444 | return mi.MessageOf(x) 445 | } 446 | 447 | // Deprecated: Use TestProto3OneOfStruct_Cat.ProtoReflect.Descriptor instead. 448 | func (*TestProto3OneOfStruct_Cat) Descriptor() ([]byte, []int) { 449 | return file_internal_test_proto3_test_proto_rawDescGZIP(), []int{4, 0} 450 | } 451 | 452 | func (x *TestProto3OneOfStruct_Cat) GetMeow() string { 453 | if x != nil { 454 | return x.Meow 455 | } 456 | return "" 457 | } 458 | 459 | type TestProto3OneOfStruct_Dog struct { 460 | state protoimpl.MessageState 461 | sizeCache protoimpl.SizeCache 462 | unknownFields protoimpl.UnknownFields 463 | 464 | Bark string `protobuf:"bytes,1,opt,name=bark,proto3" json:"bark,omitempty"` 465 | } 466 | 467 | func (x *TestProto3OneOfStruct_Dog) Reset() { 468 | *x = TestProto3OneOfStruct_Dog{} 469 | if protoimpl.UnsafeEnabled { 470 | mi := &file_internal_test_proto3_test_proto_msgTypes[7] 471 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 472 | ms.StoreMessageInfo(mi) 473 | } 474 | } 475 | 476 | func (x *TestProto3OneOfStruct_Dog) String() string { 477 | return protoimpl.X.MessageStringOf(x) 478 | } 479 | 480 | func (*TestProto3OneOfStruct_Dog) ProtoMessage() {} 481 | 482 | func (x *TestProto3OneOfStruct_Dog) ProtoReflect() protoreflect.Message { 483 | mi := &file_internal_test_proto3_test_proto_msgTypes[7] 484 | if protoimpl.UnsafeEnabled && x != nil { 485 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 486 | if ms.LoadMessageInfo() == nil { 487 | ms.StoreMessageInfo(mi) 488 | } 489 | return ms 490 | } 491 | return mi.MessageOf(x) 492 | } 493 | 494 | // Deprecated: Use TestProto3OneOfStruct_Dog.ProtoReflect.Descriptor instead. 495 | func (*TestProto3OneOfStruct_Dog) Descriptor() ([]byte, []int) { 496 | return file_internal_test_proto3_test_proto_rawDescGZIP(), []int{4, 1} 497 | } 498 | 499 | func (x *TestProto3OneOfStruct_Dog) GetBark() string { 500 | if x != nil { 501 | return x.Bark 502 | } 503 | return "" 504 | } 505 | 506 | var File_internal_test_proto3_test_proto protoreflect.FileDescriptor 507 | 508 | var file_internal_test_proto3_test_proto_rawDesc = []byte{ 509 | 0x0a, 0x1f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2f, 510 | 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 511 | 0x6f, 0x12, 0x04, 0x70, 0x62, 0x74, 0x73, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 512 | 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 513 | 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbf, 0x03, 0x0a, 0x11, 0x54, 0x65, 0x73, 0x74, 0x50, 0x72, 514 | 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 515 | 0x74, 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 516 | 0x73, 0x74, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x27, 0x0a, 0x0d, 0x6f, 0x70, 0x74, 0x5f, 517 | 0x73, 0x74, 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 518 | 0x00, 0x52, 0x0b, 0x6f, 0x70, 0x74, 0x53, 0x74, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x88, 0x01, 519 | 0x01, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 520 | 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x46, 0x69, 0x65, 521 | 0x6c, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x66, 0x69, 0x65, 0x6c, 522 | 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x46, 0x69, 523 | 0x65, 0x6c, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x74, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 524 | 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x74, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x35, 525 | 0x0a, 0x06, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 526 | 0x2e, 0x70, 0x62, 0x74, 0x73, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 527 | 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x06, 0x6e, 528 | 0x65, 0x73, 0x74, 0x65, 0x64, 0x12, 0x3e, 0x0a, 0x0b, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x5f, 529 | 0x6c, 0x69, 0x73, 0x74, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x62, 0x74, 530 | 0x73, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4e, 0x65, 0x73, 0x74, 531 | 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0a, 0x6e, 0x65, 0x73, 0x74, 0x65, 532 | 0x64, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x41, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 533 | 0x61, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x62, 0x74, 0x73, 0x2e, 0x54, 534 | 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 535 | 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 536 | 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x3b, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 537 | 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 538 | 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 539 | 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 540 | 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x6f, 0x70, 0x74, 0x5f, 0x73, 0x74, 541 | 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x36, 0x0a, 0x17, 0x54, 0x65, 0x73, 0x74, 0x50, 542 | 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 543 | 0x67, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x74, 0x72, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 544 | 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x74, 0x72, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 545 | 0x54, 0x0a, 0x16, 0x54, 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x47, 0x6f, 0x6f, 546 | 0x67, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x3a, 0x0a, 0x0c, 0x73, 0x74, 0x72, 547 | 0x75, 0x63, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 548 | 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 549 | 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 550 | 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x91, 0x01, 0x0a, 0x14, 0x54, 0x65, 0x73, 0x74, 0x50, 0x72, 551 | 0x6f, 0x74, 0x6f, 0x33, 0x45, 0x6e, 0x75, 0x6d, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x12, 0x48, 552 | 0x0a, 0x0a, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 553 | 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x70, 0x62, 0x74, 0x73, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x50, 0x72, 554 | 0x6f, 0x74, 0x6f, 0x33, 0x45, 0x6e, 0x75, 0x6d, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x54, 555 | 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x09, 0x65, 556 | 0x6e, 0x75, 0x6d, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x22, 0x2f, 0x0a, 0x0e, 0x54, 0x65, 0x73, 0x74, 557 | 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0b, 0x0a, 0x07, 0x75, 0x6e, 558 | 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x66, 0x6f, 0x6f, 0x10, 0x01, 559 | 0x12, 0x07, 0x0a, 0x03, 0x62, 0x61, 0x72, 0x10, 0x02, 0x22, 0xd6, 0x01, 0x0a, 0x15, 0x54, 0x65, 560 | 0x73, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4f, 0x6e, 0x65, 0x4f, 0x66, 0x53, 0x74, 0x72, 561 | 0x75, 0x63, 0x74, 0x12, 0x33, 0x0a, 0x03, 0x63, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 562 | 0x32, 0x1f, 0x2e, 0x70, 0x62, 0x74, 0x73, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x74, 563 | 0x6f, 0x33, 0x4f, 0x6e, 0x65, 0x4f, 0x66, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x43, 0x61, 564 | 0x74, 0x48, 0x00, 0x52, 0x03, 0x63, 0x61, 0x74, 0x12, 0x33, 0x0a, 0x03, 0x64, 0x6f, 0x67, 0x18, 565 | 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x62, 0x74, 0x73, 0x2e, 0x54, 0x65, 0x73, 566 | 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x4f, 0x6e, 0x65, 0x4f, 0x66, 0x53, 0x74, 0x72, 0x75, 567 | 0x63, 0x74, 0x2e, 0x44, 0x6f, 0x67, 0x48, 0x00, 0x52, 0x03, 0x64, 0x6f, 0x67, 0x12, 0x16, 0x0a, 568 | 0x05, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 569 | 0x6f, 0x74, 0x68, 0x65, 0x72, 0x1a, 0x19, 0x0a, 0x03, 0x43, 0x61, 0x74, 0x12, 0x12, 0x0a, 0x04, 570 | 0x6d, 0x65, 0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x65, 0x6f, 0x77, 571 | 0x1a, 0x19, 0x0a, 0x03, 0x44, 0x6f, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x61, 0x72, 0x6b, 0x18, 572 | 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x62, 0x61, 0x72, 0x6b, 0x42, 0x05, 0x0a, 0x03, 0x70, 573 | 0x65, 0x74, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 574 | 0x2f, 0x6f, 0x63, 0x74, 0x61, 0x76, 0x6f, 0x72, 0x65, 0x2f, 0x70, 0x62, 0x74, 0x73, 0x2f, 0x76, 575 | 0x32, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x62, 576 | 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 577 | } 578 | 579 | var ( 580 | file_internal_test_proto3_test_proto_rawDescOnce sync.Once 581 | file_internal_test_proto3_test_proto_rawDescData = file_internal_test_proto3_test_proto_rawDesc 582 | ) 583 | 584 | func file_internal_test_proto3_test_proto_rawDescGZIP() []byte { 585 | file_internal_test_proto3_test_proto_rawDescOnce.Do(func() { 586 | file_internal_test_proto3_test_proto_rawDescData = protoimpl.X.CompressGZIP(file_internal_test_proto3_test_proto_rawDescData) 587 | }) 588 | return file_internal_test_proto3_test_proto_rawDescData 589 | } 590 | 591 | var file_internal_test_proto3_test_proto_enumTypes = make([]protoimpl.EnumInfo, 1) 592 | var file_internal_test_proto3_test_proto_msgTypes = make([]protoimpl.MessageInfo, 8) 593 | var file_internal_test_proto3_test_proto_goTypes = []interface{}{ 594 | (TestProto3EnumStruct_TestProto3Enum)(0), // 0: pbts.TestProto3EnumStruct.TestProto3Enum 595 | (*TestProto3Message)(nil), // 1: pbts.TestProto3Message 596 | (*TestProto3NestedMessage)(nil), // 2: pbts.TestProto3NestedMessage 597 | (*TestProto3GoogleStruct)(nil), // 3: pbts.TestProto3GoogleStruct 598 | (*TestProto3EnumStruct)(nil), // 4: pbts.TestProto3EnumStruct 599 | (*TestProto3OneOfStruct)(nil), // 5: pbts.TestProto3OneOfStruct 600 | nil, // 6: pbts.TestProto3Message.MetadataEntry 601 | (*TestProto3OneOfStruct_Cat)(nil), // 7: pbts.TestProto3OneOfStruct.Cat 602 | (*TestProto3OneOfStruct_Dog)(nil), // 8: pbts.TestProto3OneOfStruct.Dog 603 | (*structpb.Struct)(nil), // 9: google.protobuf.Struct 604 | } 605 | var file_internal_test_proto3_test_proto_depIdxs = []int32{ 606 | 2, // 0: pbts.TestProto3Message.nested:type_name -> pbts.TestProto3NestedMessage 607 | 2, // 1: pbts.TestProto3Message.nested_list:type_name -> pbts.TestProto3NestedMessage 608 | 6, // 2: pbts.TestProto3Message.metadata:type_name -> pbts.TestProto3Message.MetadataEntry 609 | 9, // 3: pbts.TestProto3GoogleStruct.struct_field:type_name -> google.protobuf.Struct 610 | 0, // 4: pbts.TestProto3EnumStruct.enum_field:type_name -> pbts.TestProto3EnumStruct.TestProto3Enum 611 | 7, // 5: pbts.TestProto3OneOfStruct.cat:type_name -> pbts.TestProto3OneOfStruct.Cat 612 | 8, // 6: pbts.TestProto3OneOfStruct.dog:type_name -> pbts.TestProto3OneOfStruct.Dog 613 | 7, // [7:7] is the sub-list for method output_type 614 | 7, // [7:7] is the sub-list for method input_type 615 | 7, // [7:7] is the sub-list for extension type_name 616 | 7, // [7:7] is the sub-list for extension extendee 617 | 0, // [0:7] is the sub-list for field type_name 618 | } 619 | 620 | func init() { file_internal_test_proto3_test_proto_init() } 621 | func file_internal_test_proto3_test_proto_init() { 622 | if File_internal_test_proto3_test_proto != nil { 623 | return 624 | } 625 | if !protoimpl.UnsafeEnabled { 626 | file_internal_test_proto3_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 627 | switch v := v.(*TestProto3Message); i { 628 | case 0: 629 | return &v.state 630 | case 1: 631 | return &v.sizeCache 632 | case 2: 633 | return &v.unknownFields 634 | default: 635 | return nil 636 | } 637 | } 638 | file_internal_test_proto3_test_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 639 | switch v := v.(*TestProto3NestedMessage); i { 640 | case 0: 641 | return &v.state 642 | case 1: 643 | return &v.sizeCache 644 | case 2: 645 | return &v.unknownFields 646 | default: 647 | return nil 648 | } 649 | } 650 | file_internal_test_proto3_test_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { 651 | switch v := v.(*TestProto3GoogleStruct); i { 652 | case 0: 653 | return &v.state 654 | case 1: 655 | return &v.sizeCache 656 | case 2: 657 | return &v.unknownFields 658 | default: 659 | return nil 660 | } 661 | } 662 | file_internal_test_proto3_test_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { 663 | switch v := v.(*TestProto3EnumStruct); i { 664 | case 0: 665 | return &v.state 666 | case 1: 667 | return &v.sizeCache 668 | case 2: 669 | return &v.unknownFields 670 | default: 671 | return nil 672 | } 673 | } 674 | file_internal_test_proto3_test_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { 675 | switch v := v.(*TestProto3OneOfStruct); i { 676 | case 0: 677 | return &v.state 678 | case 1: 679 | return &v.sizeCache 680 | case 2: 681 | return &v.unknownFields 682 | default: 683 | return nil 684 | } 685 | } 686 | file_internal_test_proto3_test_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { 687 | switch v := v.(*TestProto3OneOfStruct_Cat); i { 688 | case 0: 689 | return &v.state 690 | case 1: 691 | return &v.sizeCache 692 | case 2: 693 | return &v.unknownFields 694 | default: 695 | return nil 696 | } 697 | } 698 | file_internal_test_proto3_test_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { 699 | switch v := v.(*TestProto3OneOfStruct_Dog); i { 700 | case 0: 701 | return &v.state 702 | case 1: 703 | return &v.sizeCache 704 | case 2: 705 | return &v.unknownFields 706 | default: 707 | return nil 708 | } 709 | } 710 | } 711 | file_internal_test_proto3_test_proto_msgTypes[0].OneofWrappers = []interface{}{} 712 | file_internal_test_proto3_test_proto_msgTypes[4].OneofWrappers = []interface{}{ 713 | (*TestProto3OneOfStruct_Cat_)(nil), 714 | (*TestProto3OneOfStruct_Dog_)(nil), 715 | (*TestProto3OneOfStruct_Other)(nil), 716 | } 717 | type x struct{} 718 | out := protoimpl.TypeBuilder{ 719 | File: protoimpl.DescBuilder{ 720 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 721 | RawDescriptor: file_internal_test_proto3_test_proto_rawDesc, 722 | NumEnums: 1, 723 | NumMessages: 8, 724 | NumExtensions: 0, 725 | NumServices: 0, 726 | }, 727 | GoTypes: file_internal_test_proto3_test_proto_goTypes, 728 | DependencyIndexes: file_internal_test_proto3_test_proto_depIdxs, 729 | EnumInfos: file_internal_test_proto3_test_proto_enumTypes, 730 | MessageInfos: file_internal_test_proto3_test_proto_msgTypes, 731 | }.Build() 732 | File_internal_test_proto3_test_proto = out.File 733 | file_internal_test_proto3_test_proto_rawDesc = nil 734 | file_internal_test_proto3_test_proto_goTypes = nil 735 | file_internal_test_proto3_test_proto_depIdxs = nil 736 | } 737 | -------------------------------------------------------------------------------- /internal/test/proto3_test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package pbts; 4 | 5 | option go_package = "github.com/octavore/pbts/v2/internal/test"; 6 | 7 | import "google/protobuf/struct.proto"; 8 | 9 | message TestProto3Message { 10 | string str_field = 1; 11 | optional string opt_str_field = 2; 12 | int32 int32_field = 3; 13 | int64 int64_field = 4; 14 | repeated string str_list = 5; 15 | TestProto3NestedMessage nested = 6; 16 | repeated TestProto3NestedMessage nested_list = 7; 17 | map metadata = 10; 18 | } 19 | 20 | message TestProto3NestedMessage { 21 | string str_field = 1; 22 | } 23 | 24 | message TestProto3GoogleStruct { 25 | google.protobuf.Struct struct_field = 1; 26 | } 27 | 28 | message TestProto3EnumStruct { 29 | enum TestProto3Enum { 30 | unknown = 0; 31 | foo = 1; 32 | bar = 2; 33 | } 34 | TestProto3Enum enum_field = 1; 35 | } 36 | 37 | message TestProto3OneOfStruct { 38 | message Cat { 39 | string meow = 1; 40 | } 41 | message Dog { 42 | string bark = 1; 43 | } 44 | oneof pet { 45 | Cat cat = 1; 46 | Dog dog = 2; 47 | string other = 3; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /pbts.go: -------------------------------------------------------------------------------- 1 | package pbts 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "sort" 7 | "strings" 8 | 9 | "google.golang.org/protobuf/reflect/protoreflect" 10 | "google.golang.org/protobuf/reflect/protoregistry" 11 | ) 12 | 13 | type messageType struct { 14 | Name string 15 | Instance interface{} 16 | } 17 | 18 | type options struct { 19 | exclusions []string 20 | nativeEnums bool 21 | verbose bool 22 | } 23 | 24 | func GenerateAll(destPath string, optFns ...optFn) error { 25 | o := &options{} 26 | for _, optFn := range optFns { 27 | optFn(o) 28 | } 29 | 30 | f, err := os.OpenFile(destPath, os.O_TRUNC|os.O_RDWR|os.O_CREATE, os.ModePerm) 31 | if err != nil { 32 | return fmt.Errorf("error opening file: %w", err) 33 | } 34 | 35 | g := NewGenerator(f) 36 | g.NativeEnums = o.nativeEnums 37 | 38 | messageTypes := []protoreflect.MessageDescriptor{} 39 | protoregistry.GlobalTypes.RangeMessages(func(m protoreflect.MessageType) bool { 40 | messageName := fmt.Sprintf("%s", m.Descriptor().FullName()) 41 | for _, prefix := range o.exclusions { 42 | if strings.HasPrefix(messageName, prefix) { 43 | return true 44 | } 45 | } 46 | messageTypes = append(messageTypes, m.Descriptor()) 47 | return true 48 | }) 49 | 50 | sort.Slice(messageTypes, func(i, j int) bool { 51 | return messageTypes[i].Name() < messageTypes[j].Name() 52 | }) 53 | for _, m := range messageTypes { 54 | if o.verbose { 55 | fmt.Println(m.FullName()) 56 | } 57 | g.RegisterDescriptor(m) 58 | } 59 | g.Write() 60 | 61 | return nil 62 | } 63 | 64 | type optFn func(o *options) 65 | 66 | func WithExclusions(exclusions ...string) optFn { 67 | return func(o *options) { 68 | o.exclusions = append(o.exclusions, exclusions...) 69 | } 70 | } 71 | 72 | func WithNativeEnums() optFn { 73 | return func(o *options) { 74 | o.nativeEnums = true 75 | } 76 | } 77 | 78 | func WithVerbose() optFn { 79 | return func(o *options) { 80 | o.verbose = true 81 | } 82 | } 83 | --------------------------------------------------------------------------------