├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── question.md └── workflows │ └── test.yml ├── .gitignore ├── AUTHORS ├── CONTRIBUTING.md ├── CONTRIBUTORS ├── LICENSE ├── README.md ├── descriptor ├── descriptor.go └── descriptor_test.go ├── go.mod ├── go.sum ├── internal ├── cmd │ └── generate-alias │ │ └── main.go ├── gengogrpc │ └── grpc.go └── testprotos │ ├── jsonpb_proto │ ├── test2.pb.go │ ├── test2.proto │ ├── test3.pb.go │ └── test3.proto │ ├── proto2_proto │ ├── test.pb.go │ └── test.proto │ ├── proto3_proto │ ├── test.pb.go │ └── test.proto │ └── regenerate.bash ├── jsonpb ├── decode.go ├── encode.go ├── json.go └── json_test.go ├── proto ├── buffer.go ├── defaults.go ├── deprecated.go ├── discard.go ├── discard_test.go ├── extensions.go ├── extensions_test.go ├── properties.go ├── proto.go ├── proto_clone_test.go ├── proto_equal_test.go ├── proto_test.go ├── registry.go ├── registry_test.go ├── text_decode.go ├── text_encode.go ├── text_test.go ├── wire.go └── wrappers.go ├── protoc-gen-go ├── descriptor │ └── descriptor.pb.go ├── generator │ ├── generator.go │ └── internal │ │ └── remap │ │ ├── remap.go │ │ └── remap_test.go ├── grpc │ └── grpc.go ├── main.go └── plugin │ └── plugin.pb.go ├── ptypes ├── any.go ├── any │ └── any.pb.go ├── any_test.go ├── doc.go ├── duration.go ├── duration │ └── duration.pb.go ├── duration_test.go ├── empty │ └── empty.pb.go ├── struct │ └── struct.pb.go ├── timestamp.go ├── timestamp │ └── timestamp.pb.go ├── timestamp_test.go └── wrappers │ └── wrappers.pb.go ├── regenerate.bash └── test.bash /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **What version of protobuf and what language are you using?** 8 | Version: (e.g., `v1.1.0`, `89a0c16f`, etc) 9 | 10 | **What did you do?** 11 | If possible, provide a recipe for reproducing the error. 12 | A complete runnable program is good with `.proto` and `.go` source code. 13 | 14 | **What did you expect to see?** 15 | 16 | **What did you see instead?** 17 | 18 | Make sure you include information that can help us debug (full error message, exception listing, stack trace, logs). 19 | 20 | **Anything else we should know about your project / environment?** 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Questions and troubleshooting 4 | 5 | --- 6 | 7 | 8 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | on: [push, pull_request] 2 | name: Test 3 | jobs: 4 | test: 5 | strategy: 6 | matrix: 7 | go-version: [1.17.x, 1.18.x, 1.19.x, 1.20.x, 1.21.x, 1.22.x] 8 | os: [ubuntu-latest, macos-latest] 9 | runs-on: ${{ matrix.os }} 10 | steps: 11 | - name: Install Go 12 | uses: actions/setup-go@v2 13 | with: 14 | go-version: ${{ matrix.go-version }} 15 | - name: Checkout code 16 | uses: actions/checkout@v2 17 | - name: TestLatest 18 | if: matrix.go-version == '1.21.x' 19 | run: ./test.bash 20 | - name: TestAll 21 | if: matrix.go-version != '1.21.x' 22 | run: go test ./... 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .cache 2 | vendor 3 | cmd/protoc-gen-go/protoc-gen-go 4 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # This source code refers to The Go Authors for copyright purposes. 2 | # The master list of authors is in the main Go distribution, 3 | # visible at http://tip.golang.org/AUTHORS. 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Go Protocol Buffers 2 | 3 | Go protocol buffers is an open source project and accepts contributions. 4 | 5 | This project is the first major version of Go protobufs, 6 | while the next major revision of this project is located at 7 | [protocolbuffers/protobuf-go](https://github.com/protocolbuffers/protobuf-go). 8 | Most new development effort is focused on the latter project, 9 | and changes to this project is primarily reserved for bug fixes. 10 | 11 | 12 | ## Contributor License Agreement 13 | 14 | Contributions to this project must be accompanied by a Contributor License 15 | Agreement. You (or your employer) retain the copyright to your contribution, 16 | this simply gives us permission to use and redistribute your contributions as 17 | part of the project. Head over to to see 18 | your current agreements on file or to sign a new one. 19 | 20 | You generally only need to submit a CLA once, so if you've already submitted one 21 | (even if it was for a different project), you probably don't need to do it 22 | again. 23 | 24 | 25 | ## Code reviews 26 | 27 | All submissions, including submissions by project members, require review. We 28 | use GitHub pull requests for this purpose. Consult 29 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 30 | information on using pull requests. 31 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This source code was written by the Go contributors. 2 | # The master list of contributors is in the main Go distribution, 3 | # visible at http://tip.golang.org/CONTRIBUTORS. 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2010 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Go support for Protocol Buffers 2 | 3 | [![GoDev](https://img.shields.io/static/v1?label=godev&message=reference&color=00add8)](https://pkg.go.dev/mod/github.com/golang/protobuf) 4 | [![Build Status](https://travis-ci.org/golang/protobuf.svg?branch=master)](https://travis-ci.org/golang/protobuf) 5 | 6 | This module 7 | ([`github.com/golang/protobuf`](https://pkg.go.dev/mod/github.com/golang/protobuf)) 8 | contains Go bindings for protocol buffers. 9 | 10 | It has been superseded by the 11 | [`google.golang.org/protobuf`](https://pkg.go.dev/mod/google.golang.org/protobuf) 12 | module, which contains an updated and simplified API, 13 | support for protobuf reflection, and many other improvements. 14 | We recommend that new code use the `google.golang.org/protobuf` module. 15 | 16 | Versions v1.4 and later of `github.com/golang/protobuf` are implemented 17 | in terms of `google.golang.org/protobuf`. 18 | Programs which use both modules must use at least version v1.4 of this one. 19 | 20 | See the 21 | [developer guide for protocol buffers in Go](https://developers.google.com/protocol-buffers/docs/gotutorial) 22 | for a general guide for how to get started using protobufs in Go. 23 | 24 | See 25 | [release note documentation](https://github.com/golang/protobuf/releases) 26 | for more information about individual releases of this project. 27 | 28 | See 29 | [documentation for the next major revision](https://pkg.go.dev/mod/google.golang.org/protobuf) 30 | for more information about the purpose, usage, and history of this project. 31 | 32 | ## Package index 33 | 34 | Summary of the packages provided by this module: 35 | 36 | * [`proto`](https://pkg.go.dev/github.com/golang/protobuf/proto): Package 37 | `proto` provides functions operating on protobuf messages such as cloning, 38 | merging, and checking equality, as well as binary serialization and text 39 | serialization. 40 | * [`jsonpb`](https://pkg.go.dev/github.com/golang/protobuf/jsonpb): Package 41 | `jsonpb` serializes protobuf messages as JSON. 42 | * [`ptypes`](https://pkg.go.dev/github.com/golang/protobuf/ptypes): Package 43 | `ptypes` provides helper functionality for protobuf well-known types. 44 | * [`ptypes/any`](https://pkg.go.dev/github.com/golang/protobuf/ptypes/any): 45 | Package `any` is the generated package for `google/protobuf/any.proto`. 46 | * [`ptypes/empty`](https://pkg.go.dev/github.com/golang/protobuf/ptypes/empty): 47 | Package `empty` is the generated package for `google/protobuf/empty.proto`. 48 | * [`ptypes/timestamp`](https://pkg.go.dev/github.com/golang/protobuf/ptypes/timestamp): 49 | Package `timestamp` is the generated package for 50 | `google/protobuf/timestamp.proto`. 51 | * [`ptypes/duration`](https://pkg.go.dev/github.com/golang/protobuf/ptypes/duration): 52 | Package `duration` is the generated package for 53 | `google/protobuf/duration.proto`. 54 | * [`ptypes/wrappers`](https://pkg.go.dev/github.com/golang/protobuf/ptypes/wrappers): 55 | Package `wrappers` is the generated package for 56 | `google/protobuf/wrappers.proto`. 57 | * [`ptypes/struct`](https://pkg.go.dev/github.com/golang/protobuf/ptypes/struct): 58 | Package `structpb` is the generated package for 59 | `google/protobuf/struct.proto`. 60 | * [`protoc-gen-go/descriptor`](https://pkg.go.dev/github.com/golang/protobuf/protoc-gen-go/descriptor): 61 | Package `descriptor` is the generated package for 62 | `google/protobuf/descriptor.proto`. 63 | * [`protoc-gen-go/plugin`](https://pkg.go.dev/github.com/golang/protobuf/protoc-gen-go/plugin): 64 | Package `plugin` is the generated package for 65 | `google/protobuf/compiler/plugin.proto`. 66 | * [`protoc-gen-go`](https://pkg.go.dev/github.com/golang/protobuf/protoc-gen-go): 67 | The `protoc-gen-go` binary is a protoc plugin to generate a Go protocol 68 | buffer package. 69 | 70 | ## Reporting issues 71 | 72 | The issue tracker for this project 73 | [is located here](https://github.com/golang/protobuf/issues). 74 | 75 | Please report any issues with a sufficient description of the bug or feature 76 | request. Bug reports should ideally be accompanied by a minimal reproduction of 77 | the issue. Irreproducible bugs are difficult to diagnose and fix (and likely to 78 | be closed after some period of time). Bug reports must specify the version of 79 | the 80 | [Go protocol buffer module](https://github.com/protocolbuffers/protobuf-go/releases) 81 | and also the version of the 82 | [protocol buffer toolchain](https://github.com/protocolbuffers/protobuf/releases) 83 | being used. 84 | 85 | ## Contributing 86 | 87 | This project is open-source and accepts contributions. See the 88 | [contribution guide](https://github.com/golang/protobuf/blob/master/CONTRIBUTING.md) 89 | for more information. 90 | 91 | ## Compatibility 92 | 93 | This module and the generated code are expected to be stable over time. However, 94 | we reserve the right to make breaking changes without notice for the following 95 | reasons: 96 | 97 | * **Security:** A security issue in the specification or implementation may 98 | come to light whose resolution requires breaking compatibility. We reserve 99 | the right to address such issues. 100 | * **Unspecified behavior:** There are some aspects of the protocol buffer 101 | specification that are undefined. Programs that depend on unspecified 102 | behavior may break in future releases. 103 | * **Specification changes:** It may become necessary to address an 104 | inconsistency, incompleteness, or change in the protocol buffer 105 | specification, which may affect the behavior of existing programs. We 106 | reserve the right to address such changes. 107 | * **Bugs:** If a package has a bug that violates correctness, a program 108 | depending on the buggy behavior may break if the bug is fixed. We reserve 109 | the right to fix such bugs. 110 | * **Generated additions**: We reserve the right to add new declarations to 111 | generated Go packages of `.proto` files. This includes declared constants, 112 | variables, functions, types, fields in structs, and methods on types. This 113 | may break attempts at injecting additional code on top of what is generated 114 | by `protoc-gen-go`. Such practice is not supported by this project. 115 | * **Internal changes**: We reserve the right to add, modify, and remove 116 | internal code, which includes all unexported declarations, the 117 | [`generator`](https://pkg.go.dev/github.com/golang/protobuf/protoc-gen-go/generator) 118 | package, and all packages under 119 | [`internal`](https://pkg.go.dev/github.com/golang/protobuf/internal). 120 | 121 | Any breaking changes outside of these will be announced 6 months in advance to 122 | [protobuf@googlegroups.com](https://groups.google.com/forum/#!forum/protobuf). 123 | -------------------------------------------------------------------------------- /descriptor/descriptor.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package descriptor provides functions for obtaining the protocol buffer 6 | // descriptors of generated Go types. 7 | // 8 | // Deprecated: See the "google.golang.org/protobuf/reflect/protoreflect" package 9 | // for how to obtain an EnumDescriptor or MessageDescriptor in order to 10 | // programatically interact with the protobuf type system. 11 | package descriptor 12 | 13 | import ( 14 | "bytes" 15 | "compress/gzip" 16 | "io/ioutil" 17 | "sync" 18 | 19 | "github.com/golang/protobuf/proto" 20 | "google.golang.org/protobuf/reflect/protodesc" 21 | "google.golang.org/protobuf/reflect/protoreflect" 22 | "google.golang.org/protobuf/runtime/protoimpl" 23 | 24 | descriptorpb "github.com/golang/protobuf/protoc-gen-go/descriptor" 25 | ) 26 | 27 | // Message is proto.Message with a method to return its descriptor. 28 | // 29 | // Deprecated: The Descriptor method may not be generated by future 30 | // versions of protoc-gen-go, meaning that this interface may not 31 | // be implemented by many concrete message types. 32 | type Message interface { 33 | proto.Message 34 | Descriptor() ([]byte, []int) 35 | } 36 | 37 | // ForMessage returns the file descriptor proto containing 38 | // the message and the message descriptor proto for the message itself. 39 | // The returned proto messages must not be mutated. 40 | // 41 | // Deprecated: Not all concrete message types satisfy the Message interface. 42 | // Use MessageDescriptorProto instead. If possible, the calling code should 43 | // be rewritten to use protobuf reflection instead. 44 | // See package "google.golang.org/protobuf/reflect/protoreflect" for details. 45 | func ForMessage(m Message) (*descriptorpb.FileDescriptorProto, *descriptorpb.DescriptorProto) { 46 | return MessageDescriptorProto(m) 47 | } 48 | 49 | type rawDesc struct { 50 | fileDesc []byte 51 | indexes []int 52 | } 53 | 54 | var rawDescCache sync.Map // map[protoreflect.Descriptor]*rawDesc 55 | 56 | func deriveRawDescriptor(d protoreflect.Descriptor) ([]byte, []int) { 57 | // Fast-path: check whether raw descriptors are already cached. 58 | origDesc := d 59 | if v, ok := rawDescCache.Load(origDesc); ok { 60 | return v.(*rawDesc).fileDesc, v.(*rawDesc).indexes 61 | } 62 | 63 | // Slow-path: derive the raw descriptor from the v2 descriptor. 64 | 65 | // Start with the leaf (a given enum or message declaration) and 66 | // ascend upwards until we hit the parent file descriptor. 67 | var idxs []int 68 | for { 69 | idxs = append(idxs, d.Index()) 70 | d = d.Parent() 71 | if d == nil { 72 | // TODO: We could construct a FileDescriptor stub for standalone 73 | // descriptors to satisfy the API. 74 | return nil, nil 75 | } 76 | if _, ok := d.(protoreflect.FileDescriptor); ok { 77 | break 78 | } 79 | } 80 | 81 | // Obtain the raw file descriptor. 82 | fd := d.(protoreflect.FileDescriptor) 83 | b, _ := proto.Marshal(protodesc.ToFileDescriptorProto(fd)) 84 | file := protoimpl.X.CompressGZIP(b) 85 | 86 | // Reverse the indexes, since we populated it in reverse. 87 | for i, j := 0, len(idxs)-1; i < j; i, j = i+1, j-1 { 88 | idxs[i], idxs[j] = idxs[j], idxs[i] 89 | } 90 | 91 | if v, ok := rawDescCache.LoadOrStore(origDesc, &rawDesc{file, idxs}); ok { 92 | return v.(*rawDesc).fileDesc, v.(*rawDesc).indexes 93 | } 94 | return file, idxs 95 | } 96 | 97 | // EnumRawDescriptor returns the GZIP'd raw file descriptor representing 98 | // the enum and the index path to reach the enum declaration. 99 | // The returned slices must not be mutated. 100 | func EnumRawDescriptor(e proto.GeneratedEnum) ([]byte, []int) { 101 | if ev, ok := e.(interface{ EnumDescriptor() ([]byte, []int) }); ok { 102 | return ev.EnumDescriptor() 103 | } 104 | ed := protoimpl.X.EnumTypeOf(e) 105 | return deriveRawDescriptor(ed.Descriptor()) 106 | } 107 | 108 | // MessageRawDescriptor returns the GZIP'd raw file descriptor representing 109 | // the message and the index path to reach the message declaration. 110 | // The returned slices must not be mutated. 111 | func MessageRawDescriptor(m proto.GeneratedMessage) ([]byte, []int) { 112 | if mv, ok := m.(interface{ Descriptor() ([]byte, []int) }); ok { 113 | return mv.Descriptor() 114 | } 115 | md := protoimpl.X.MessageTypeOf(m) 116 | return deriveRawDescriptor(md.Descriptor()) 117 | } 118 | 119 | var fileDescCache sync.Map // map[*byte]*descriptorpb.FileDescriptorProto 120 | 121 | func deriveFileDescriptor(rawDesc []byte) *descriptorpb.FileDescriptorProto { 122 | // Fast-path: check whether descriptor protos are already cached. 123 | if v, ok := fileDescCache.Load(&rawDesc[0]); ok { 124 | return v.(*descriptorpb.FileDescriptorProto) 125 | } 126 | 127 | // Slow-path: derive the descriptor proto from the GZIP'd message. 128 | zr, err := gzip.NewReader(bytes.NewReader(rawDesc)) 129 | if err != nil { 130 | panic(err) 131 | } 132 | b, err := ioutil.ReadAll(zr) 133 | if err != nil { 134 | panic(err) 135 | } 136 | fd := new(descriptorpb.FileDescriptorProto) 137 | if err := proto.Unmarshal(b, fd); err != nil { 138 | panic(err) 139 | } 140 | if v, ok := fileDescCache.LoadOrStore(&rawDesc[0], fd); ok { 141 | return v.(*descriptorpb.FileDescriptorProto) 142 | } 143 | return fd 144 | } 145 | 146 | // EnumDescriptorProto returns the file descriptor proto representing 147 | // the enum and the enum descriptor proto for the enum itself. 148 | // The returned proto messages must not be mutated. 149 | func EnumDescriptorProto(e proto.GeneratedEnum) (*descriptorpb.FileDescriptorProto, *descriptorpb.EnumDescriptorProto) { 150 | rawDesc, idxs := EnumRawDescriptor(e) 151 | if rawDesc == nil || idxs == nil { 152 | return nil, nil 153 | } 154 | fd := deriveFileDescriptor(rawDesc) 155 | if len(idxs) == 1 { 156 | return fd, fd.EnumType[idxs[0]] 157 | } 158 | md := fd.MessageType[idxs[0]] 159 | for _, i := range idxs[1 : len(idxs)-1] { 160 | md = md.NestedType[i] 161 | } 162 | ed := md.EnumType[idxs[len(idxs)-1]] 163 | return fd, ed 164 | } 165 | 166 | // MessageDescriptorProto returns the file descriptor proto representing 167 | // the message and the message descriptor proto for the message itself. 168 | // The returned proto messages must not be mutated. 169 | func MessageDescriptorProto(m proto.GeneratedMessage) (*descriptorpb.FileDescriptorProto, *descriptorpb.DescriptorProto) { 170 | rawDesc, idxs := MessageRawDescriptor(m) 171 | if rawDesc == nil || idxs == nil { 172 | return nil, nil 173 | } 174 | fd := deriveFileDescriptor(rawDesc) 175 | md := fd.MessageType[idxs[0]] 176 | for _, i := range idxs[1:] { 177 | md = md.NestedType[i] 178 | } 179 | return fd, md 180 | } 181 | -------------------------------------------------------------------------------- /descriptor/descriptor_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package descriptor 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/google/go-cmp/cmp" 11 | "google.golang.org/protobuf/reflect/protoreflect" 12 | 13 | descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" 14 | ) 15 | 16 | func TestEnumDescriptor(t *testing.T) { 17 | tests := []struct { 18 | enum protoreflect.Enum 19 | idxs []int 20 | name string 21 | }{{ 22 | enum: descpb.FieldDescriptorProto_Type(0), 23 | idxs: []int{ 24 | new(descpb.FieldDescriptorProto).ProtoReflect().Descriptor().Index(), 25 | new(descpb.FieldDescriptorProto_Type).Descriptor().Index(), 26 | }, 27 | name: "Type", 28 | }, { 29 | enum: descpb.FieldOptions_CType(0), 30 | idxs: []int{ 31 | new(descpb.FieldOptions).ProtoReflect().Descriptor().Index(), 32 | new(descpb.FieldOptions_CType).Descriptor().Index(), 33 | }, 34 | name: "CType", 35 | }} 36 | 37 | for _, tt := range tests { 38 | e := struct{ protoreflect.Enum }{tt.enum} // v2-only enum 39 | 40 | _, idxs := EnumRawDescriptor(e) 41 | if diff := cmp.Diff(tt.idxs, idxs); diff != "" { 42 | t.Errorf("path index mismatch (-want +got):\n%v", diff) 43 | } 44 | 45 | _, ed := EnumDescriptorProto(e) 46 | if ed.GetName() != tt.name { 47 | t.Errorf("mismatching enum name: got %v, want %v", ed.GetName(), tt.name) 48 | } 49 | } 50 | } 51 | 52 | func TestMessageDescriptor(t *testing.T) { 53 | tests := []struct { 54 | message protoreflect.ProtoMessage 55 | idxs []int 56 | name string 57 | }{{ 58 | message: (*descpb.SourceCodeInfo_Location)(nil), 59 | idxs: []int{ 60 | new(descpb.SourceCodeInfo).ProtoReflect().Descriptor().Index(), 61 | new(descpb.SourceCodeInfo_Location).ProtoReflect().Descriptor().Index(), 62 | }, 63 | name: "Location", 64 | }, { 65 | message: (*descpb.FileDescriptorProto)(nil), 66 | idxs: []int{ 67 | new(descpb.FileDescriptorProto).ProtoReflect().Descriptor().Index(), 68 | }, 69 | name: "FileDescriptorProto", 70 | }} 71 | 72 | for _, tt := range tests { 73 | m := struct{ protoreflect.ProtoMessage }{tt.message} // v2-only message 74 | 75 | _, idxs := MessageRawDescriptor(m) 76 | if diff := cmp.Diff(tt.idxs, idxs); diff != "" { 77 | t.Errorf("path index mismatch (-want +got):\n%v", diff) 78 | } 79 | 80 | _, md := MessageDescriptorProto(m) 81 | if md.GetName() != tt.name { 82 | t.Errorf("mismatching message name: got %v, want %v", md.GetName(), tt.name) 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | // Deprecated: Use the "google.golang.org/protobuf" module instead. 2 | module github.com/golang/protobuf 3 | 4 | go 1.17 5 | 6 | require ( 7 | github.com/google/go-cmp v0.5.5 8 | google.golang.org/protobuf v1.33.0 9 | ) 10 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 2 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 3 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 4 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 5 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 6 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 7 | google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= 8 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 9 | google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= 10 | google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 11 | -------------------------------------------------------------------------------- /internal/cmd/generate-alias/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:generate go run . -execute 6 | 7 | package main 8 | 9 | import ( 10 | "flag" 11 | "fmt" 12 | "io/ioutil" 13 | "os" 14 | "os/exec" 15 | "path" 16 | "path/filepath" 17 | "strings" 18 | 19 | "github.com/golang/protobuf/proto" 20 | gengo "google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo" 21 | "google.golang.org/protobuf/compiler/protogen" 22 | "google.golang.org/protobuf/reflect/protodesc" 23 | "google.golang.org/protobuf/reflect/protoreflect" 24 | 25 | "google.golang.org/protobuf/types/descriptorpb" 26 | "google.golang.org/protobuf/types/known/anypb" 27 | "google.golang.org/protobuf/types/known/durationpb" 28 | "google.golang.org/protobuf/types/known/emptypb" 29 | "google.golang.org/protobuf/types/known/structpb" 30 | "google.golang.org/protobuf/types/known/timestamppb" 31 | "google.golang.org/protobuf/types/known/wrapperspb" 32 | "google.golang.org/protobuf/types/pluginpb" 33 | ) 34 | 35 | func main() { 36 | run := flag.Bool("execute", false, "Write generated files to destination.") 37 | flag.Parse() 38 | 39 | // Set of generated proto packages to forward to v2. 40 | files := []struct { 41 | oldGoPkg string 42 | newGoPkg string 43 | pbDesc protoreflect.FileDescriptor 44 | }{{ 45 | oldGoPkg: "github.com/golang/protobuf/protoc-gen-go/descriptor;descriptor", 46 | newGoPkg: "google.golang.org/protobuf/types/descriptorpb", 47 | pbDesc: descriptorpb.File_google_protobuf_descriptor_proto, 48 | }, { 49 | oldGoPkg: "github.com/golang/protobuf/protoc-gen-go/plugin;plugin_go", 50 | newGoPkg: "google.golang.org/protobuf/types/pluginpb", 51 | pbDesc: pluginpb.File_google_protobuf_compiler_plugin_proto, 52 | }, { 53 | oldGoPkg: "github.com/golang/protobuf/ptypes/any;any", 54 | newGoPkg: "google.golang.org/protobuf/types/known/anypb", 55 | pbDesc: anypb.File_google_protobuf_any_proto, 56 | }, { 57 | oldGoPkg: "github.com/golang/protobuf/ptypes/duration;duration", 58 | newGoPkg: "google.golang.org/protobuf/types/known/durationpb", 59 | pbDesc: durationpb.File_google_protobuf_duration_proto, 60 | }, { 61 | oldGoPkg: "github.com/golang/protobuf/ptypes/timestamp;timestamp", 62 | newGoPkg: "google.golang.org/protobuf/types/known/timestamppb", 63 | pbDesc: timestamppb.File_google_protobuf_timestamp_proto, 64 | }, { 65 | oldGoPkg: "github.com/golang/protobuf/ptypes/wrappers;wrappers", 66 | newGoPkg: "google.golang.org/protobuf/types/known/wrapperspb", 67 | pbDesc: wrapperspb.File_google_protobuf_wrappers_proto, 68 | }, { 69 | oldGoPkg: "github.com/golang/protobuf/ptypes/struct;structpb", 70 | newGoPkg: "google.golang.org/protobuf/types/known/structpb", 71 | pbDesc: structpb.File_google_protobuf_struct_proto, 72 | }, { 73 | oldGoPkg: "github.com/golang/protobuf/ptypes/empty;empty", 74 | newGoPkg: "google.golang.org/protobuf/types/known/emptypb", 75 | pbDesc: emptypb.File_google_protobuf_empty_proto, 76 | }} 77 | 78 | // For each package, construct a proto file that public imports the package. 79 | var req pluginpb.CodeGeneratorRequest 80 | var flags []string 81 | for _, file := range files { 82 | pkgPath := file.oldGoPkg[:strings.IndexByte(file.oldGoPkg, ';')] 83 | fd := &descriptorpb.FileDescriptorProto{ 84 | Name: proto.String(pkgPath + "/" + path.Base(pkgPath) + ".proto"), 85 | Syntax: proto.String(file.pbDesc.Syntax().String()), 86 | Dependency: []string{file.pbDesc.Path()}, 87 | PublicDependency: []int32{0}, 88 | Options: &descriptorpb.FileOptions{GoPackage: proto.String(file.oldGoPkg)}, 89 | } 90 | req.ProtoFile = append(req.ProtoFile, protodesc.ToFileDescriptorProto(file.pbDesc), fd) 91 | req.FileToGenerate = append(req.FileToGenerate, fd.GetName()) 92 | flags = append(flags, "M"+file.pbDesc.Path()+"="+file.newGoPkg) 93 | } 94 | req.Parameter = proto.String(strings.Join(flags, ",")) 95 | 96 | // Use the internal logic of protoc-gen-go to generate the files. 97 | gen, err := protogen.Options{}.New(&req) 98 | check(err) 99 | for _, file := range gen.Files { 100 | if file.Generate { 101 | gengo.GenerateVersionMarkers = false 102 | gengo.GenerateFile(gen, file) 103 | } 104 | } 105 | 106 | // Write the generated files. 107 | resp := gen.Response() 108 | if resp.Error != nil { 109 | panic("gengo error: " + resp.GetError()) 110 | } 111 | for _, file := range resp.File { 112 | relPath, err := filepath.Rel(filepath.FromSlash("github.com/golang/protobuf"), file.GetName()) 113 | check(err) 114 | 115 | check(ioutil.WriteFile(relPath+".bak", []byte(file.GetContent()), 0664)) 116 | if *run { 117 | fmt.Println("#", relPath) 118 | check(os.Rename(relPath+".bak", relPath)) 119 | } else { 120 | cmd := exec.Command("diff", relPath, relPath+".bak", "-N", "-u") 121 | cmd.Stdout = os.Stdout 122 | cmd.Run() 123 | os.Remove(relPath + ".bak") // best-effort delete 124 | } 125 | } 126 | } 127 | 128 | func check(err error) { 129 | if err != nil { 130 | panic(err) 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /internal/gengogrpc/grpc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package gengogrpc contains the gRPC code generator. 6 | package gengogrpc 7 | 8 | import ( 9 | "fmt" 10 | "strconv" 11 | "strings" 12 | 13 | "google.golang.org/protobuf/compiler/protogen" 14 | 15 | "google.golang.org/protobuf/types/descriptorpb" 16 | ) 17 | 18 | const ( 19 | contextPackage = protogen.GoImportPath("context") 20 | grpcPackage = protogen.GoImportPath("google.golang.org/grpc") 21 | codesPackage = protogen.GoImportPath("google.golang.org/grpc/codes") 22 | statusPackage = protogen.GoImportPath("google.golang.org/grpc/status") 23 | ) 24 | 25 | // GenerateFile generates a _grpc.pb.go file containing gRPC service definitions. 26 | func GenerateFile(gen *protogen.Plugin, file *protogen.File) *protogen.GeneratedFile { 27 | if len(file.Services) == 0 { 28 | return nil 29 | } 30 | filename := file.GeneratedFilenamePrefix + "_grpc.pb.go" 31 | g := gen.NewGeneratedFile(filename, file.GoImportPath) 32 | g.P("// Code generated by protoc-gen-go-grpc. DO NOT EDIT.") 33 | g.P() 34 | g.P("package ", file.GoPackageName) 35 | g.P() 36 | GenerateFileContent(gen, file, g) 37 | return g 38 | } 39 | 40 | // GenerateFileContent generates the gRPC service definitions, excluding the package statement. 41 | func GenerateFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile) { 42 | if len(file.Services) == 0 { 43 | return 44 | } 45 | 46 | // TODO: Remove this. We don't need to include these references any more. 47 | g.P("// Reference imports to suppress errors if they are not otherwise used.") 48 | g.P("var _ ", contextPackage.Ident("Context")) 49 | g.P("var _ ", grpcPackage.Ident("ClientConnInterface")) 50 | g.P() 51 | 52 | g.P("// This is a compile-time assertion to ensure that this generated file") 53 | g.P("// is compatible with the grpc package it is being compiled against.") 54 | g.P("const _ = ", grpcPackage.Ident("SupportPackageIsVersion6")) 55 | g.P() 56 | for _, service := range file.Services { 57 | genService(gen, file, g, service) 58 | } 59 | } 60 | 61 | func genService(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, service *protogen.Service) { 62 | clientName := service.GoName + "Client" 63 | 64 | g.P("// ", clientName, " is the client API for ", service.GoName, " service.") 65 | g.P("//") 66 | g.P("// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.") 67 | 68 | // Client interface. 69 | if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() { 70 | g.P("//") 71 | g.P(deprecationComment) 72 | } 73 | g.Annotate(clientName, service.Location) 74 | g.P("type ", clientName, " interface {") 75 | for _, method := range service.Methods { 76 | g.Annotate(clientName+"."+method.GoName, method.Location) 77 | if method.Desc.Options().(*descriptorpb.MethodOptions).GetDeprecated() { 78 | g.P(deprecationComment) 79 | } 80 | g.P(method.Comments.Leading, 81 | clientSignature(g, method)) 82 | } 83 | g.P("}") 84 | g.P() 85 | 86 | // Client structure. 87 | g.P("type ", unexport(clientName), " struct {") 88 | g.P("cc ", grpcPackage.Ident("ClientConnInterface")) 89 | g.P("}") 90 | g.P() 91 | 92 | // NewClient factory. 93 | if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() { 94 | g.P(deprecationComment) 95 | } 96 | g.P("func New", clientName, " (cc ", grpcPackage.Ident("ClientConnInterface"), ") ", clientName, " {") 97 | g.P("return &", unexport(clientName), "{cc}") 98 | g.P("}") 99 | g.P() 100 | 101 | var methodIndex, streamIndex int 102 | // Client method implementations. 103 | for _, method := range service.Methods { 104 | if !method.Desc.IsStreamingServer() && !method.Desc.IsStreamingClient() { 105 | // Unary RPC method 106 | genClientMethod(gen, file, g, method, methodIndex) 107 | methodIndex++ 108 | } else { 109 | // Streaming RPC method 110 | genClientMethod(gen, file, g, method, streamIndex) 111 | streamIndex++ 112 | } 113 | } 114 | 115 | // Server interface. 116 | serverType := service.GoName + "Server" 117 | g.P("// ", serverType, " is the server API for ", service.GoName, " service.") 118 | if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() { 119 | g.P("//") 120 | g.P(deprecationComment) 121 | } 122 | g.Annotate(serverType, service.Location) 123 | g.P("type ", serverType, " interface {") 124 | for _, method := range service.Methods { 125 | g.Annotate(serverType+"."+method.GoName, method.Location) 126 | if method.Desc.Options().(*descriptorpb.MethodOptions).GetDeprecated() { 127 | g.P(deprecationComment) 128 | } 129 | g.P(method.Comments.Leading, 130 | serverSignature(g, method)) 131 | } 132 | g.P("}") 133 | g.P() 134 | 135 | // Server Unimplemented struct for forward compatibility. 136 | g.P("// Unimplemented", serverType, " can be embedded to have forward compatible implementations.") 137 | g.P("type Unimplemented", serverType, " struct {") 138 | g.P("}") 139 | g.P() 140 | for _, method := range service.Methods { 141 | nilArg := "" 142 | if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { 143 | nilArg = "nil," 144 | } 145 | g.P("func (*Unimplemented", serverType, ") ", serverSignature(g, method), "{") 146 | g.P("return ", nilArg, statusPackage.Ident("Errorf"), "(", codesPackage.Ident("Unimplemented"), `, "method `, method.GoName, ` not implemented")`) 147 | g.P("}") 148 | } 149 | g.P() 150 | 151 | // Server registration. 152 | if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() { 153 | g.P(deprecationComment) 154 | } 155 | serviceDescVar := "_" + service.GoName + "_serviceDesc" 156 | g.P("func Register", service.GoName, "Server(s *", grpcPackage.Ident("Server"), ", srv ", serverType, ") {") 157 | g.P("s.RegisterService(&", serviceDescVar, `, srv)`) 158 | g.P("}") 159 | g.P() 160 | 161 | // Server handler implementations. 162 | var handlerNames []string 163 | for _, method := range service.Methods { 164 | hname := genServerMethod(gen, file, g, method) 165 | handlerNames = append(handlerNames, hname) 166 | } 167 | 168 | // Service descriptor. 169 | g.P("var ", serviceDescVar, " = ", grpcPackage.Ident("ServiceDesc"), " {") 170 | g.P("ServiceName: ", strconv.Quote(string(service.Desc.FullName())), ",") 171 | g.P("HandlerType: (*", serverType, ")(nil),") 172 | g.P("Methods: []", grpcPackage.Ident("MethodDesc"), "{") 173 | for i, method := range service.Methods { 174 | if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() { 175 | continue 176 | } 177 | g.P("{") 178 | g.P("MethodName: ", strconv.Quote(string(method.Desc.Name())), ",") 179 | g.P("Handler: ", handlerNames[i], ",") 180 | g.P("},") 181 | } 182 | g.P("},") 183 | g.P("Streams: []", grpcPackage.Ident("StreamDesc"), "{") 184 | for i, method := range service.Methods { 185 | if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { 186 | continue 187 | } 188 | g.P("{") 189 | g.P("StreamName: ", strconv.Quote(string(method.Desc.Name())), ",") 190 | g.P("Handler: ", handlerNames[i], ",") 191 | if method.Desc.IsStreamingServer() { 192 | g.P("ServerStreams: true,") 193 | } 194 | if method.Desc.IsStreamingClient() { 195 | g.P("ClientStreams: true,") 196 | } 197 | g.P("},") 198 | } 199 | g.P("},") 200 | g.P("Metadata: \"", file.Desc.Path(), "\",") 201 | g.P("}") 202 | g.P() 203 | } 204 | 205 | func clientSignature(g *protogen.GeneratedFile, method *protogen.Method) string { 206 | s := method.GoName + "(ctx " + g.QualifiedGoIdent(contextPackage.Ident("Context")) 207 | if !method.Desc.IsStreamingClient() { 208 | s += ", in *" + g.QualifiedGoIdent(method.Input.GoIdent) 209 | } 210 | s += ", opts ..." + g.QualifiedGoIdent(grpcPackage.Ident("CallOption")) + ") (" 211 | if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { 212 | s += "*" + g.QualifiedGoIdent(method.Output.GoIdent) 213 | } else { 214 | s += method.Parent.GoName + "_" + method.GoName + "Client" 215 | } 216 | s += ", error)" 217 | return s 218 | } 219 | 220 | func genClientMethod(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, method *protogen.Method, index int) { 221 | service := method.Parent 222 | sname := fmt.Sprintf("/%s/%s", service.Desc.FullName(), method.Desc.Name()) 223 | 224 | if method.Desc.Options().(*descriptorpb.MethodOptions).GetDeprecated() { 225 | g.P(deprecationComment) 226 | } 227 | g.P("func (c *", unexport(service.GoName), "Client) ", clientSignature(g, method), "{") 228 | if !method.Desc.IsStreamingServer() && !method.Desc.IsStreamingClient() { 229 | g.P("out := new(", method.Output.GoIdent, ")") 230 | g.P(`err := c.cc.Invoke(ctx, "`, sname, `", in, out, opts...)`) 231 | g.P("if err != nil { return nil, err }") 232 | g.P("return out, nil") 233 | g.P("}") 234 | g.P() 235 | return 236 | } 237 | streamType := unexport(service.GoName) + method.GoName + "Client" 238 | serviceDescVar := "_" + service.GoName + "_serviceDesc" 239 | g.P("stream, err := c.cc.NewStream(ctx, &", serviceDescVar, ".Streams[", index, `], "`, sname, `", opts...)`) 240 | g.P("if err != nil { return nil, err }") 241 | g.P("x := &", streamType, "{stream}") 242 | if !method.Desc.IsStreamingClient() { 243 | g.P("if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }") 244 | g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }") 245 | } 246 | g.P("return x, nil") 247 | g.P("}") 248 | g.P() 249 | 250 | genSend := method.Desc.IsStreamingClient() 251 | genRecv := method.Desc.IsStreamingServer() 252 | genCloseAndRecv := !method.Desc.IsStreamingServer() 253 | 254 | // Stream auxiliary types and methods. 255 | g.P("type ", service.GoName, "_", method.GoName, "Client interface {") 256 | if genSend { 257 | g.P("Send(*", method.Input.GoIdent, ") error") 258 | } 259 | if genRecv { 260 | g.P("Recv() (*", method.Output.GoIdent, ", error)") 261 | } 262 | if genCloseAndRecv { 263 | g.P("CloseAndRecv() (*", method.Output.GoIdent, ", error)") 264 | } 265 | g.P(grpcPackage.Ident("ClientStream")) 266 | g.P("}") 267 | g.P() 268 | 269 | g.P("type ", streamType, " struct {") 270 | g.P(grpcPackage.Ident("ClientStream")) 271 | g.P("}") 272 | g.P() 273 | 274 | if genSend { 275 | g.P("func (x *", streamType, ") Send(m *", method.Input.GoIdent, ") error {") 276 | g.P("return x.ClientStream.SendMsg(m)") 277 | g.P("}") 278 | g.P() 279 | } 280 | if genRecv { 281 | g.P("func (x *", streamType, ") Recv() (*", method.Output.GoIdent, ", error) {") 282 | g.P("m := new(", method.Output.GoIdent, ")") 283 | g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }") 284 | g.P("return m, nil") 285 | g.P("}") 286 | g.P() 287 | } 288 | if genCloseAndRecv { 289 | g.P("func (x *", streamType, ") CloseAndRecv() (*", method.Output.GoIdent, ", error) {") 290 | g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }") 291 | g.P("m := new(", method.Output.GoIdent, ")") 292 | g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }") 293 | g.P("return m, nil") 294 | g.P("}") 295 | g.P() 296 | } 297 | } 298 | 299 | func serverSignature(g *protogen.GeneratedFile, method *protogen.Method) string { 300 | var reqArgs []string 301 | ret := "error" 302 | if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { 303 | reqArgs = append(reqArgs, g.QualifiedGoIdent(contextPackage.Ident("Context"))) 304 | ret = "(*" + g.QualifiedGoIdent(method.Output.GoIdent) + ", error)" 305 | } 306 | if !method.Desc.IsStreamingClient() { 307 | reqArgs = append(reqArgs, "*"+g.QualifiedGoIdent(method.Input.GoIdent)) 308 | } 309 | if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() { 310 | reqArgs = append(reqArgs, method.Parent.GoName+"_"+method.GoName+"Server") 311 | } 312 | return method.GoName + "(" + strings.Join(reqArgs, ", ") + ") " + ret 313 | } 314 | 315 | func genServerMethod(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, method *protogen.Method) string { 316 | service := method.Parent 317 | hname := fmt.Sprintf("_%s_%s_Handler", service.GoName, method.GoName) 318 | 319 | if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { 320 | g.P("func ", hname, "(srv interface{}, ctx ", contextPackage.Ident("Context"), ", dec func(interface{}) error, interceptor ", grpcPackage.Ident("UnaryServerInterceptor"), ") (interface{}, error) {") 321 | g.P("in := new(", method.Input.GoIdent, ")") 322 | g.P("if err := dec(in); err != nil { return nil, err }") 323 | g.P("if interceptor == nil { return srv.(", service.GoName, "Server).", method.GoName, "(ctx, in) }") 324 | g.P("info := &", grpcPackage.Ident("UnaryServerInfo"), "{") 325 | g.P("Server: srv,") 326 | g.P("FullMethod: ", strconv.Quote(fmt.Sprintf("/%s/%s", service.Desc.FullName(), method.GoName)), ",") 327 | g.P("}") 328 | g.P("handler := func(ctx ", contextPackage.Ident("Context"), ", req interface{}) (interface{}, error) {") 329 | g.P("return srv.(", service.GoName, "Server).", method.GoName, "(ctx, req.(*", method.Input.GoIdent, "))") 330 | g.P("}") 331 | g.P("return interceptor(ctx, in, info, handler)") 332 | g.P("}") 333 | g.P() 334 | return hname 335 | } 336 | streamType := unexport(service.GoName) + method.GoName + "Server" 337 | g.P("func ", hname, "(srv interface{}, stream ", grpcPackage.Ident("ServerStream"), ") error {") 338 | if !method.Desc.IsStreamingClient() { 339 | g.P("m := new(", method.Input.GoIdent, ")") 340 | g.P("if err := stream.RecvMsg(m); err != nil { return err }") 341 | g.P("return srv.(", service.GoName, "Server).", method.GoName, "(m, &", streamType, "{stream})") 342 | } else { 343 | g.P("return srv.(", service.GoName, "Server).", method.GoName, "(&", streamType, "{stream})") 344 | } 345 | g.P("}") 346 | g.P() 347 | 348 | genSend := method.Desc.IsStreamingServer() 349 | genSendAndClose := !method.Desc.IsStreamingServer() 350 | genRecv := method.Desc.IsStreamingClient() 351 | 352 | // Stream auxiliary types and methods. 353 | g.P("type ", service.GoName, "_", method.GoName, "Server interface {") 354 | if genSend { 355 | g.P("Send(*", method.Output.GoIdent, ") error") 356 | } 357 | if genSendAndClose { 358 | g.P("SendAndClose(*", method.Output.GoIdent, ") error") 359 | } 360 | if genRecv { 361 | g.P("Recv() (*", method.Input.GoIdent, ", error)") 362 | } 363 | g.P(grpcPackage.Ident("ServerStream")) 364 | g.P("}") 365 | g.P() 366 | 367 | g.P("type ", streamType, " struct {") 368 | g.P(grpcPackage.Ident("ServerStream")) 369 | g.P("}") 370 | g.P() 371 | 372 | if genSend { 373 | g.P("func (x *", streamType, ") Send(m *", method.Output.GoIdent, ") error {") 374 | g.P("return x.ServerStream.SendMsg(m)") 375 | g.P("}") 376 | g.P() 377 | } 378 | if genSendAndClose { 379 | g.P("func (x *", streamType, ") SendAndClose(m *", method.Output.GoIdent, ") error {") 380 | g.P("return x.ServerStream.SendMsg(m)") 381 | g.P("}") 382 | g.P() 383 | } 384 | if genRecv { 385 | g.P("func (x *", streamType, ") Recv() (*", method.Input.GoIdent, ", error) {") 386 | g.P("m := new(", method.Input.GoIdent, ")") 387 | g.P("if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }") 388 | g.P("return m, nil") 389 | g.P("}") 390 | g.P() 391 | } 392 | 393 | return hname 394 | } 395 | 396 | const deprecationComment = "// Deprecated: Do not use." 397 | 398 | func unexport(s string) string { return strings.ToLower(s[:1]) + s[1:] } 399 | -------------------------------------------------------------------------------- /internal/testprotos/jsonpb_proto/test2.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | syntax = "proto2"; 6 | 7 | option go_package = "github.com/golang/protobuf/internal/testprotos/jsonpb_proto"; 8 | 9 | import "google/protobuf/any.proto"; 10 | import "google/protobuf/duration.proto"; 11 | import "google/protobuf/struct.proto"; 12 | import "google/protobuf/timestamp.proto"; 13 | import "google/protobuf/wrappers.proto"; 14 | 15 | package jsonpb_test; 16 | 17 | // Test message for holding primitive types. 18 | message Simple { 19 | optional bool o_bool = 1; 20 | optional int32 o_int32 = 2; 21 | optional int32 o_int32_str = 3; 22 | optional int64 o_int64 = 4; 23 | optional int64 o_int64_str = 5; 24 | optional uint32 o_uint32 = 6; 25 | optional uint32 o_uint32_str = 7; 26 | optional uint64 o_uint64 = 8; 27 | optional uint64 o_uint64_str = 9; 28 | optional sint32 o_sint32 = 10; 29 | optional sint32 o_sint32_str = 11; 30 | optional sint64 o_sint64 = 12; 31 | optional sint64 o_sint64_str = 13; 32 | optional float o_float = 14; 33 | optional float o_float_str = 15; 34 | optional double o_double = 16; 35 | optional double o_double_str = 17; 36 | optional string o_string = 18; 37 | optional bytes o_bytes = 19; 38 | } 39 | 40 | // Test message for holding special non-finites primitives. 41 | message NonFinites { 42 | optional float f_nan = 1; 43 | optional float f_pinf = 2; 44 | optional float f_ninf = 3; 45 | optional double d_nan = 4; 46 | optional double d_pinf = 5; 47 | optional double d_ninf = 6; 48 | } 49 | 50 | // Test message for holding repeated primitives. 51 | message Repeats { 52 | repeated bool r_bool = 1; 53 | repeated int32 r_int32 = 2; 54 | repeated int64 r_int64 = 3; 55 | repeated uint32 r_uint32 = 4; 56 | repeated uint64 r_uint64 = 5; 57 | repeated sint32 r_sint32 = 6; 58 | repeated sint64 r_sint64 = 7; 59 | repeated float r_float = 8; 60 | repeated double r_double = 9; 61 | repeated string r_string = 10; 62 | repeated bytes r_bytes = 11; 63 | } 64 | 65 | // Test message for holding enums and nested messages. 66 | message Widget { 67 | enum Color { 68 | RED = 0; 69 | GREEN = 1; 70 | BLUE = 2; 71 | }; 72 | optional Color color = 1; 73 | repeated Color r_color = 2; 74 | 75 | optional Simple simple = 10; 76 | repeated Simple r_simple = 11; 77 | 78 | optional Repeats repeats = 20; 79 | repeated Repeats r_repeats = 21; 80 | } 81 | 82 | message Maps { 83 | map m_int64_str = 1; 84 | map m_bool_simple = 2; 85 | } 86 | 87 | message MsgWithOneof { 88 | oneof union { 89 | string title = 1; 90 | int64 salary = 2; 91 | string Country = 3; 92 | string home_address = 4; 93 | MsgWithRequired msg_with_required = 5; 94 | google.protobuf.NullValue null_value = 6; 95 | } 96 | } 97 | 98 | message Real { 99 | optional double value = 1; 100 | extensions 100 to max; 101 | } 102 | 103 | extend Real { 104 | optional string name = 124; 105 | } 106 | 107 | message Complex { 108 | extend Real { 109 | optional Complex real_extension = 123; 110 | } 111 | optional double imaginary = 1; 112 | extensions 100 to max; 113 | } 114 | 115 | message KnownTypes { 116 | optional google.protobuf.Any an = 14; 117 | optional google.protobuf.Duration dur = 1; 118 | optional google.protobuf.Struct st = 12; 119 | optional google.protobuf.Timestamp ts = 2; 120 | optional google.protobuf.ListValue lv = 15; 121 | optional google.protobuf.Value val = 16; 122 | 123 | optional google.protobuf.DoubleValue dbl = 3; 124 | optional google.protobuf.FloatValue flt = 4; 125 | optional google.protobuf.Int64Value i64 = 5; 126 | optional google.protobuf.UInt64Value u64 = 6; 127 | optional google.protobuf.Int32Value i32 = 7; 128 | optional google.protobuf.UInt32Value u32 = 8; 129 | optional google.protobuf.BoolValue bool = 9; 130 | optional google.protobuf.StringValue str = 10; 131 | optional google.protobuf.BytesValue bytes = 11; 132 | } 133 | 134 | // Test messages for marshaling/unmarshaling required fields. 135 | message MsgWithRequired { 136 | required string str = 1; 137 | } 138 | 139 | message MsgWithIndirectRequired { 140 | optional MsgWithRequired subm = 1; 141 | map map_field = 2; 142 | repeated MsgWithRequired slice_field = 3; 143 | } 144 | 145 | message MsgWithRequiredBytes { 146 | required bytes byts = 1; 147 | } 148 | 149 | message MsgWithRequiredWKT { 150 | required google.protobuf.StringValue str = 1; 151 | } 152 | 153 | extend Real { 154 | optional MsgWithRequired extm = 125; 155 | } 156 | -------------------------------------------------------------------------------- /internal/testprotos/jsonpb_proto/test3.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | syntax = "proto3"; 6 | 7 | option go_package = "github.com/golang/protobuf/internal/testprotos/jsonpb_proto"; 8 | 9 | package jsonpb_test; 10 | 11 | message Simple3 { 12 | double dub = 1; 13 | } 14 | 15 | message SimpleSlice3 { 16 | repeated string slices = 1; 17 | } 18 | 19 | message SimpleMap3 { 20 | map stringy = 1; 21 | } 22 | 23 | message SimpleNull3 { 24 | Simple3 simple = 1; 25 | } 26 | 27 | enum Numeral { 28 | UNKNOWN = 0; 29 | ARABIC = 1; 30 | ROMAN = 2; 31 | } 32 | 33 | message Mappy { 34 | map nummy = 1; 35 | map strry = 2; 36 | map objjy = 3; 37 | map buggy = 4; 38 | map booly = 5; 39 | map enumy = 6; 40 | map s32booly = 7; 41 | map s64booly = 8; 42 | map u32booly = 9; 43 | map u64booly = 10; 44 | } 45 | -------------------------------------------------------------------------------- /internal/testprotos/proto2_proto/test.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // A feature-rich test file for the protocol compiler and libraries. 6 | 7 | syntax = "proto2"; 8 | 9 | option go_package = "github.com/golang/protobuf/internal/testprotos/proto2_proto"; 10 | 11 | package proto2_test; 12 | 13 | enum FOO { FOO1 = 1; }; 14 | 15 | message GoEnum { 16 | required FOO foo = 1; 17 | } 18 | 19 | message GoTestField { 20 | required string Label = 1; 21 | required string Type = 2; 22 | } 23 | 24 | message GoTest { 25 | // An enum, for completeness. 26 | enum KIND { 27 | VOID = 0; 28 | 29 | // Basic types 30 | BOOL = 1; 31 | BYTES = 2; 32 | FINGERPRINT = 3; 33 | FLOAT = 4; 34 | INT = 5; 35 | STRING = 6; 36 | TIME = 7; 37 | 38 | // Groupings 39 | TUPLE = 8; 40 | ARRAY = 9; 41 | MAP = 10; 42 | 43 | // Table types 44 | TABLE = 11; 45 | 46 | // Functions 47 | FUNCTION = 12; // last tag 48 | }; 49 | 50 | // Some typical parameters 51 | required KIND Kind = 1; 52 | optional string Table = 2; 53 | optional int32 Param = 3; 54 | 55 | // Required, repeated and optional foreign fields. 56 | required GoTestField RequiredField = 4; 57 | repeated GoTestField RepeatedField = 5; 58 | optional GoTestField OptionalField = 6; 59 | 60 | // Required fields of all basic types 61 | required bool F_Bool_required = 10; 62 | required int32 F_Int32_required = 11; 63 | required int64 F_Int64_required = 12; 64 | required fixed32 F_Fixed32_required = 13; 65 | required fixed64 F_Fixed64_required = 14; 66 | required uint32 F_Uint32_required = 15; 67 | required uint64 F_Uint64_required = 16; 68 | required float F_Float_required = 17; 69 | required double F_Double_required = 18; 70 | required string F_String_required = 19; 71 | required bytes F_Bytes_required = 101; 72 | required sint32 F_Sint32_required = 102; 73 | required sint64 F_Sint64_required = 103; 74 | required sfixed32 F_Sfixed32_required = 104; 75 | required sfixed64 F_Sfixed64_required = 105; 76 | 77 | // Repeated fields of all basic types 78 | repeated bool F_Bool_repeated = 20; 79 | repeated int32 F_Int32_repeated = 21; 80 | repeated int64 F_Int64_repeated = 22; 81 | repeated fixed32 F_Fixed32_repeated = 23; 82 | repeated fixed64 F_Fixed64_repeated = 24; 83 | repeated uint32 F_Uint32_repeated = 25; 84 | repeated uint64 F_Uint64_repeated = 26; 85 | repeated float F_Float_repeated = 27; 86 | repeated double F_Double_repeated = 28; 87 | repeated string F_String_repeated = 29; 88 | repeated bytes F_Bytes_repeated = 201; 89 | repeated sint32 F_Sint32_repeated = 202; 90 | repeated sint64 F_Sint64_repeated = 203; 91 | repeated sfixed32 F_Sfixed32_repeated = 204; 92 | repeated sfixed64 F_Sfixed64_repeated = 205; 93 | 94 | // Optional fields of all basic types 95 | optional bool F_Bool_optional = 30; 96 | optional int32 F_Int32_optional = 31; 97 | optional int64 F_Int64_optional = 32; 98 | optional fixed32 F_Fixed32_optional = 33; 99 | optional fixed64 F_Fixed64_optional = 34; 100 | optional uint32 F_Uint32_optional = 35; 101 | optional uint64 F_Uint64_optional = 36; 102 | optional float F_Float_optional = 37; 103 | optional double F_Double_optional = 38; 104 | optional string F_String_optional = 39; 105 | optional bytes F_Bytes_optional = 301; 106 | optional sint32 F_Sint32_optional = 302; 107 | optional sint64 F_Sint64_optional = 303; 108 | optional sfixed32 F_Sfixed32_optional = 304; 109 | optional sfixed64 F_Sfixed64_optional = 305; 110 | 111 | // Default-valued fields of all basic types 112 | optional bool F_Bool_defaulted = 40 [default=true]; 113 | optional int32 F_Int32_defaulted = 41 [default=32]; 114 | optional int64 F_Int64_defaulted = 42 [default=64]; 115 | optional fixed32 F_Fixed32_defaulted = 43 [default=320]; 116 | optional fixed64 F_Fixed64_defaulted = 44 [default=640]; 117 | optional uint32 F_Uint32_defaulted = 45 [default=3200]; 118 | optional uint64 F_Uint64_defaulted = 46 [default=6400]; 119 | optional float F_Float_defaulted = 47 [default=314159.]; 120 | optional double F_Double_defaulted = 48 [default=271828.]; 121 | optional string F_String_defaulted = 49 [default="hello, \"world!\"\n"]; 122 | optional bytes F_Bytes_defaulted = 401 [default="Bignose"]; 123 | optional sint32 F_Sint32_defaulted = 402 [default = -32]; 124 | optional sint64 F_Sint64_defaulted = 403 [default = -64]; 125 | optional sfixed32 F_Sfixed32_defaulted = 404 [default = -32]; 126 | optional sfixed64 F_Sfixed64_defaulted = 405 [default = -64]; 127 | 128 | // Packed repeated fields (no string or bytes). 129 | repeated bool F_Bool_repeated_packed = 50 [packed=true]; 130 | repeated int32 F_Int32_repeated_packed = 51 [packed=true]; 131 | repeated int64 F_Int64_repeated_packed = 52 [packed=true]; 132 | repeated fixed32 F_Fixed32_repeated_packed = 53 [packed=true]; 133 | repeated fixed64 F_Fixed64_repeated_packed = 54 [packed=true]; 134 | repeated uint32 F_Uint32_repeated_packed = 55 [packed=true]; 135 | repeated uint64 F_Uint64_repeated_packed = 56 [packed=true]; 136 | repeated float F_Float_repeated_packed = 57 [packed=true]; 137 | repeated double F_Double_repeated_packed = 58 [packed=true]; 138 | repeated sint32 F_Sint32_repeated_packed = 502 [packed=true]; 139 | repeated sint64 F_Sint64_repeated_packed = 503 [packed=true]; 140 | repeated sfixed32 F_Sfixed32_repeated_packed = 504 [packed=true]; 141 | repeated sfixed64 F_Sfixed64_repeated_packed = 505 [packed=true]; 142 | 143 | // Required, repeated, and optional groups. 144 | required group RequiredGroup = 70 { 145 | required string RequiredField = 71; 146 | }; 147 | 148 | repeated group RepeatedGroup = 80 { 149 | required string RequiredField = 81; 150 | }; 151 | 152 | optional group OptionalGroup = 90 { 153 | required string RequiredField = 91; 154 | }; 155 | } 156 | 157 | // For testing a group containing a required field. 158 | message GoTestRequiredGroupField { 159 | required group Group = 1 { 160 | required int32 Field = 2; 161 | }; 162 | } 163 | 164 | // For testing skipping of unrecognized fields. 165 | // Numbers are all big, larger than tag numbers in GoTestField, 166 | // the message used in the corresponding test. 167 | message GoSkipTest { 168 | required int32 skip_int32 = 11; 169 | required fixed32 skip_fixed32 = 12; 170 | required fixed64 skip_fixed64 = 13; 171 | required string skip_string = 14; 172 | required group SkipGroup = 15 { 173 | required int32 group_int32 = 16; 174 | required string group_string = 17; 175 | } 176 | } 177 | 178 | // For testing packed/non-packed decoder switching. 179 | // A serialized instance of one should be deserializable as the other. 180 | message NonPackedTest { 181 | repeated int32 a = 1; 182 | } 183 | 184 | message PackedTest { 185 | repeated int32 b = 1 [packed=true]; 186 | } 187 | 188 | message MaxTag { 189 | // Maximum possible tag number. 190 | optional string last_field = 536870911; 191 | } 192 | 193 | message OldMessage { 194 | message Nested { 195 | optional string name = 1; 196 | } 197 | optional Nested nested = 1; 198 | 199 | optional int32 num = 2; 200 | } 201 | 202 | // NewMessage is wire compatible with OldMessage; 203 | // imagine it as a future version. 204 | message NewMessage { 205 | message Nested { 206 | optional string name = 1; 207 | optional string food_group = 2; 208 | } 209 | optional Nested nested = 1; 210 | 211 | // This is an int32 in OldMessage. 212 | optional int64 num = 2; 213 | } 214 | 215 | // Smaller tests for ASCII formatting. 216 | 217 | message InnerMessage { 218 | required string host = 1; 219 | optional int32 port = 2 [default=4000]; 220 | optional bool connected = 3; 221 | } 222 | 223 | message OtherMessage { 224 | optional int64 key = 1; 225 | optional bytes value = 2; 226 | optional float weight = 3; 227 | optional InnerMessage inner = 4; 228 | 229 | extensions 100 to max; 230 | } 231 | 232 | message RequiredInnerMessage { 233 | required InnerMessage leo_finally_won_an_oscar = 1; 234 | } 235 | 236 | message MyMessage { 237 | required int32 count = 1; 238 | optional string name = 2; 239 | optional string quote = 3; 240 | repeated string pet = 4; 241 | optional InnerMessage inner = 5; 242 | repeated OtherMessage others = 6; 243 | optional RequiredInnerMessage we_must_go_deeper = 13; 244 | repeated InnerMessage rep_inner = 12; 245 | 246 | enum Color { 247 | RED = 0; 248 | GREEN = 1; 249 | BLUE = 2; 250 | }; 251 | optional Color bikeshed = 7; 252 | 253 | optional group SomeGroup = 8 { 254 | optional int32 group_field = 9; 255 | } 256 | 257 | // This field becomes [][]byte in the generated code. 258 | repeated bytes rep_bytes = 10; 259 | 260 | optional double bigfloat = 11; 261 | 262 | extensions 100 to max; 263 | } 264 | 265 | message Ext { 266 | extend MyMessage { 267 | optional Ext more = 103; 268 | optional string text = 104; 269 | optional int32 number = 105; 270 | } 271 | 272 | optional string data = 1; 273 | map map_field = 2; 274 | } 275 | 276 | extend MyMessage { 277 | repeated string greeting = 106; 278 | // leave field 200 unregistered for testing 279 | } 280 | 281 | message ComplexExtension { 282 | optional int32 first = 1; 283 | optional int32 second = 2; 284 | repeated int32 third = 3; 285 | } 286 | 287 | extend OtherMessage { 288 | optional ComplexExtension complex = 200; 289 | repeated ComplexExtension r_complex = 201; 290 | } 291 | 292 | message DefaultsMessage { 293 | enum DefaultsEnum { 294 | ZERO = 0; 295 | ONE = 1; 296 | TWO = 2; 297 | }; 298 | extensions 100 to max; 299 | } 300 | 301 | extend DefaultsMessage { 302 | optional double no_default_double = 101; 303 | optional float no_default_float = 102; 304 | optional int32 no_default_int32 = 103; 305 | optional int64 no_default_int64 = 104; 306 | optional uint32 no_default_uint32 = 105; 307 | optional uint64 no_default_uint64 = 106; 308 | optional sint32 no_default_sint32 = 107; 309 | optional sint64 no_default_sint64 = 108; 310 | optional fixed32 no_default_fixed32 = 109; 311 | optional fixed64 no_default_fixed64 = 110; 312 | optional sfixed32 no_default_sfixed32 = 111; 313 | optional sfixed64 no_default_sfixed64 = 112; 314 | optional bool no_default_bool = 113; 315 | optional string no_default_string = 114; 316 | optional bytes no_default_bytes = 115; 317 | optional DefaultsMessage.DefaultsEnum no_default_enum = 116; 318 | 319 | optional double default_double = 201 [default = 3.1415]; 320 | optional float default_float = 202 [default = 3.14]; 321 | optional int32 default_int32 = 203 [default = 42]; 322 | optional int64 default_int64 = 204 [default = 43]; 323 | optional uint32 default_uint32 = 205 [default = 44]; 324 | optional uint64 default_uint64 = 206 [default = 45]; 325 | optional sint32 default_sint32 = 207 [default = 46]; 326 | optional sint64 default_sint64 = 208 [default = 47]; 327 | optional fixed32 default_fixed32 = 209 [default = 48]; 328 | optional fixed64 default_fixed64 = 210 [default = 49]; 329 | optional sfixed32 default_sfixed32 = 211 [default = 50]; 330 | optional sfixed64 default_sfixed64 = 212 [default = 51]; 331 | optional bool default_bool = 213 [default = true]; 332 | optional string default_string = 214 [default = "Hello, string,def=foo"]; 333 | optional bytes default_bytes = 215 [default = "Hello, bytes"]; 334 | optional DefaultsMessage.DefaultsEnum default_enum = 216 [default = ONE]; 335 | } 336 | 337 | message Empty { 338 | } 339 | 340 | message MessageList { 341 | repeated group Message = 1 { 342 | required string name = 2; 343 | required int32 count = 3; 344 | } 345 | } 346 | 347 | message Strings { 348 | optional string string_field = 1; 349 | optional bytes bytes_field = 2; 350 | } 351 | 352 | message Defaults { 353 | enum Color { 354 | RED = 0; 355 | GREEN = 1; 356 | BLUE = 2; 357 | } 358 | 359 | // Default-valued fields of all basic types. 360 | // Same as GoTest, but copied here to make testing easier. 361 | optional bool F_Bool = 1 [default=true]; 362 | optional int32 F_Int32 = 2 [default=32]; 363 | optional int64 F_Int64 = 3 [default=64]; 364 | optional fixed32 F_Fixed32 = 4 [default=320]; 365 | optional fixed64 F_Fixed64 = 5 [default=640]; 366 | optional uint32 F_Uint32 = 6 [default=3200]; 367 | optional uint64 F_Uint64 = 7 [default=6400]; 368 | optional float F_Float = 8 [default=314159.]; 369 | optional double F_Double = 9 [default=271828.]; 370 | optional string F_String = 10 [default="hello, \"world!\"\n"]; 371 | optional bytes F_Bytes = 11 [default="Bignose"]; 372 | optional sint32 F_Sint32 = 12 [default=-32]; 373 | optional sint64 F_Sint64 = 13 [default=-64]; 374 | optional Color F_Enum = 14 [default=GREEN]; 375 | 376 | // More fields with crazy defaults. 377 | optional float F_Pinf = 15 [default=inf]; 378 | optional float F_Ninf = 16 [default=-inf]; 379 | optional float F_Nan = 17 [default=nan]; 380 | 381 | // Sub-message. 382 | optional SubDefaults sub = 18; 383 | 384 | // Redundant but explicit defaults. 385 | optional string str_zero = 19 [default=""]; 386 | } 387 | 388 | message SubDefaults { 389 | optional int64 n = 1 [default=7]; 390 | } 391 | 392 | message RepeatedEnum { 393 | enum Color { 394 | RED = 1; 395 | } 396 | repeated Color color = 1; 397 | } 398 | 399 | message MoreRepeated { 400 | repeated bool bools = 1; 401 | repeated bool bools_packed = 2 [packed=true]; 402 | repeated int32 ints = 3; 403 | repeated int32 ints_packed = 4 [packed=true]; 404 | repeated int64 int64s_packed = 7 [packed=true]; 405 | repeated string strings = 5; 406 | repeated fixed32 fixeds = 6; 407 | } 408 | 409 | // GroupOld and GroupNew have the same wire format. 410 | // GroupNew has a new field inside a group. 411 | 412 | message GroupOld { 413 | optional group G = 101 { 414 | optional int32 x = 2; 415 | } 416 | } 417 | 418 | message GroupNew { 419 | optional group G = 101 { 420 | optional int32 x = 2; 421 | optional int32 y = 3; 422 | } 423 | } 424 | 425 | message FloatingPoint { 426 | required double f = 1; 427 | optional bool exact = 2; 428 | } 429 | 430 | message MessageWithMap { 431 | map name_mapping = 1; 432 | map msg_mapping = 2; 433 | map byte_mapping = 3; 434 | map str_to_str = 4; 435 | } 436 | 437 | message Oneof { 438 | oneof union { 439 | bool F_Bool = 1; 440 | int32 F_Int32 = 2; 441 | int64 F_Int64 = 3; 442 | fixed32 F_Fixed32 = 4; 443 | fixed64 F_Fixed64 = 5; 444 | uint32 F_Uint32 = 6; 445 | uint64 F_Uint64 = 7; 446 | float F_Float = 8; 447 | double F_Double = 9; 448 | string F_String = 10; 449 | bytes F_Bytes = 11; 450 | sint32 F_Sint32 = 12; 451 | sint64 F_Sint64 = 13; 452 | MyMessage.Color F_Enum = 14; 453 | GoTestField F_Message = 15; 454 | group F_Group = 16 { 455 | optional int32 x = 17; 456 | } 457 | int32 F_Largest_Tag = 536870911; 458 | } 459 | 460 | oneof tormato { 461 | int32 value = 100; 462 | } 463 | } 464 | 465 | message Communique { 466 | optional bool make_me_cry = 1; 467 | 468 | // This is a oneof, called "union". 469 | oneof union { 470 | int32 number = 5; 471 | string name = 6; 472 | bytes data = 7; 473 | double temp_c = 8; 474 | MyMessage.Color col = 9; 475 | Strings msg = 10; 476 | } 477 | } 478 | 479 | message TestUTF8 { 480 | optional string scalar = 1; 481 | repeated string vector = 2; 482 | oneof oneof { string field = 3; } 483 | map map_key = 4; 484 | map map_value = 5; 485 | } 486 | -------------------------------------------------------------------------------- /internal/testprotos/proto3_proto/test.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | syntax = "proto3"; 6 | 7 | option go_package = "github.com/golang/protobuf/internal/testprotos/proto3_proto"; 8 | 9 | import "google/protobuf/any.proto"; 10 | import "proto2_proto/test.proto"; 11 | 12 | package proto3_test; 13 | 14 | message Message { 15 | enum Humour { 16 | UNKNOWN = 0; 17 | PUNS = 1; 18 | SLAPSTICK = 2; 19 | BILL_BAILEY = 3; 20 | } 21 | 22 | string name = 1; 23 | Humour hilarity = 2; 24 | uint32 height_in_cm = 3; 25 | bytes data = 4; 26 | int64 result_count = 7; 27 | bool true_scotsman = 8; 28 | float score = 9; 29 | 30 | repeated uint64 key = 5; 31 | repeated int32 short_key = 19; 32 | Nested nested = 6; 33 | repeated Humour r_funny = 16; 34 | 35 | map terrain = 10; 36 | proto2_test.SubDefaults proto2_field = 11; 37 | map proto2_value = 13; 38 | 39 | google.protobuf.Any anything = 14; 40 | repeated google.protobuf.Any many_things = 15; 41 | 42 | Message submessage = 17; 43 | repeated Message children = 18; 44 | 45 | map string_map = 20; 46 | } 47 | 48 | message Nested { 49 | string bunny = 1; 50 | bool cute = 2; 51 | } 52 | 53 | message MessageWithMap { 54 | map byte_mapping = 1; 55 | } 56 | 57 | 58 | message IntMap { 59 | map rtt = 1; 60 | } 61 | 62 | message IntMaps { 63 | repeated IntMap maps = 1; 64 | } 65 | 66 | message TestUTF8 { 67 | string scalar = 1; 68 | repeated string vector = 2; 69 | oneof oneof { string field = 3; } 70 | map map_key = 4; 71 | map map_value = 5; 72 | } 73 | -------------------------------------------------------------------------------- /internal/testprotos/regenerate.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2020 The Go Authors. All rights reserved. 3 | # Use of this source code is governed by a BSD-style 4 | # license that can be found in the LICENSE file. 5 | 6 | # NOTE: The integration scripts deliberately do not check to 7 | # make sure that the test protos have been regenerated. 8 | # It is intentional that older versions of the .pb.go files 9 | # are checked in to ensure that they continue to function. 10 | # 11 | # Versions used: 12 | # protoc: v3.9.1 13 | # protoc-gen-go: v1.3.2 14 | 15 | for X in $(find . -name "*.proto" | sed "s|^\./||"); do 16 | protoc -I$(pwd) --go_out=paths=source_relative:. $X 17 | done 18 | -------------------------------------------------------------------------------- /jsonpb/json.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package jsonpb provides functionality to marshal and unmarshal between a 6 | // protocol buffer message and JSON. It follows the specification at 7 | // https://developers.google.com/protocol-buffers/docs/proto3#json. 8 | // 9 | // Do not rely on the default behavior of the standard encoding/json package 10 | // when called on generated message types as it does not operate correctly. 11 | // 12 | // Deprecated: Use the "google.golang.org/protobuf/encoding/protojson" 13 | // package instead. 14 | package jsonpb 15 | 16 | import ( 17 | "github.com/golang/protobuf/proto" 18 | "google.golang.org/protobuf/reflect/protoreflect" 19 | "google.golang.org/protobuf/reflect/protoregistry" 20 | "google.golang.org/protobuf/runtime/protoimpl" 21 | ) 22 | 23 | // AnyResolver takes a type URL, present in an Any message, 24 | // and resolves it into an instance of the associated message. 25 | type AnyResolver interface { 26 | Resolve(typeURL string) (proto.Message, error) 27 | } 28 | 29 | type anyResolver struct{ AnyResolver } 30 | 31 | func (r anyResolver) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) { 32 | return r.FindMessageByURL(string(message)) 33 | } 34 | 35 | func (r anyResolver) FindMessageByURL(url string) (protoreflect.MessageType, error) { 36 | m, err := r.Resolve(url) 37 | if err != nil { 38 | return nil, err 39 | } 40 | return protoimpl.X.MessageTypeOf(m), nil 41 | } 42 | 43 | func (r anyResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) { 44 | return protoregistry.GlobalTypes.FindExtensionByName(field) 45 | } 46 | 47 | func (r anyResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) { 48 | return protoregistry.GlobalTypes.FindExtensionByNumber(message, field) 49 | } 50 | 51 | func wellKnownType(s protoreflect.FullName) string { 52 | if s.Parent() == "google.protobuf" { 53 | switch s.Name() { 54 | case "Empty", "Any", 55 | "BoolValue", "BytesValue", "StringValue", 56 | "Int32Value", "UInt32Value", "FloatValue", 57 | "Int64Value", "UInt64Value", "DoubleValue", 58 | "Duration", "Timestamp", 59 | "NullValue", "Struct", "Value", "ListValue": 60 | return string(s.Name()) 61 | } 62 | } 63 | return "" 64 | } 65 | 66 | func isMessageSet(md protoreflect.MessageDescriptor) bool { 67 | ms, ok := md.(interface{ IsMessageSet() bool }) 68 | return ok && ms.IsMessageSet() 69 | } 70 | -------------------------------------------------------------------------------- /proto/buffer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package proto 6 | 7 | import ( 8 | "errors" 9 | "fmt" 10 | 11 | "google.golang.org/protobuf/encoding/prototext" 12 | "google.golang.org/protobuf/encoding/protowire" 13 | "google.golang.org/protobuf/runtime/protoimpl" 14 | ) 15 | 16 | const ( 17 | WireVarint = 0 18 | WireFixed32 = 5 19 | WireFixed64 = 1 20 | WireBytes = 2 21 | WireStartGroup = 3 22 | WireEndGroup = 4 23 | ) 24 | 25 | // EncodeVarint returns the varint encoded bytes of v. 26 | func EncodeVarint(v uint64) []byte { 27 | return protowire.AppendVarint(nil, v) 28 | } 29 | 30 | // SizeVarint returns the length of the varint encoded bytes of v. 31 | // This is equal to len(EncodeVarint(v)). 32 | func SizeVarint(v uint64) int { 33 | return protowire.SizeVarint(v) 34 | } 35 | 36 | // DecodeVarint parses a varint encoded integer from b, 37 | // returning the integer value and the length of the varint. 38 | // It returns (0, 0) if there is a parse error. 39 | func DecodeVarint(b []byte) (uint64, int) { 40 | v, n := protowire.ConsumeVarint(b) 41 | if n < 0 { 42 | return 0, 0 43 | } 44 | return v, n 45 | } 46 | 47 | // Buffer is a buffer for encoding and decoding the protobuf wire format. 48 | // It may be reused between invocations to reduce memory usage. 49 | type Buffer struct { 50 | buf []byte 51 | idx int 52 | deterministic bool 53 | } 54 | 55 | // NewBuffer allocates a new Buffer initialized with buf, 56 | // where the contents of buf are considered the unread portion of the buffer. 57 | func NewBuffer(buf []byte) *Buffer { 58 | return &Buffer{buf: buf} 59 | } 60 | 61 | // SetDeterministic specifies whether to use deterministic serialization. 62 | // 63 | // Deterministic serialization guarantees that for a given binary, equal 64 | // messages will always be serialized to the same bytes. This implies: 65 | // 66 | // - Repeated serialization of a message will return the same bytes. 67 | // - Different processes of the same binary (which may be executing on 68 | // different machines) will serialize equal messages to the same bytes. 69 | // 70 | // Note that the deterministic serialization is NOT canonical across 71 | // languages. It is not guaranteed to remain stable over time. It is unstable 72 | // across different builds with schema changes due to unknown fields. 73 | // Users who need canonical serialization (e.g., persistent storage in a 74 | // canonical form, fingerprinting, etc.) should define their own 75 | // canonicalization specification and implement their own serializer rather 76 | // than relying on this API. 77 | // 78 | // If deterministic serialization is requested, map entries will be sorted 79 | // by keys in lexographical order. This is an implementation detail and 80 | // subject to change. 81 | func (b *Buffer) SetDeterministic(deterministic bool) { 82 | b.deterministic = deterministic 83 | } 84 | 85 | // SetBuf sets buf as the internal buffer, 86 | // where the contents of buf are considered the unread portion of the buffer. 87 | func (b *Buffer) SetBuf(buf []byte) { 88 | b.buf = buf 89 | b.idx = 0 90 | } 91 | 92 | // Reset clears the internal buffer of all written and unread data. 93 | func (b *Buffer) Reset() { 94 | b.buf = b.buf[:0] 95 | b.idx = 0 96 | } 97 | 98 | // Bytes returns the internal buffer. 99 | func (b *Buffer) Bytes() []byte { 100 | return b.buf 101 | } 102 | 103 | // Unread returns the unread portion of the buffer. 104 | func (b *Buffer) Unread() []byte { 105 | return b.buf[b.idx:] 106 | } 107 | 108 | // Marshal appends the wire-format encoding of m to the buffer. 109 | func (b *Buffer) Marshal(m Message) error { 110 | var err error 111 | b.buf, err = marshalAppend(b.buf, m, b.deterministic) 112 | return err 113 | } 114 | 115 | // Unmarshal parses the wire-format message in the buffer and 116 | // places the decoded results in m. 117 | // It does not reset m before unmarshaling. 118 | func (b *Buffer) Unmarshal(m Message) error { 119 | err := UnmarshalMerge(b.Unread(), m) 120 | b.idx = len(b.buf) 121 | return err 122 | } 123 | 124 | type unknownFields struct{ XXX_unrecognized protoimpl.UnknownFields } 125 | 126 | func (m *unknownFields) String() string { panic("not implemented") } 127 | func (m *unknownFields) Reset() { panic("not implemented") } 128 | func (m *unknownFields) ProtoMessage() { panic("not implemented") } 129 | 130 | // DebugPrint dumps the encoded bytes of b with a header and footer including s 131 | // to stdout. This is only intended for debugging. 132 | func (*Buffer) DebugPrint(s string, b []byte) { 133 | m := MessageReflect(new(unknownFields)) 134 | m.SetUnknown(b) 135 | b, _ = prototext.MarshalOptions{AllowPartial: true, Indent: "\t"}.Marshal(m.Interface()) 136 | fmt.Printf("==== %s ====\n%s==== %s ====\n", s, b, s) 137 | } 138 | 139 | // EncodeVarint appends an unsigned varint encoding to the buffer. 140 | func (b *Buffer) EncodeVarint(v uint64) error { 141 | b.buf = protowire.AppendVarint(b.buf, v) 142 | return nil 143 | } 144 | 145 | // EncodeZigzag32 appends a 32-bit zig-zag varint encoding to the buffer. 146 | func (b *Buffer) EncodeZigzag32(v uint64) error { 147 | return b.EncodeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) 148 | } 149 | 150 | // EncodeZigzag64 appends a 64-bit zig-zag varint encoding to the buffer. 151 | func (b *Buffer) EncodeZigzag64(v uint64) error { 152 | return b.EncodeVarint(uint64((uint64(v) << 1) ^ uint64((int64(v) >> 63)))) 153 | } 154 | 155 | // EncodeFixed32 appends a 32-bit little-endian integer to the buffer. 156 | func (b *Buffer) EncodeFixed32(v uint64) error { 157 | b.buf = protowire.AppendFixed32(b.buf, uint32(v)) 158 | return nil 159 | } 160 | 161 | // EncodeFixed64 appends a 64-bit little-endian integer to the buffer. 162 | func (b *Buffer) EncodeFixed64(v uint64) error { 163 | b.buf = protowire.AppendFixed64(b.buf, uint64(v)) 164 | return nil 165 | } 166 | 167 | // EncodeRawBytes appends a length-prefixed raw bytes to the buffer. 168 | func (b *Buffer) EncodeRawBytes(v []byte) error { 169 | b.buf = protowire.AppendBytes(b.buf, v) 170 | return nil 171 | } 172 | 173 | // EncodeStringBytes appends a length-prefixed raw bytes to the buffer. 174 | // It does not validate whether v contains valid UTF-8. 175 | func (b *Buffer) EncodeStringBytes(v string) error { 176 | b.buf = protowire.AppendString(b.buf, v) 177 | return nil 178 | } 179 | 180 | // EncodeMessage appends a length-prefixed encoded message to the buffer. 181 | func (b *Buffer) EncodeMessage(m Message) error { 182 | var err error 183 | b.buf = protowire.AppendVarint(b.buf, uint64(Size(m))) 184 | b.buf, err = marshalAppend(b.buf, m, b.deterministic) 185 | return err 186 | } 187 | 188 | // DecodeVarint consumes an encoded unsigned varint from the buffer. 189 | func (b *Buffer) DecodeVarint() (uint64, error) { 190 | v, n := protowire.ConsumeVarint(b.buf[b.idx:]) 191 | if n < 0 { 192 | return 0, protowire.ParseError(n) 193 | } 194 | b.idx += n 195 | return uint64(v), nil 196 | } 197 | 198 | // DecodeZigzag32 consumes an encoded 32-bit zig-zag varint from the buffer. 199 | func (b *Buffer) DecodeZigzag32() (uint64, error) { 200 | v, err := b.DecodeVarint() 201 | if err != nil { 202 | return 0, err 203 | } 204 | return uint64((uint32(v) >> 1) ^ uint32((int32(v&1)<<31)>>31)), nil 205 | } 206 | 207 | // DecodeZigzag64 consumes an encoded 64-bit zig-zag varint from the buffer. 208 | func (b *Buffer) DecodeZigzag64() (uint64, error) { 209 | v, err := b.DecodeVarint() 210 | if err != nil { 211 | return 0, err 212 | } 213 | return uint64((uint64(v) >> 1) ^ uint64((int64(v&1)<<63)>>63)), nil 214 | } 215 | 216 | // DecodeFixed32 consumes a 32-bit little-endian integer from the buffer. 217 | func (b *Buffer) DecodeFixed32() (uint64, error) { 218 | v, n := protowire.ConsumeFixed32(b.buf[b.idx:]) 219 | if n < 0 { 220 | return 0, protowire.ParseError(n) 221 | } 222 | b.idx += n 223 | return uint64(v), nil 224 | } 225 | 226 | // DecodeFixed64 consumes a 64-bit little-endian integer from the buffer. 227 | func (b *Buffer) DecodeFixed64() (uint64, error) { 228 | v, n := protowire.ConsumeFixed64(b.buf[b.idx:]) 229 | if n < 0 { 230 | return 0, protowire.ParseError(n) 231 | } 232 | b.idx += n 233 | return uint64(v), nil 234 | } 235 | 236 | // DecodeRawBytes consumes a length-prefixed raw bytes from the buffer. 237 | // If alloc is specified, it returns a copy the raw bytes 238 | // rather than a sub-slice of the buffer. 239 | func (b *Buffer) DecodeRawBytes(alloc bool) ([]byte, error) { 240 | v, n := protowire.ConsumeBytes(b.buf[b.idx:]) 241 | if n < 0 { 242 | return nil, protowire.ParseError(n) 243 | } 244 | b.idx += n 245 | if alloc { 246 | v = append([]byte(nil), v...) 247 | } 248 | return v, nil 249 | } 250 | 251 | // DecodeStringBytes consumes a length-prefixed raw bytes from the buffer. 252 | // It does not validate whether the raw bytes contain valid UTF-8. 253 | func (b *Buffer) DecodeStringBytes() (string, error) { 254 | v, n := protowire.ConsumeString(b.buf[b.idx:]) 255 | if n < 0 { 256 | return "", protowire.ParseError(n) 257 | } 258 | b.idx += n 259 | return v, nil 260 | } 261 | 262 | // DecodeMessage consumes a length-prefixed message from the buffer. 263 | // It does not reset m before unmarshaling. 264 | func (b *Buffer) DecodeMessage(m Message) error { 265 | v, err := b.DecodeRawBytes(false) 266 | if err != nil { 267 | return err 268 | } 269 | return UnmarshalMerge(v, m) 270 | } 271 | 272 | // DecodeGroup consumes a message group from the buffer. 273 | // It assumes that the start group marker has already been consumed and 274 | // consumes all bytes until (and including the end group marker). 275 | // It does not reset m before unmarshaling. 276 | func (b *Buffer) DecodeGroup(m Message) error { 277 | v, n, err := consumeGroup(b.buf[b.idx:]) 278 | if err != nil { 279 | return err 280 | } 281 | b.idx += n 282 | return UnmarshalMerge(v, m) 283 | } 284 | 285 | // consumeGroup parses b until it finds an end group marker, returning 286 | // the raw bytes of the message (excluding the end group marker) and the 287 | // the total length of the message (including the end group marker). 288 | func consumeGroup(b []byte) ([]byte, int, error) { 289 | b0 := b 290 | depth := 1 // assume this follows a start group marker 291 | for { 292 | _, wtyp, tagLen := protowire.ConsumeTag(b) 293 | if tagLen < 0 { 294 | return nil, 0, protowire.ParseError(tagLen) 295 | } 296 | b = b[tagLen:] 297 | 298 | var valLen int 299 | switch wtyp { 300 | case protowire.VarintType: 301 | _, valLen = protowire.ConsumeVarint(b) 302 | case protowire.Fixed32Type: 303 | _, valLen = protowire.ConsumeFixed32(b) 304 | case protowire.Fixed64Type: 305 | _, valLen = protowire.ConsumeFixed64(b) 306 | case protowire.BytesType: 307 | _, valLen = protowire.ConsumeBytes(b) 308 | case protowire.StartGroupType: 309 | depth++ 310 | case protowire.EndGroupType: 311 | depth-- 312 | default: 313 | return nil, 0, errors.New("proto: cannot parse reserved wire type") 314 | } 315 | if valLen < 0 { 316 | return nil, 0, protowire.ParseError(valLen) 317 | } 318 | b = b[valLen:] 319 | 320 | if depth == 0 { 321 | return b0[:len(b0)-len(b)-tagLen], len(b0) - len(b), nil 322 | } 323 | } 324 | } 325 | -------------------------------------------------------------------------------- /proto/defaults.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package proto 6 | 7 | import ( 8 | "google.golang.org/protobuf/reflect/protoreflect" 9 | ) 10 | 11 | // SetDefaults sets unpopulated scalar fields to their default values. 12 | // Fields within a oneof are not set even if they have a default value. 13 | // SetDefaults is recursively called upon any populated message fields. 14 | func SetDefaults(m Message) { 15 | if m != nil { 16 | setDefaults(MessageReflect(m)) 17 | } 18 | } 19 | 20 | func setDefaults(m protoreflect.Message) { 21 | fds := m.Descriptor().Fields() 22 | for i := 0; i < fds.Len(); i++ { 23 | fd := fds.Get(i) 24 | if !m.Has(fd) { 25 | if fd.HasDefault() && fd.ContainingOneof() == nil { 26 | v := fd.Default() 27 | if fd.Kind() == protoreflect.BytesKind { 28 | v = protoreflect.ValueOf(append([]byte(nil), v.Bytes()...)) // copy the default bytes 29 | } 30 | m.Set(fd, v) 31 | } 32 | continue 33 | } 34 | } 35 | 36 | m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { 37 | switch { 38 | // Handle singular message. 39 | case fd.Cardinality() != protoreflect.Repeated: 40 | if fd.Message() != nil { 41 | setDefaults(m.Get(fd).Message()) 42 | } 43 | // Handle list of messages. 44 | case fd.IsList(): 45 | if fd.Message() != nil { 46 | ls := m.Get(fd).List() 47 | for i := 0; i < ls.Len(); i++ { 48 | setDefaults(ls.Get(i).Message()) 49 | } 50 | } 51 | // Handle map of messages. 52 | case fd.IsMap(): 53 | if fd.MapValue().Message() != nil { 54 | ms := m.Get(fd).Map() 55 | ms.Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool { 56 | setDefaults(v.Message()) 57 | return true 58 | }) 59 | } 60 | } 61 | return true 62 | }) 63 | } 64 | -------------------------------------------------------------------------------- /proto/deprecated.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package proto 6 | 7 | import ( 8 | "encoding/json" 9 | "errors" 10 | "fmt" 11 | "strconv" 12 | 13 | protoV2 "google.golang.org/protobuf/proto" 14 | ) 15 | 16 | var ( 17 | // Deprecated: No longer returned. 18 | ErrNil = errors.New("proto: Marshal called with nil") 19 | 20 | // Deprecated: No longer returned. 21 | ErrTooLarge = errors.New("proto: message encodes to over 2 GB") 22 | 23 | // Deprecated: No longer returned. 24 | ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") 25 | ) 26 | 27 | // Deprecated: Do not use. 28 | type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 } 29 | 30 | // Deprecated: Do not use. 31 | func GetStats() Stats { return Stats{} } 32 | 33 | // Deprecated: Do not use. 34 | func MarshalMessageSet(interface{}) ([]byte, error) { 35 | return nil, errors.New("proto: not implemented") 36 | } 37 | 38 | // Deprecated: Do not use. 39 | func UnmarshalMessageSet([]byte, interface{}) error { 40 | return errors.New("proto: not implemented") 41 | } 42 | 43 | // Deprecated: Do not use. 44 | func MarshalMessageSetJSON(interface{}) ([]byte, error) { 45 | return nil, errors.New("proto: not implemented") 46 | } 47 | 48 | // Deprecated: Do not use. 49 | func UnmarshalMessageSetJSON([]byte, interface{}) error { 50 | return errors.New("proto: not implemented") 51 | } 52 | 53 | // Deprecated: Do not use. 54 | func RegisterMessageSetType(Message, int32, string) {} 55 | 56 | // Deprecated: Do not use. 57 | func EnumName(m map[int32]string, v int32) string { 58 | s, ok := m[v] 59 | if ok { 60 | return s 61 | } 62 | return strconv.Itoa(int(v)) 63 | } 64 | 65 | // Deprecated: Do not use. 66 | func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) { 67 | if data[0] == '"' { 68 | // New style: enums are strings. 69 | var repr string 70 | if err := json.Unmarshal(data, &repr); err != nil { 71 | return -1, err 72 | } 73 | val, ok := m[repr] 74 | if !ok { 75 | return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr) 76 | } 77 | return val, nil 78 | } 79 | // Old style: enums are ints. 80 | var val int32 81 | if err := json.Unmarshal(data, &val); err != nil { 82 | return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName) 83 | } 84 | return val, nil 85 | } 86 | 87 | // Deprecated: Do not use; this type existed for intenal-use only. 88 | type InternalMessageInfo struct{} 89 | 90 | // Deprecated: Do not use; this method existed for intenal-use only. 91 | func (*InternalMessageInfo) DiscardUnknown(m Message) { 92 | DiscardUnknown(m) 93 | } 94 | 95 | // Deprecated: Do not use; this method existed for intenal-use only. 96 | func (*InternalMessageInfo) Marshal(b []byte, m Message, deterministic bool) ([]byte, error) { 97 | return protoV2.MarshalOptions{Deterministic: deterministic}.MarshalAppend(b, MessageV2(m)) 98 | } 99 | 100 | // Deprecated: Do not use; this method existed for intenal-use only. 101 | func (*InternalMessageInfo) Merge(dst, src Message) { 102 | protoV2.Merge(MessageV2(dst), MessageV2(src)) 103 | } 104 | 105 | // Deprecated: Do not use; this method existed for intenal-use only. 106 | func (*InternalMessageInfo) Size(m Message) int { 107 | return protoV2.Size(MessageV2(m)) 108 | } 109 | 110 | // Deprecated: Do not use; this method existed for intenal-use only. 111 | func (*InternalMessageInfo) Unmarshal(m Message, b []byte) error { 112 | return protoV2.UnmarshalOptions{Merge: true}.Unmarshal(b, MessageV2(m)) 113 | } 114 | -------------------------------------------------------------------------------- /proto/discard.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package proto 6 | 7 | import ( 8 | "google.golang.org/protobuf/reflect/protoreflect" 9 | ) 10 | 11 | // DiscardUnknown recursively discards all unknown fields from this message 12 | // and all embedded messages. 13 | // 14 | // When unmarshaling a message with unrecognized fields, the tags and values 15 | // of such fields are preserved in the Message. This allows a later call to 16 | // marshal to be able to produce a message that continues to have those 17 | // unrecognized fields. To avoid this, DiscardUnknown is used to 18 | // explicitly clear the unknown fields after unmarshaling. 19 | func DiscardUnknown(m Message) { 20 | if m != nil { 21 | discardUnknown(MessageReflect(m)) 22 | } 23 | } 24 | 25 | func discardUnknown(m protoreflect.Message) { 26 | m.Range(func(fd protoreflect.FieldDescriptor, val protoreflect.Value) bool { 27 | switch { 28 | // Handle singular message. 29 | case fd.Cardinality() != protoreflect.Repeated: 30 | if fd.Message() != nil { 31 | discardUnknown(m.Get(fd).Message()) 32 | } 33 | // Handle list of messages. 34 | case fd.IsList(): 35 | if fd.Message() != nil { 36 | ls := m.Get(fd).List() 37 | for i := 0; i < ls.Len(); i++ { 38 | discardUnknown(ls.Get(i).Message()) 39 | } 40 | } 41 | // Handle map of messages. 42 | case fd.IsMap(): 43 | if fd.MapValue().Message() != nil { 44 | ms := m.Get(fd).Map() 45 | ms.Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool { 46 | discardUnknown(v.Message()) 47 | return true 48 | }) 49 | } 50 | } 51 | return true 52 | }) 53 | 54 | // Discard unknown fields. 55 | if len(m.GetUnknown()) > 0 { 56 | m.SetUnknown(nil) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /proto/discard_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package proto_test 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/golang/protobuf/proto" 11 | "google.golang.org/protobuf/testing/protopack" 12 | 13 | pb2 "github.com/golang/protobuf/internal/testprotos/proto2_proto" 14 | pb3 "github.com/golang/protobuf/internal/testprotos/proto3_proto" 15 | ) 16 | 17 | var rawFields = protopack.Message{ 18 | protopack.Tag{5, protopack.Fixed32Type}, protopack.Uint32(4041331395), 19 | }.Marshal() 20 | 21 | func TestDiscardUnknown(t *testing.T) { 22 | tests := []struct { 23 | desc string 24 | in, want proto.Message 25 | }{{ 26 | desc: "Nil", 27 | in: nil, want: nil, // Should not panic 28 | }, { 29 | desc: "NilPtr", 30 | in: (*pb3.Message)(nil), want: (*pb3.Message)(nil), // Should not panic 31 | }, { 32 | desc: "Nested", 33 | in: &pb3.Message{ 34 | Name: "Aaron", 35 | Nested: &pb3.Nested{Cute: true, XXX_unrecognized: []byte(rawFields)}, 36 | XXX_unrecognized: []byte(rawFields), 37 | }, 38 | want: &pb3.Message{ 39 | Name: "Aaron", 40 | Nested: &pb3.Nested{Cute: true}, 41 | }, 42 | }, { 43 | desc: "Slice", 44 | in: &pb3.Message{ 45 | Name: "Aaron", 46 | Children: []*pb3.Message{ 47 | {Name: "Sarah", XXX_unrecognized: []byte(rawFields)}, 48 | {Name: "Abraham", XXX_unrecognized: []byte(rawFields)}, 49 | }, 50 | XXX_unrecognized: []byte(rawFields), 51 | }, 52 | want: &pb3.Message{ 53 | Name: "Aaron", 54 | Children: []*pb3.Message{ 55 | {Name: "Sarah"}, 56 | {Name: "Abraham"}, 57 | }, 58 | }, 59 | }, { 60 | desc: "OneOf", 61 | in: &pb2.Communique{ 62 | Union: &pb2.Communique_Msg{&pb2.Strings{ 63 | StringField: proto.String("123"), 64 | XXX_unrecognized: []byte(rawFields), 65 | }}, 66 | XXX_unrecognized: []byte(rawFields), 67 | }, 68 | want: &pb2.Communique{ 69 | Union: &pb2.Communique_Msg{&pb2.Strings{StringField: proto.String("123")}}, 70 | }, 71 | }, { 72 | desc: "Map", 73 | in: &pb2.MessageWithMap{MsgMapping: map[int64]*pb2.FloatingPoint{ 74 | 0x4002: &pb2.FloatingPoint{ 75 | Exact: proto.Bool(true), 76 | XXX_unrecognized: []byte(rawFields), 77 | }, 78 | }}, 79 | want: &pb2.MessageWithMap{MsgMapping: map[int64]*pb2.FloatingPoint{ 80 | 0x4002: &pb2.FloatingPoint{Exact: proto.Bool(true)}, 81 | }}, 82 | }, { 83 | desc: "Extension", 84 | in: func() proto.Message { 85 | m := &pb2.MyMessage{ 86 | Count: proto.Int32(42), 87 | Somegroup: &pb2.MyMessage_SomeGroup{ 88 | GroupField: proto.Int32(6), 89 | XXX_unrecognized: []byte(rawFields), 90 | }, 91 | XXX_unrecognized: []byte(rawFields), 92 | } 93 | proto.SetExtension(m, pb2.E_Ext_More, &pb2.Ext{ 94 | Data: proto.String("extension"), 95 | XXX_unrecognized: []byte(rawFields), 96 | }) 97 | return m 98 | }(), 99 | want: func() proto.Message { 100 | m := &pb2.MyMessage{ 101 | Count: proto.Int32(42), 102 | Somegroup: &pb2.MyMessage_SomeGroup{GroupField: proto.Int32(6)}, 103 | } 104 | proto.SetExtension(m, pb2.E_Ext_More, &pb2.Ext{Data: proto.String("extension")}) 105 | return m 106 | }(), 107 | }} 108 | 109 | for _, tt := range tests { 110 | proto.DiscardUnknown(tt.in) 111 | if !proto.Equal(tt.in, tt.want) { 112 | t.Errorf("test %s, expected unknown fields to be discarded\ngot %v\nwant %v", tt.desc, tt.in, tt.want) 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /proto/extensions.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package proto 6 | 7 | import ( 8 | "errors" 9 | "fmt" 10 | "reflect" 11 | 12 | "google.golang.org/protobuf/encoding/protowire" 13 | "google.golang.org/protobuf/proto" 14 | "google.golang.org/protobuf/reflect/protoreflect" 15 | "google.golang.org/protobuf/reflect/protoregistry" 16 | "google.golang.org/protobuf/runtime/protoiface" 17 | "google.golang.org/protobuf/runtime/protoimpl" 18 | ) 19 | 20 | type ( 21 | // ExtensionDesc represents an extension descriptor and 22 | // is used to interact with an extension field in a message. 23 | // 24 | // Variables of this type are generated in code by protoc-gen-go. 25 | ExtensionDesc = protoimpl.ExtensionInfo 26 | 27 | // ExtensionRange represents a range of message extensions. 28 | // Used in code generated by protoc-gen-go. 29 | ExtensionRange = protoiface.ExtensionRangeV1 30 | 31 | // Deprecated: Do not use; this is an internal type. 32 | Extension = protoimpl.ExtensionFieldV1 33 | 34 | // Deprecated: Do not use; this is an internal type. 35 | XXX_InternalExtensions = protoimpl.ExtensionFields 36 | ) 37 | 38 | // ErrMissingExtension reports whether the extension was not present. 39 | var ErrMissingExtension = errors.New("proto: missing extension") 40 | 41 | var errNotExtendable = errors.New("proto: not an extendable proto.Message") 42 | 43 | // HasExtension reports whether the extension field is present in m 44 | // either as an explicitly populated field or as an unknown field. 45 | func HasExtension(m Message, xt *ExtensionDesc) (has bool) { 46 | mr := MessageReflect(m) 47 | if mr == nil || !mr.IsValid() { 48 | return false 49 | } 50 | 51 | // Check whether any populated known field matches the field number. 52 | xtd := xt.TypeDescriptor() 53 | if isValidExtension(mr.Descriptor(), xtd) { 54 | has = mr.Has(xtd) 55 | } else { 56 | mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool { 57 | has = int32(fd.Number()) == xt.Field 58 | return !has 59 | }) 60 | } 61 | 62 | // Check whether any unknown field matches the field number. 63 | for b := mr.GetUnknown(); !has && len(b) > 0; { 64 | num, _, n := protowire.ConsumeField(b) 65 | has = int32(num) == xt.Field 66 | b = b[n:] 67 | } 68 | return has 69 | } 70 | 71 | // ClearExtension removes the extension field from m 72 | // either as an explicitly populated field or as an unknown field. 73 | func ClearExtension(m Message, xt *ExtensionDesc) { 74 | mr := MessageReflect(m) 75 | if mr == nil || !mr.IsValid() { 76 | return 77 | } 78 | 79 | xtd := xt.TypeDescriptor() 80 | if isValidExtension(mr.Descriptor(), xtd) { 81 | mr.Clear(xtd) 82 | } else { 83 | mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool { 84 | if int32(fd.Number()) == xt.Field { 85 | mr.Clear(fd) 86 | return false 87 | } 88 | return true 89 | }) 90 | } 91 | clearUnknown(mr, fieldNum(xt.Field)) 92 | } 93 | 94 | // ClearAllExtensions clears all extensions from m. 95 | // This includes populated fields and unknown fields in the extension range. 96 | func ClearAllExtensions(m Message) { 97 | mr := MessageReflect(m) 98 | if mr == nil || !mr.IsValid() { 99 | return 100 | } 101 | 102 | mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool { 103 | if fd.IsExtension() { 104 | mr.Clear(fd) 105 | } 106 | return true 107 | }) 108 | clearUnknown(mr, mr.Descriptor().ExtensionRanges()) 109 | } 110 | 111 | // GetExtension retrieves a proto2 extended field from m. 112 | // 113 | // If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil), 114 | // then GetExtension parses the encoded field and returns a Go value of the specified type. 115 | // If the field is not present, then the default value is returned (if one is specified), 116 | // otherwise ErrMissingExtension is reported. 117 | // 118 | // If the descriptor is type incomplete (i.e., ExtensionDesc.ExtensionType is nil), 119 | // then GetExtension returns the raw encoded bytes for the extension field. 120 | func GetExtension(m Message, xt *ExtensionDesc) (interface{}, error) { 121 | mr := MessageReflect(m) 122 | if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { 123 | return nil, errNotExtendable 124 | } 125 | 126 | // Retrieve the unknown fields for this extension field. 127 | var bo protoreflect.RawFields 128 | for bi := mr.GetUnknown(); len(bi) > 0; { 129 | num, _, n := protowire.ConsumeField(bi) 130 | if int32(num) == xt.Field { 131 | bo = append(bo, bi[:n]...) 132 | } 133 | bi = bi[n:] 134 | } 135 | 136 | // For type incomplete descriptors, only retrieve the unknown fields. 137 | if xt.ExtensionType == nil { 138 | return []byte(bo), nil 139 | } 140 | 141 | // If the extension field only exists as unknown fields, unmarshal it. 142 | // This is rarely done since proto.Unmarshal eagerly unmarshals extensions. 143 | xtd := xt.TypeDescriptor() 144 | if !isValidExtension(mr.Descriptor(), xtd) { 145 | return nil, fmt.Errorf("proto: bad extended type; %T does not extend %T", xt.ExtendedType, m) 146 | } 147 | if !mr.Has(xtd) && len(bo) > 0 { 148 | m2 := mr.New() 149 | if err := (proto.UnmarshalOptions{ 150 | Resolver: extensionResolver{xt}, 151 | }.Unmarshal(bo, m2.Interface())); err != nil { 152 | return nil, err 153 | } 154 | if m2.Has(xtd) { 155 | mr.Set(xtd, m2.Get(xtd)) 156 | clearUnknown(mr, fieldNum(xt.Field)) 157 | } 158 | } 159 | 160 | // Check whether the message has the extension field set or a default. 161 | var pv protoreflect.Value 162 | switch { 163 | case mr.Has(xtd): 164 | pv = mr.Get(xtd) 165 | case xtd.HasDefault(): 166 | pv = xtd.Default() 167 | default: 168 | return nil, ErrMissingExtension 169 | } 170 | 171 | v := xt.InterfaceOf(pv) 172 | rv := reflect.ValueOf(v) 173 | if isScalarKind(rv.Kind()) { 174 | rv2 := reflect.New(rv.Type()) 175 | rv2.Elem().Set(rv) 176 | v = rv2.Interface() 177 | } 178 | return v, nil 179 | } 180 | 181 | // extensionResolver is a custom extension resolver that stores a single 182 | // extension type that takes precedence over the global registry. 183 | type extensionResolver struct{ xt protoreflect.ExtensionType } 184 | 185 | func (r extensionResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) { 186 | if xtd := r.xt.TypeDescriptor(); xtd.FullName() == field { 187 | return r.xt, nil 188 | } 189 | return protoregistry.GlobalTypes.FindExtensionByName(field) 190 | } 191 | 192 | func (r extensionResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) { 193 | if xtd := r.xt.TypeDescriptor(); xtd.ContainingMessage().FullName() == message && xtd.Number() == field { 194 | return r.xt, nil 195 | } 196 | return protoregistry.GlobalTypes.FindExtensionByNumber(message, field) 197 | } 198 | 199 | // GetExtensions returns a list of the extensions values present in m, 200 | // corresponding with the provided list of extension descriptors, xts. 201 | // If an extension is missing in m, the corresponding value is nil. 202 | func GetExtensions(m Message, xts []*ExtensionDesc) ([]interface{}, error) { 203 | mr := MessageReflect(m) 204 | if mr == nil || !mr.IsValid() { 205 | return nil, errNotExtendable 206 | } 207 | 208 | vs := make([]interface{}, len(xts)) 209 | for i, xt := range xts { 210 | v, err := GetExtension(m, xt) 211 | if err != nil { 212 | if err == ErrMissingExtension { 213 | continue 214 | } 215 | return vs, err 216 | } 217 | vs[i] = v 218 | } 219 | return vs, nil 220 | } 221 | 222 | // SetExtension sets an extension field in m to the provided value. 223 | func SetExtension(m Message, xt *ExtensionDesc, v interface{}) error { 224 | mr := MessageReflect(m) 225 | if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { 226 | return errNotExtendable 227 | } 228 | 229 | rv := reflect.ValueOf(v) 230 | if reflect.TypeOf(v) != reflect.TypeOf(xt.ExtensionType) { 231 | return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", v, xt.ExtensionType) 232 | } 233 | if rv.Kind() == reflect.Ptr { 234 | if rv.IsNil() { 235 | return fmt.Errorf("proto: SetExtension called with nil value of type %T", v) 236 | } 237 | if isScalarKind(rv.Elem().Kind()) { 238 | v = rv.Elem().Interface() 239 | } 240 | } 241 | 242 | xtd := xt.TypeDescriptor() 243 | if !isValidExtension(mr.Descriptor(), xtd) { 244 | return fmt.Errorf("proto: bad extended type; %T does not extend %T", xt.ExtendedType, m) 245 | } 246 | mr.Set(xtd, xt.ValueOf(v)) 247 | clearUnknown(mr, fieldNum(xt.Field)) 248 | return nil 249 | } 250 | 251 | // SetRawExtension inserts b into the unknown fields of m. 252 | // 253 | // Deprecated: Use Message.ProtoReflect.SetUnknown instead. 254 | func SetRawExtension(m Message, fnum int32, b []byte) { 255 | mr := MessageReflect(m) 256 | if mr == nil || !mr.IsValid() { 257 | return 258 | } 259 | 260 | // Verify that the raw field is valid. 261 | for b0 := b; len(b0) > 0; { 262 | num, _, n := protowire.ConsumeField(b0) 263 | if int32(num) != fnum { 264 | panic(fmt.Sprintf("mismatching field number: got %d, want %d", num, fnum)) 265 | } 266 | b0 = b0[n:] 267 | } 268 | 269 | ClearExtension(m, &ExtensionDesc{Field: fnum}) 270 | mr.SetUnknown(append(mr.GetUnknown(), b...)) 271 | } 272 | 273 | // ExtensionDescs returns a list of extension descriptors found in m, 274 | // containing descriptors for both populated extension fields in m and 275 | // also unknown fields of m that are in the extension range. 276 | // For the later case, an type incomplete descriptor is provided where only 277 | // the ExtensionDesc.Field field is populated. 278 | // The order of the extension descriptors is undefined. 279 | func ExtensionDescs(m Message) ([]*ExtensionDesc, error) { 280 | mr := MessageReflect(m) 281 | if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { 282 | return nil, errNotExtendable 283 | } 284 | 285 | // Collect a set of known extension descriptors. 286 | extDescs := make(map[protoreflect.FieldNumber]*ExtensionDesc) 287 | mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { 288 | if fd.IsExtension() { 289 | xt := fd.(protoreflect.ExtensionTypeDescriptor) 290 | if xd, ok := xt.Type().(*ExtensionDesc); ok { 291 | extDescs[fd.Number()] = xd 292 | } 293 | } 294 | return true 295 | }) 296 | 297 | // Collect a set of unknown extension descriptors. 298 | extRanges := mr.Descriptor().ExtensionRanges() 299 | for b := mr.GetUnknown(); len(b) > 0; { 300 | num, _, n := protowire.ConsumeField(b) 301 | if extRanges.Has(num) && extDescs[num] == nil { 302 | extDescs[num] = nil 303 | } 304 | b = b[n:] 305 | } 306 | 307 | // Transpose the set of descriptors into a list. 308 | var xts []*ExtensionDesc 309 | for num, xt := range extDescs { 310 | if xt == nil { 311 | xt = &ExtensionDesc{Field: int32(num)} 312 | } 313 | xts = append(xts, xt) 314 | } 315 | return xts, nil 316 | } 317 | 318 | // isValidExtension reports whether xtd is a valid extension descriptor for md. 319 | func isValidExtension(md protoreflect.MessageDescriptor, xtd protoreflect.ExtensionTypeDescriptor) bool { 320 | return xtd.ContainingMessage() == md && md.ExtensionRanges().Has(xtd.Number()) 321 | } 322 | 323 | // isScalarKind reports whether k is a protobuf scalar kind (except bytes). 324 | // This function exists for historical reasons since the representation of 325 | // scalars differs between v1 and v2, where v1 uses *T and v2 uses T. 326 | func isScalarKind(k reflect.Kind) bool { 327 | switch k { 328 | case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String: 329 | return true 330 | default: 331 | return false 332 | } 333 | } 334 | 335 | // clearUnknown removes unknown fields from m where remover.Has reports true. 336 | func clearUnknown(m protoreflect.Message, remover interface { 337 | Has(protoreflect.FieldNumber) bool 338 | }) { 339 | var bo protoreflect.RawFields 340 | for bi := m.GetUnknown(); len(bi) > 0; { 341 | num, _, n := protowire.ConsumeField(bi) 342 | if !remover.Has(num) { 343 | bo = append(bo, bi[:n]...) 344 | } 345 | bi = bi[n:] 346 | } 347 | if bi := m.GetUnknown(); len(bi) != len(bo) { 348 | m.SetUnknown(bo) 349 | } 350 | } 351 | 352 | type fieldNum protoreflect.FieldNumber 353 | 354 | func (n1 fieldNum) Has(n2 protoreflect.FieldNumber) bool { 355 | return protoreflect.FieldNumber(n1) == n2 356 | } 357 | -------------------------------------------------------------------------------- /proto/properties.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package proto 6 | 7 | import ( 8 | "fmt" 9 | "reflect" 10 | "strconv" 11 | "strings" 12 | "sync" 13 | 14 | "google.golang.org/protobuf/reflect/protoreflect" 15 | "google.golang.org/protobuf/runtime/protoimpl" 16 | ) 17 | 18 | // StructProperties represents protocol buffer type information for a 19 | // generated protobuf message in the open-struct API. 20 | // 21 | // Deprecated: Do not use. 22 | type StructProperties struct { 23 | // Prop are the properties for each field. 24 | // 25 | // Fields belonging to a oneof are stored in OneofTypes instead, with a 26 | // single Properties representing the parent oneof held here. 27 | // 28 | // The order of Prop matches the order of fields in the Go struct. 29 | // Struct fields that are not related to protobufs have a "XXX_" prefix 30 | // in the Properties.Name and must be ignored by the user. 31 | Prop []*Properties 32 | 33 | // OneofTypes contains information about the oneof fields in this message. 34 | // It is keyed by the protobuf field name. 35 | OneofTypes map[string]*OneofProperties 36 | } 37 | 38 | // Properties represents the type information for a protobuf message field. 39 | // 40 | // Deprecated: Do not use. 41 | type Properties struct { 42 | // Name is a placeholder name with little meaningful semantic value. 43 | // If the name has an "XXX_" prefix, the entire Properties must be ignored. 44 | Name string 45 | // OrigName is the protobuf field name or oneof name. 46 | OrigName string 47 | // JSONName is the JSON name for the protobuf field. 48 | JSONName string 49 | // Enum is a placeholder name for enums. 50 | // For historical reasons, this is neither the Go name for the enum, 51 | // nor the protobuf name for the enum. 52 | Enum string // Deprecated: Do not use. 53 | // Weak contains the full name of the weakly referenced message. 54 | Weak string 55 | // Wire is a string representation of the wire type. 56 | Wire string 57 | // WireType is the protobuf wire type for the field. 58 | WireType int 59 | // Tag is the protobuf field number. 60 | Tag int 61 | // Required reports whether this is a required field. 62 | Required bool 63 | // Optional reports whether this is a optional field. 64 | Optional bool 65 | // Repeated reports whether this is a repeated field. 66 | Repeated bool 67 | // Packed reports whether this is a packed repeated field of scalars. 68 | Packed bool 69 | // Proto3 reports whether this field operates under the proto3 syntax. 70 | Proto3 bool 71 | // Oneof reports whether this field belongs within a oneof. 72 | Oneof bool 73 | 74 | // Default is the default value in string form. 75 | Default string 76 | // HasDefault reports whether the field has a default value. 77 | HasDefault bool 78 | 79 | // MapKeyProp is the properties for the key field for a map field. 80 | MapKeyProp *Properties 81 | // MapValProp is the properties for the value field for a map field. 82 | MapValProp *Properties 83 | } 84 | 85 | // OneofProperties represents the type information for a protobuf oneof. 86 | // 87 | // Deprecated: Do not use. 88 | type OneofProperties struct { 89 | // Type is a pointer to the generated wrapper type for the field value. 90 | // This is nil for messages that are not in the open-struct API. 91 | Type reflect.Type 92 | // Field is the index into StructProperties.Prop for the containing oneof. 93 | Field int 94 | // Prop is the properties for the field. 95 | Prop *Properties 96 | } 97 | 98 | // String formats the properties in the protobuf struct field tag style. 99 | func (p *Properties) String() string { 100 | s := p.Wire 101 | s += "," + strconv.Itoa(p.Tag) 102 | if p.Required { 103 | s += ",req" 104 | } 105 | if p.Optional { 106 | s += ",opt" 107 | } 108 | if p.Repeated { 109 | s += ",rep" 110 | } 111 | if p.Packed { 112 | s += ",packed" 113 | } 114 | s += ",name=" + p.OrigName 115 | if p.JSONName != "" { 116 | s += ",json=" + p.JSONName 117 | } 118 | if len(p.Enum) > 0 { 119 | s += ",enum=" + p.Enum 120 | } 121 | if len(p.Weak) > 0 { 122 | s += ",weak=" + p.Weak 123 | } 124 | if p.Proto3 { 125 | s += ",proto3" 126 | } 127 | if p.Oneof { 128 | s += ",oneof" 129 | } 130 | if p.HasDefault { 131 | s += ",def=" + p.Default 132 | } 133 | return s 134 | } 135 | 136 | // Parse populates p by parsing a string in the protobuf struct field tag style. 137 | func (p *Properties) Parse(tag string) { 138 | // For example: "bytes,49,opt,name=foo,def=hello!" 139 | for len(tag) > 0 { 140 | i := strings.IndexByte(tag, ',') 141 | if i < 0 { 142 | i = len(tag) 143 | } 144 | switch s := tag[:i]; { 145 | case strings.HasPrefix(s, "name="): 146 | p.OrigName = s[len("name="):] 147 | case strings.HasPrefix(s, "json="): 148 | p.JSONName = s[len("json="):] 149 | case strings.HasPrefix(s, "enum="): 150 | p.Enum = s[len("enum="):] 151 | case strings.HasPrefix(s, "weak="): 152 | p.Weak = s[len("weak="):] 153 | case strings.Trim(s, "0123456789") == "": 154 | n, _ := strconv.ParseUint(s, 10, 32) 155 | p.Tag = int(n) 156 | case s == "opt": 157 | p.Optional = true 158 | case s == "req": 159 | p.Required = true 160 | case s == "rep": 161 | p.Repeated = true 162 | case s == "varint" || s == "zigzag32" || s == "zigzag64": 163 | p.Wire = s 164 | p.WireType = WireVarint 165 | case s == "fixed32": 166 | p.Wire = s 167 | p.WireType = WireFixed32 168 | case s == "fixed64": 169 | p.Wire = s 170 | p.WireType = WireFixed64 171 | case s == "bytes": 172 | p.Wire = s 173 | p.WireType = WireBytes 174 | case s == "group": 175 | p.Wire = s 176 | p.WireType = WireStartGroup 177 | case s == "packed": 178 | p.Packed = true 179 | case s == "proto3": 180 | p.Proto3 = true 181 | case s == "oneof": 182 | p.Oneof = true 183 | case strings.HasPrefix(s, "def="): 184 | // The default tag is special in that everything afterwards is the 185 | // default regardless of the presence of commas. 186 | p.HasDefault = true 187 | p.Default, i = tag[len("def="):], len(tag) 188 | } 189 | tag = strings.TrimPrefix(tag[i:], ",") 190 | } 191 | } 192 | 193 | // Init populates the properties from a protocol buffer struct tag. 194 | // 195 | // Deprecated: Do not use. 196 | func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { 197 | p.Name = name 198 | p.OrigName = name 199 | if tag == "" { 200 | return 201 | } 202 | p.Parse(tag) 203 | 204 | if typ != nil && typ.Kind() == reflect.Map { 205 | p.MapKeyProp = new(Properties) 206 | p.MapKeyProp.Init(nil, "Key", f.Tag.Get("protobuf_key"), nil) 207 | p.MapValProp = new(Properties) 208 | p.MapValProp.Init(nil, "Value", f.Tag.Get("protobuf_val"), nil) 209 | } 210 | } 211 | 212 | var propertiesCache sync.Map // map[reflect.Type]*StructProperties 213 | 214 | // GetProperties returns the list of properties for the type represented by t, 215 | // which must be a generated protocol buffer message in the open-struct API, 216 | // where protobuf message fields are represented by exported Go struct fields. 217 | // 218 | // Deprecated: Use protobuf reflection instead. 219 | func GetProperties(t reflect.Type) *StructProperties { 220 | if p, ok := propertiesCache.Load(t); ok { 221 | return p.(*StructProperties) 222 | } 223 | p, _ := propertiesCache.LoadOrStore(t, newProperties(t)) 224 | return p.(*StructProperties) 225 | } 226 | 227 | func newProperties(t reflect.Type) *StructProperties { 228 | if t.Kind() != reflect.Struct { 229 | panic(fmt.Sprintf("%v is not a generated message in the open-struct API", t)) 230 | } 231 | 232 | var hasOneof bool 233 | prop := new(StructProperties) 234 | 235 | // Construct a list of properties for each field in the struct. 236 | for i := 0; i < t.NumField(); i++ { 237 | p := new(Properties) 238 | f := t.Field(i) 239 | tagField := f.Tag.Get("protobuf") 240 | p.Init(f.Type, f.Name, tagField, &f) 241 | 242 | tagOneof := f.Tag.Get("protobuf_oneof") 243 | if tagOneof != "" { 244 | hasOneof = true 245 | p.OrigName = tagOneof 246 | } 247 | 248 | // Rename unrelated struct fields with the "XXX_" prefix since so much 249 | // user code simply checks for this to exclude special fields. 250 | if tagField == "" && tagOneof == "" && !strings.HasPrefix(p.Name, "XXX_") { 251 | p.Name = "XXX_" + p.Name 252 | p.OrigName = "XXX_" + p.OrigName 253 | } else if p.Weak != "" { 254 | p.Name = p.OrigName // avoid possible "XXX_" prefix on weak field 255 | } 256 | 257 | prop.Prop = append(prop.Prop, p) 258 | } 259 | 260 | // Construct a mapping of oneof field names to properties. 261 | if hasOneof { 262 | var oneofWrappers []interface{} 263 | if fn, ok := reflect.PtrTo(t).MethodByName("XXX_OneofFuncs"); ok { 264 | oneofWrappers = fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[3].Interface().([]interface{}) 265 | } 266 | if fn, ok := reflect.PtrTo(t).MethodByName("XXX_OneofWrappers"); ok { 267 | oneofWrappers = fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0].Interface().([]interface{}) 268 | } 269 | if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(protoreflect.ProtoMessage); ok { 270 | if m, ok := m.ProtoReflect().(interface{ ProtoMessageInfo() *protoimpl.MessageInfo }); ok { 271 | oneofWrappers = m.ProtoMessageInfo().OneofWrappers 272 | } 273 | } 274 | 275 | prop.OneofTypes = make(map[string]*OneofProperties) 276 | for _, wrapper := range oneofWrappers { 277 | p := &OneofProperties{ 278 | Type: reflect.ValueOf(wrapper).Type(), // *T 279 | Prop: new(Properties), 280 | } 281 | f := p.Type.Elem().Field(0) 282 | p.Prop.Name = f.Name 283 | p.Prop.Parse(f.Tag.Get("protobuf")) 284 | 285 | // Determine the struct field that contains this oneof. 286 | // Each wrapper is assignable to exactly one parent field. 287 | var foundOneof bool 288 | for i := 0; i < t.NumField() && !foundOneof; i++ { 289 | if p.Type.AssignableTo(t.Field(i).Type) { 290 | p.Field = i 291 | foundOneof = true 292 | } 293 | } 294 | if !foundOneof { 295 | panic(fmt.Sprintf("%v is not a generated message in the open-struct API", t)) 296 | } 297 | prop.OneofTypes[p.Prop.OrigName] = p 298 | } 299 | } 300 | 301 | return prop 302 | } 303 | 304 | func (sp *StructProperties) Len() int { return len(sp.Prop) } 305 | func (sp *StructProperties) Less(i, j int) bool { return false } 306 | func (sp *StructProperties) Swap(i, j int) { return } 307 | -------------------------------------------------------------------------------- /proto/proto.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package proto provides functionality for handling protocol buffer messages. 6 | // In particular, it provides marshaling and unmarshaling between a protobuf 7 | // message and the binary wire format. 8 | // 9 | // See https://developers.google.com/protocol-buffers/docs/gotutorial for 10 | // more information. 11 | // 12 | // Deprecated: Use the "google.golang.org/protobuf/proto" package instead. 13 | package proto 14 | 15 | import ( 16 | protoV2 "google.golang.org/protobuf/proto" 17 | "google.golang.org/protobuf/reflect/protoreflect" 18 | "google.golang.org/protobuf/runtime/protoiface" 19 | "google.golang.org/protobuf/runtime/protoimpl" 20 | ) 21 | 22 | const ( 23 | ProtoPackageIsVersion1 = true 24 | ProtoPackageIsVersion2 = true 25 | ProtoPackageIsVersion3 = true 26 | ProtoPackageIsVersion4 = true 27 | ) 28 | 29 | // GeneratedEnum is any enum type generated by protoc-gen-go 30 | // which is a named int32 kind. 31 | // This type exists for documentation purposes. 32 | type GeneratedEnum interface{} 33 | 34 | // GeneratedMessage is any message type generated by protoc-gen-go 35 | // which is a pointer to a named struct kind. 36 | // This type exists for documentation purposes. 37 | type GeneratedMessage interface{} 38 | 39 | // Message is a protocol buffer message. 40 | // 41 | // This is the v1 version of the message interface and is marginally better 42 | // than an empty interface as it lacks any method to programatically interact 43 | // with the contents of the message. 44 | // 45 | // A v2 message is declared in "google.golang.org/protobuf/proto".Message and 46 | // exposes protobuf reflection as a first-class feature of the interface. 47 | // 48 | // To convert a v1 message to a v2 message, use the MessageV2 function. 49 | // To convert a v2 message to a v1 message, use the MessageV1 function. 50 | type Message = protoiface.MessageV1 51 | 52 | // MessageV1 converts either a v1 or v2 message to a v1 message. 53 | // It returns nil if m is nil. 54 | func MessageV1(m GeneratedMessage) protoiface.MessageV1 { 55 | return protoimpl.X.ProtoMessageV1Of(m) 56 | } 57 | 58 | // MessageV2 converts either a v1 or v2 message to a v2 message. 59 | // It returns nil if m is nil. 60 | func MessageV2(m GeneratedMessage) protoV2.Message { 61 | return protoimpl.X.ProtoMessageV2Of(m) 62 | } 63 | 64 | // MessageReflect returns a reflective view for a message. 65 | // It returns nil if m is nil. 66 | func MessageReflect(m Message) protoreflect.Message { 67 | return protoimpl.X.MessageOf(m) 68 | } 69 | 70 | // Marshaler is implemented by messages that can marshal themselves. 71 | // This interface is used by the following functions: Size, Marshal, 72 | // Buffer.Marshal, and Buffer.EncodeMessage. 73 | // 74 | // Deprecated: Do not implement. 75 | type Marshaler interface { 76 | // Marshal formats the encoded bytes of the message. 77 | // It should be deterministic and emit valid protobuf wire data. 78 | // The caller takes ownership of the returned buffer. 79 | Marshal() ([]byte, error) 80 | } 81 | 82 | // Unmarshaler is implemented by messages that can unmarshal themselves. 83 | // This interface is used by the following functions: Unmarshal, UnmarshalMerge, 84 | // Buffer.Unmarshal, Buffer.DecodeMessage, and Buffer.DecodeGroup. 85 | // 86 | // Deprecated: Do not implement. 87 | type Unmarshaler interface { 88 | // Unmarshal parses the encoded bytes of the protobuf wire input. 89 | // The provided buffer is only valid for during method call. 90 | // It should not reset the receiver message. 91 | Unmarshal([]byte) error 92 | } 93 | 94 | // Merger is implemented by messages that can merge themselves. 95 | // This interface is used by the following functions: Clone and Merge. 96 | // 97 | // Deprecated: Do not implement. 98 | type Merger interface { 99 | // Merge merges the contents of src into the receiver message. 100 | // It clones all data structures in src such that it aliases no mutable 101 | // memory referenced by src. 102 | Merge(src Message) 103 | } 104 | 105 | // RequiredNotSetError is an error type returned when 106 | // marshaling or unmarshaling a message with missing required fields. 107 | type RequiredNotSetError struct { 108 | err error 109 | } 110 | 111 | func (e *RequiredNotSetError) Error() string { 112 | if e.err != nil { 113 | return e.err.Error() 114 | } 115 | return "proto: required field not set" 116 | } 117 | func (e *RequiredNotSetError) RequiredNotSet() bool { 118 | return true 119 | } 120 | 121 | func checkRequiredNotSet(m protoV2.Message) error { 122 | if err := protoV2.CheckInitialized(m); err != nil { 123 | return &RequiredNotSetError{err: err} 124 | } 125 | return nil 126 | } 127 | 128 | // Clone returns a deep copy of src. 129 | func Clone(src Message) Message { 130 | return MessageV1(protoV2.Clone(MessageV2(src))) 131 | } 132 | 133 | // Merge merges src into dst, which must be messages of the same type. 134 | // 135 | // Populated scalar fields in src are copied to dst, while populated 136 | // singular messages in src are merged into dst by recursively calling Merge. 137 | // The elements of every list field in src is appended to the corresponded 138 | // list fields in dst. The entries of every map field in src is copied into 139 | // the corresponding map field in dst, possibly replacing existing entries. 140 | // The unknown fields of src are appended to the unknown fields of dst. 141 | func Merge(dst, src Message) { 142 | protoV2.Merge(MessageV2(dst), MessageV2(src)) 143 | } 144 | 145 | // Equal reports whether two messages are equal. 146 | // If two messages marshal to the same bytes under deterministic serialization, 147 | // then Equal is guaranteed to report true. 148 | // 149 | // Two messages are equal if they are the same protobuf message type, 150 | // have the same set of populated known and extension field values, 151 | // and the same set of unknown fields values. 152 | // 153 | // Scalar values are compared with the equivalent of the == operator in Go, 154 | // except bytes values which are compared using bytes.Equal and 155 | // floating point values which specially treat NaNs as equal. 156 | // Message values are compared by recursively calling Equal. 157 | // Lists are equal if each element value is also equal. 158 | // Maps are equal if they have the same set of keys, where the pair of values 159 | // for each key is also equal. 160 | func Equal(x, y Message) bool { 161 | return protoV2.Equal(MessageV2(x), MessageV2(y)) 162 | } 163 | 164 | func isMessageSet(md protoreflect.MessageDescriptor) bool { 165 | ms, ok := md.(interface{ IsMessageSet() bool }) 166 | return ok && ms.IsMessageSet() 167 | } 168 | -------------------------------------------------------------------------------- /proto/proto_clone_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package proto_test 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/golang/protobuf/proto" 11 | 12 | pb2 "github.com/golang/protobuf/internal/testprotos/proto2_proto" 13 | pb3 "github.com/golang/protobuf/internal/testprotos/proto3_proto" 14 | ) 15 | 16 | var cloneTestMessage = &pb2.MyMessage{ 17 | Count: proto.Int32(42), 18 | Name: proto.String("Dave"), 19 | Pet: []string{"bunny", "kitty", "horsey"}, 20 | Inner: &pb2.InnerMessage{ 21 | Host: proto.String("niles"), 22 | Port: proto.Int32(9099), 23 | Connected: proto.Bool(true), 24 | }, 25 | Others: []*pb2.OtherMessage{ 26 | { 27 | Value: []byte("some bytes"), 28 | }, 29 | }, 30 | Somegroup: &pb2.MyMessage_SomeGroup{ 31 | GroupField: proto.Int32(6), 32 | }, 33 | RepBytes: [][]byte{[]byte("sham"), []byte("wow")}, 34 | } 35 | 36 | func init() { 37 | ext := &pb2.Ext{ 38 | Data: proto.String("extension"), 39 | } 40 | if err := proto.SetExtension(cloneTestMessage, pb2.E_Ext_More, ext); err != nil { 41 | panic("SetExtension: " + err.Error()) 42 | } 43 | if err := proto.SetExtension(cloneTestMessage, pb2.E_Ext_Text, proto.String("hello")); err != nil { 44 | panic("SetExtension: " + err.Error()) 45 | } 46 | if err := proto.SetExtension(cloneTestMessage, pb2.E_Greeting, []string{"one", "two"}); err != nil { 47 | panic("SetExtension: " + err.Error()) 48 | } 49 | } 50 | 51 | func TestClone(t *testing.T) { 52 | // Create a clone using a marshal/unmarshal roundtrip. 53 | vanilla := new(pb2.MyMessage) 54 | b, err := proto.Marshal(cloneTestMessage) 55 | if err != nil { 56 | t.Errorf("unexpected Marshal error: %v", err) 57 | } 58 | if err := proto.Unmarshal(b, vanilla); err != nil { 59 | t.Errorf("unexpected Unarshal error: %v", err) 60 | } 61 | 62 | // Create a clone using Clone and verify that it is equal to the original. 63 | m := proto.Clone(cloneTestMessage).(*pb2.MyMessage) 64 | if !proto.Equal(m, cloneTestMessage) { 65 | t.Fatalf("Clone(%v) = %v", cloneTestMessage, m) 66 | } 67 | 68 | // Mutate the clone, which should not affect the original. 69 | x1, err := proto.GetExtension(m, pb2.E_Ext_More) 70 | if err != nil { 71 | t.Errorf("unexpected GetExtension(%v) error: %v", pb2.E_Ext_More.Name, err) 72 | } 73 | x2, err := proto.GetExtension(m, pb2.E_Ext_Text) 74 | if err != nil { 75 | t.Errorf("unexpected GetExtension(%v) error: %v", pb2.E_Ext_Text.Name, err) 76 | } 77 | x3, err := proto.GetExtension(m, pb2.E_Greeting) 78 | if err != nil { 79 | t.Errorf("unexpected GetExtension(%v) error: %v", pb2.E_Greeting.Name, err) 80 | } 81 | *m.Inner.Port++ 82 | *(x1.(*pb2.Ext)).Data = "blah blah" 83 | *(x2.(*string)) = "goodbye" 84 | x3.([]string)[0] = "zero" 85 | if !proto.Equal(cloneTestMessage, vanilla) { 86 | t.Fatalf("mutation on original detected:\ngot %v\nwant %v", cloneTestMessage, vanilla) 87 | } 88 | } 89 | 90 | func TestCloneNil(t *testing.T) { 91 | var m *pb2.MyMessage 92 | if c := proto.Clone(m); !proto.Equal(m, c) { 93 | t.Errorf("Clone(%v) = %v", m, c) 94 | } 95 | } 96 | 97 | var mergeTests = []struct { 98 | src, dst, want proto.Message 99 | }{ 100 | { 101 | src: &pb2.MyMessage{ 102 | Count: proto.Int32(42), 103 | }, 104 | dst: &pb2.MyMessage{ 105 | Name: proto.String("Dave"), 106 | }, 107 | want: &pb2.MyMessage{ 108 | Count: proto.Int32(42), 109 | Name: proto.String("Dave"), 110 | }, 111 | }, 112 | { 113 | src: &pb2.MyMessage{ 114 | Inner: &pb2.InnerMessage{ 115 | Host: proto.String("hey"), 116 | Connected: proto.Bool(true), 117 | }, 118 | Pet: []string{"horsey"}, 119 | Others: []*pb2.OtherMessage{ 120 | { 121 | Value: []byte("some bytes"), 122 | }, 123 | }, 124 | }, 125 | dst: &pb2.MyMessage{ 126 | Inner: &pb2.InnerMessage{ 127 | Host: proto.String("niles"), 128 | Port: proto.Int32(9099), 129 | }, 130 | Pet: []string{"bunny", "kitty"}, 131 | Others: []*pb2.OtherMessage{ 132 | { 133 | Key: proto.Int64(31415926535), 134 | }, 135 | { 136 | // Explicitly test a src=nil field 137 | Inner: nil, 138 | }, 139 | }, 140 | }, 141 | want: &pb2.MyMessage{ 142 | Inner: &pb2.InnerMessage{ 143 | Host: proto.String("hey"), 144 | Connected: proto.Bool(true), 145 | Port: proto.Int32(9099), 146 | }, 147 | Pet: []string{"bunny", "kitty", "horsey"}, 148 | Others: []*pb2.OtherMessage{ 149 | { 150 | Key: proto.Int64(31415926535), 151 | }, 152 | {}, 153 | { 154 | Value: []byte("some bytes"), 155 | }, 156 | }, 157 | }, 158 | }, 159 | { 160 | src: &pb2.MyMessage{ 161 | RepBytes: [][]byte{[]byte("wow")}, 162 | }, 163 | dst: &pb2.MyMessage{ 164 | Somegroup: &pb2.MyMessage_SomeGroup{ 165 | GroupField: proto.Int32(6), 166 | }, 167 | RepBytes: [][]byte{[]byte("sham")}, 168 | }, 169 | want: &pb2.MyMessage{ 170 | Somegroup: &pb2.MyMessage_SomeGroup{ 171 | GroupField: proto.Int32(6), 172 | }, 173 | RepBytes: [][]byte{[]byte("sham"), []byte("wow")}, 174 | }, 175 | }, 176 | // Check that a scalar bytes field replaces rather than appends. 177 | { 178 | src: &pb2.OtherMessage{Value: []byte("foo")}, 179 | dst: &pb2.OtherMessage{Value: []byte("bar")}, 180 | want: &pb2.OtherMessage{Value: []byte("foo")}, 181 | }, 182 | { 183 | src: &pb2.MessageWithMap{ 184 | NameMapping: map[int32]string{6: "Nigel"}, 185 | MsgMapping: map[int64]*pb2.FloatingPoint{ 186 | 0x4001: &pb2.FloatingPoint{F: proto.Float64(2.0)}, 187 | 0x4002: &pb2.FloatingPoint{ 188 | F: proto.Float64(2.0), 189 | }, 190 | }, 191 | ByteMapping: map[bool][]byte{true: []byte("wowsa")}, 192 | }, 193 | dst: &pb2.MessageWithMap{ 194 | NameMapping: map[int32]string{ 195 | 6: "Bruce", // should be overwritten 196 | 7: "Andrew", 197 | }, 198 | MsgMapping: map[int64]*pb2.FloatingPoint{ 199 | 0x4002: &pb2.FloatingPoint{ 200 | F: proto.Float64(3.0), 201 | Exact: proto.Bool(true), 202 | }, // the entire message should be overwritten 203 | }, 204 | }, 205 | want: &pb2.MessageWithMap{ 206 | NameMapping: map[int32]string{ 207 | 6: "Nigel", 208 | 7: "Andrew", 209 | }, 210 | MsgMapping: map[int64]*pb2.FloatingPoint{ 211 | 0x4001: &pb2.FloatingPoint{F: proto.Float64(2.0)}, 212 | 0x4002: &pb2.FloatingPoint{ 213 | F: proto.Float64(2.0), 214 | }, 215 | }, 216 | ByteMapping: map[bool][]byte{true: []byte("wowsa")}, 217 | }, 218 | }, 219 | // proto3 shouldn't merge zero values, 220 | // in the same way that proto2 shouldn't merge nils. 221 | { 222 | src: &pb3.Message{ 223 | Name: "Aaron", 224 | Data: []byte(""), // zero value, but not nil 225 | }, 226 | dst: &pb3.Message{ 227 | HeightInCm: 176, 228 | Data: []byte("texas!"), 229 | }, 230 | want: &pb3.Message{ 231 | Name: "Aaron", 232 | HeightInCm: 176, 233 | Data: []byte("texas!"), 234 | }, 235 | }, 236 | { // Oneof fields should merge by assignment. 237 | src: &pb2.Communique{Union: &pb2.Communique_Number{41}}, 238 | dst: &pb2.Communique{Union: &pb2.Communique_Name{"Bobby Tables"}}, 239 | want: &pb2.Communique{Union: &pb2.Communique_Number{41}}, 240 | }, 241 | { // Oneof nil is the same as not set. 242 | src: &pb2.Communique{}, 243 | dst: &pb2.Communique{Union: &pb2.Communique_Name{"Bobby Tables"}}, 244 | want: &pb2.Communique{Union: &pb2.Communique_Name{"Bobby Tables"}}, 245 | }, 246 | { 247 | src: &pb2.Communique{Union: &pb2.Communique_Number{1337}}, 248 | dst: &pb2.Communique{}, 249 | want: &pb2.Communique{Union: &pb2.Communique_Number{1337}}, 250 | }, 251 | { 252 | src: &pb2.Communique{Union: &pb2.Communique_Col{pb2.MyMessage_RED}}, 253 | dst: &pb2.Communique{}, 254 | want: &pb2.Communique{Union: &pb2.Communique_Col{pb2.MyMessage_RED}}, 255 | }, 256 | { 257 | src: &pb2.Communique{Union: &pb2.Communique_Data{[]byte("hello")}}, 258 | dst: &pb2.Communique{}, 259 | want: &pb2.Communique{Union: &pb2.Communique_Data{[]byte("hello")}}, 260 | }, 261 | { 262 | src: &pb2.Communique{Union: &pb2.Communique_Msg{&pb2.Strings{BytesField: []byte{1, 2, 3}}}}, 263 | dst: &pb2.Communique{}, 264 | want: &pb2.Communique{Union: &pb2.Communique_Msg{&pb2.Strings{BytesField: []byte{1, 2, 3}}}}, 265 | }, 266 | { 267 | src: &pb2.Communique{Union: &pb2.Communique_Msg{}}, 268 | dst: &pb2.Communique{}, 269 | want: &pb2.Communique{Union: &pb2.Communique_Msg{}}, 270 | }, 271 | { 272 | src: &pb2.Communique{Union: &pb2.Communique_Msg{&pb2.Strings{StringField: proto.String("123")}}}, 273 | dst: &pb2.Communique{Union: &pb2.Communique_Msg{&pb2.Strings{BytesField: []byte{1, 2, 3}}}}, 274 | want: &pb2.Communique{Union: &pb2.Communique_Msg{&pb2.Strings{StringField: proto.String("123"), BytesField: []byte{1, 2, 3}}}}, 275 | }, 276 | { 277 | src: &pb3.Message{ 278 | Terrain: map[string]*pb3.Nested{ 279 | "kay_a": &pb3.Nested{Cute: true}, // replace 280 | "kay_b": &pb3.Nested{Bunny: "rabbit"}, // insert 281 | }, 282 | }, 283 | dst: &pb3.Message{ 284 | Terrain: map[string]*pb3.Nested{ 285 | "kay_a": &pb3.Nested{Bunny: "lost"}, // replaced 286 | "kay_c": &pb3.Nested{Bunny: "bunny"}, // keep 287 | }, 288 | }, 289 | want: &pb3.Message{ 290 | Terrain: map[string]*pb3.Nested{ 291 | "kay_a": &pb3.Nested{Cute: true}, 292 | "kay_b": &pb3.Nested{Bunny: "rabbit"}, 293 | "kay_c": &pb3.Nested{Bunny: "bunny"}, 294 | }, 295 | }, 296 | }, 297 | { 298 | src: &pb2.GoTest{ 299 | F_BoolRepeated: []bool{}, 300 | F_Int32Repeated: []int32{}, 301 | F_Int64Repeated: []int64{}, 302 | F_Uint32Repeated: []uint32{}, 303 | F_Uint64Repeated: []uint64{}, 304 | F_FloatRepeated: []float32{}, 305 | F_DoubleRepeated: []float64{}, 306 | F_StringRepeated: []string{}, 307 | F_BytesRepeated: [][]byte{}, 308 | }, 309 | dst: &pb2.GoTest{}, 310 | want: &pb2.GoTest{ 311 | F_BoolRepeated: []bool{}, 312 | F_Int32Repeated: []int32{}, 313 | F_Int64Repeated: []int64{}, 314 | F_Uint32Repeated: []uint32{}, 315 | F_Uint64Repeated: []uint64{}, 316 | F_FloatRepeated: []float32{}, 317 | F_DoubleRepeated: []float64{}, 318 | F_StringRepeated: []string{}, 319 | F_BytesRepeated: [][]byte{}, 320 | }, 321 | }, 322 | { 323 | src: &pb2.GoTest{}, 324 | dst: &pb2.GoTest{ 325 | F_BoolRepeated: []bool{}, 326 | F_Int32Repeated: []int32{}, 327 | F_Int64Repeated: []int64{}, 328 | F_Uint32Repeated: []uint32{}, 329 | F_Uint64Repeated: []uint64{}, 330 | F_FloatRepeated: []float32{}, 331 | F_DoubleRepeated: []float64{}, 332 | F_StringRepeated: []string{}, 333 | F_BytesRepeated: [][]byte{}, 334 | }, 335 | want: &pb2.GoTest{ 336 | F_BoolRepeated: []bool{}, 337 | F_Int32Repeated: []int32{}, 338 | F_Int64Repeated: []int64{}, 339 | F_Uint32Repeated: []uint32{}, 340 | F_Uint64Repeated: []uint64{}, 341 | F_FloatRepeated: []float32{}, 342 | F_DoubleRepeated: []float64{}, 343 | F_StringRepeated: []string{}, 344 | F_BytesRepeated: [][]byte{}, 345 | }, 346 | }, 347 | { 348 | src: &pb2.GoTest{ 349 | F_BytesRepeated: [][]byte{nil, []byte{}, []byte{0}}, 350 | }, 351 | dst: &pb2.GoTest{}, 352 | want: &pb2.GoTest{ 353 | F_BytesRepeated: [][]byte{nil, []byte{}, []byte{0}}, 354 | }, 355 | }, 356 | { 357 | src: &pb2.MyMessage{ 358 | Others: []*pb2.OtherMessage{}, 359 | }, 360 | dst: &pb2.MyMessage{}, 361 | want: &pb2.MyMessage{ 362 | Others: []*pb2.OtherMessage{}, 363 | }, 364 | }, 365 | } 366 | 367 | func TestMerge(t *testing.T) { 368 | for _, m := range mergeTests { 369 | got := proto.Clone(m.dst) 370 | if !proto.Equal(got, m.dst) { 371 | t.Errorf("Clone()\ngot %v\nwant %v", got, m.dst) 372 | continue 373 | } 374 | proto.Merge(got, m.src) 375 | if !proto.Equal(got, m.want) { 376 | t.Errorf("Merge(%v, %v)\ngot %v\nwant %v", m.dst, m.src, got, m.want) 377 | } 378 | } 379 | } 380 | -------------------------------------------------------------------------------- /proto/proto_equal_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package proto_test 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/golang/protobuf/proto" 11 | 12 | pb2 "github.com/golang/protobuf/internal/testprotos/proto2_proto" 13 | pb3 "github.com/golang/protobuf/internal/testprotos/proto3_proto" 14 | ) 15 | 16 | // Four identical base messages. 17 | // The init function adds extensions to some of them. 18 | var messageWithoutExtension = &pb2.MyMessage{Count: proto.Int32(7)} 19 | var messageWithExtension1a = &pb2.MyMessage{Count: proto.Int32(7)} 20 | var messageWithExtension1b = &pb2.MyMessage{Count: proto.Int32(7)} 21 | var messageWithExtension2 = &pb2.MyMessage{Count: proto.Int32(7)} 22 | var messageWithExtension3a = &pb2.MyMessage{Count: proto.Int32(7)} 23 | var messageWithExtension3b = &pb2.MyMessage{Count: proto.Int32(7)} 24 | var messageWithExtension3c = &pb2.MyMessage{Count: proto.Int32(7)} 25 | 26 | // Two messages with non-message extensions. 27 | var messageWithInt32Extension1 = &pb2.MyMessage{Count: proto.Int32(8)} 28 | var messageWithInt32Extension2 = &pb2.MyMessage{Count: proto.Int32(8)} 29 | 30 | func init() { 31 | ext1 := &pb2.Ext{Data: proto.String("Kirk")} 32 | ext2 := &pb2.Ext{Data: proto.String("Picard")} 33 | 34 | // messageWithExtension1a has ext1, but never marshals it. 35 | if err := proto.SetExtension(messageWithExtension1a, pb2.E_Ext_More, ext1); err != nil { 36 | panic("proto.SetExtension on 1a failed: " + err.Error()) 37 | } 38 | 39 | // messageWithExtension1b is the unmarshaled form of messageWithExtension1a. 40 | if err := proto.SetExtension(messageWithExtension1b, pb2.E_Ext_More, ext1); err != nil { 41 | panic("proto.SetExtension on 1b failed: " + err.Error()) 42 | } 43 | buf, err := proto.Marshal(messageWithExtension1b) 44 | if err != nil { 45 | panic("proto.Marshal of 1b failed: " + err.Error()) 46 | } 47 | messageWithExtension1b.Reset() 48 | if err := proto.Unmarshal(buf, messageWithExtension1b); err != nil { 49 | panic("proto.Unmarshal of 1b failed: " + err.Error()) 50 | } 51 | 52 | // messageWithExtension2 has ext2. 53 | if err := proto.SetExtension(messageWithExtension2, pb2.E_Ext_More, ext2); err != nil { 54 | panic("proto.SetExtension on 2 failed: " + err.Error()) 55 | } 56 | 57 | if err := proto.SetExtension(messageWithInt32Extension1, pb2.E_Ext_Number, proto.Int32(23)); err != nil { 58 | panic("proto.SetExtension on Int32-1 failed: " + err.Error()) 59 | } 60 | if err := proto.SetExtension(messageWithInt32Extension1, pb2.E_Ext_Number, proto.Int32(24)); err != nil { 61 | panic("proto.SetExtension on Int32-2 failed: " + err.Error()) 62 | } 63 | 64 | // messageWithExtension3{a,b,c} has unregistered extension. 65 | if proto.RegisteredExtensions(messageWithExtension3a)[200] != nil { 66 | panic("expect extension 200 unregistered") 67 | } 68 | bytes := []byte{ 69 | 0xc0, 0x0c, 0x01, // id=200, wiretype=0 (varint), data=1 70 | } 71 | bytes2 := []byte{ 72 | 0xc0, 0x0c, 0x02, // id=200, wiretype=0 (varint), data=2 73 | } 74 | proto.SetRawExtension(messageWithExtension3a, 200, bytes) 75 | proto.SetRawExtension(messageWithExtension3b, 200, bytes) 76 | proto.SetRawExtension(messageWithExtension3c, 200, bytes2) 77 | } 78 | 79 | var EqualTests = []struct { 80 | desc string 81 | a, b proto.Message 82 | exp bool 83 | }{ 84 | {"different types", &pb2.GoEnum{}, &pb2.GoTestField{}, false}, 85 | {"equal empty", &pb2.GoEnum{}, &pb2.GoEnum{}, true}, 86 | {"nil vs nil", nil, nil, true}, 87 | {"typed nil vs typed nil", (*pb2.GoEnum)(nil), (*pb2.GoEnum)(nil), true}, 88 | {"typed nil vs empty", (*pb2.GoEnum)(nil), &pb2.GoEnum{}, false}, 89 | {"different typed nil", (*pb2.GoEnum)(nil), (*pb2.GoTestField)(nil), false}, 90 | 91 | {"one set field, one unset field", &pb2.GoTestField{Label: proto.String("foo")}, &pb2.GoTestField{}, false}, 92 | {"one set field zero, one unset field", &pb2.GoTest{Param: proto.Int32(0)}, &pb2.GoTest{}, false}, 93 | {"different set fields", &pb2.GoTestField{Label: proto.String("foo")}, &pb2.GoTestField{Label: proto.String("bar")}, false}, 94 | {"equal set", &pb2.GoTestField{Label: proto.String("foo")}, &pb2.GoTestField{Label: proto.String("foo")}, true}, 95 | 96 | {"repeated, one set", &pb2.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb2.GoTest{}, false}, 97 | {"repeated, different length", &pb2.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb2.GoTest{F_Int32Repeated: []int32{2}}, false}, 98 | {"repeated, different value", &pb2.GoTest{F_Int32Repeated: []int32{2}}, &pb2.GoTest{F_Int32Repeated: []int32{3}}, false}, 99 | {"repeated, equal", &pb2.GoTest{F_Int32Repeated: []int32{2, 4}}, &pb2.GoTest{F_Int32Repeated: []int32{2, 4}}, true}, 100 | {"repeated, nil equal nil", &pb2.GoTest{F_Int32Repeated: nil}, &pb2.GoTest{F_Int32Repeated: nil}, true}, 101 | {"repeated, nil equal empty", &pb2.GoTest{F_Int32Repeated: nil}, &pb2.GoTest{F_Int32Repeated: []int32{}}, true}, 102 | {"repeated, empty equal nil", &pb2.GoTest{F_Int32Repeated: []int32{}}, &pb2.GoTest{F_Int32Repeated: nil}, true}, 103 | 104 | { 105 | "nested, different", 106 | &pb2.GoTest{RequiredField: &pb2.GoTestField{Label: proto.String("foo")}}, 107 | &pb2.GoTest{RequiredField: &pb2.GoTestField{Label: proto.String("bar")}}, 108 | false, 109 | }, 110 | { 111 | "nested, equal", 112 | &pb2.GoTest{RequiredField: &pb2.GoTestField{Label: proto.String("wow")}}, 113 | &pb2.GoTest{RequiredField: &pb2.GoTestField{Label: proto.String("wow")}}, 114 | true, 115 | }, 116 | 117 | {"bytes", &pb2.OtherMessage{Value: []byte("foo")}, &pb2.OtherMessage{Value: []byte("foo")}, true}, 118 | {"bytes, empty", &pb2.OtherMessage{Value: []byte{}}, &pb2.OtherMessage{Value: []byte{}}, true}, 119 | {"bytes, empty vs nil", &pb2.OtherMessage{Value: []byte{}}, &pb2.OtherMessage{Value: nil}, false}, 120 | { 121 | "repeated bytes", 122 | &pb2.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}}, 123 | &pb2.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}}, 124 | true, 125 | }, 126 | // In proto3, []byte{} and []byte(nil) are equal. 127 | {"proto3 bytes, empty vs nil", &pb3.Message{Data: []byte{}}, &pb3.Message{Data: nil}, true}, 128 | 129 | {"extension vs. no extension", messageWithoutExtension, messageWithExtension1a, false}, 130 | {"extension vs. same extension", messageWithExtension1a, messageWithExtension1b, true}, 131 | {"extension vs. different extension", messageWithExtension1a, messageWithExtension2, false}, 132 | 133 | {"int32 extension vs. itself", messageWithInt32Extension1, messageWithInt32Extension1, true}, 134 | {"int32 extension vs. a different int32", messageWithInt32Extension1, messageWithInt32Extension2, false}, 135 | 136 | {"unregistered extension same", messageWithExtension3a, messageWithExtension3b, true}, 137 | {"unregistered extension different", messageWithExtension3a, messageWithExtension3c, false}, 138 | 139 | { 140 | "message with group", 141 | &pb2.MyMessage{ 142 | Count: proto.Int32(1), 143 | Somegroup: &pb2.MyMessage_SomeGroup{ 144 | GroupField: proto.Int32(5), 145 | }, 146 | }, 147 | &pb2.MyMessage{ 148 | Count: proto.Int32(1), 149 | Somegroup: &pb2.MyMessage_SomeGroup{ 150 | GroupField: proto.Int32(5), 151 | }, 152 | }, 153 | true, 154 | }, 155 | 156 | { 157 | "map same", 158 | &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, 159 | &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, 160 | true, 161 | }, 162 | { 163 | "map different entry", 164 | &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, 165 | &pb2.MessageWithMap{NameMapping: map[int32]string{2: "Rob"}}, 166 | false, 167 | }, 168 | { 169 | "map different key only", 170 | &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, 171 | &pb2.MessageWithMap{NameMapping: map[int32]string{2: "Ken"}}, 172 | false, 173 | }, 174 | { 175 | "map different value only", 176 | &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, 177 | &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}}, 178 | false, 179 | }, 180 | { 181 | "zero-length maps same", 182 | &pb2.MessageWithMap{NameMapping: map[int32]string{}}, 183 | &pb2.MessageWithMap{NameMapping: nil}, 184 | true, 185 | }, 186 | { 187 | "orders in map don't matter", 188 | &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken", 2: "Rob"}}, 189 | &pb2.MessageWithMap{NameMapping: map[int32]string{2: "Rob", 1: "Ken"}}, 190 | true, 191 | }, 192 | { 193 | "oneof same", 194 | &pb2.Communique{Union: &pb2.Communique_Number{41}}, 195 | &pb2.Communique{Union: &pb2.Communique_Number{41}}, 196 | true, 197 | }, 198 | { 199 | "oneof one nil", 200 | &pb2.Communique{Union: &pb2.Communique_Number{41}}, 201 | &pb2.Communique{}, 202 | false, 203 | }, 204 | { 205 | "oneof different", 206 | &pb2.Communique{Union: &pb2.Communique_Number{41}}, 207 | &pb2.Communique{Union: &pb2.Communique_Name{"Bobby Tables"}}, 208 | false, 209 | }, 210 | } 211 | 212 | func TestEqual(t *testing.T) { 213 | for _, tc := range EqualTests { 214 | if res := proto.Equal(tc.a, tc.b); res != tc.exp { 215 | t.Errorf("%v: Equal(%v, %v) = %v, want %v", tc.desc, tc.a, tc.b, res, tc.exp) 216 | } 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /proto/registry.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package proto 6 | 7 | import ( 8 | "bytes" 9 | "compress/gzip" 10 | "fmt" 11 | "io/ioutil" 12 | "reflect" 13 | "strings" 14 | "sync" 15 | 16 | "google.golang.org/protobuf/reflect/protodesc" 17 | "google.golang.org/protobuf/reflect/protoreflect" 18 | "google.golang.org/protobuf/reflect/protoregistry" 19 | "google.golang.org/protobuf/runtime/protoimpl" 20 | ) 21 | 22 | // filePath is the path to the proto source file. 23 | type filePath = string // e.g., "google/protobuf/descriptor.proto" 24 | 25 | // fileDescGZIP is the compressed contents of the encoded FileDescriptorProto. 26 | type fileDescGZIP = []byte 27 | 28 | var fileCache sync.Map // map[filePath]fileDescGZIP 29 | 30 | // RegisterFile is called from generated code to register the compressed 31 | // FileDescriptorProto with the file path for a proto source file. 32 | // 33 | // Deprecated: Use protoregistry.GlobalFiles.RegisterFile instead. 34 | func RegisterFile(s filePath, d fileDescGZIP) { 35 | // Decompress the descriptor. 36 | zr, err := gzip.NewReader(bytes.NewReader(d)) 37 | if err != nil { 38 | panic(fmt.Sprintf("proto: invalid compressed file descriptor: %v", err)) 39 | } 40 | b, err := ioutil.ReadAll(zr) 41 | if err != nil { 42 | panic(fmt.Sprintf("proto: invalid compressed file descriptor: %v", err)) 43 | } 44 | 45 | // Construct a protoreflect.FileDescriptor from the raw descriptor. 46 | // Note that DescBuilder.Build automatically registers the constructed 47 | // file descriptor with the v2 registry. 48 | protoimpl.DescBuilder{RawDescriptor: b}.Build() 49 | 50 | // Locally cache the raw descriptor form for the file. 51 | fileCache.Store(s, d) 52 | } 53 | 54 | // FileDescriptor returns the compressed FileDescriptorProto given the file path 55 | // for a proto source file. It returns nil if not found. 56 | // 57 | // Deprecated: Use protoregistry.GlobalFiles.FindFileByPath instead. 58 | func FileDescriptor(s filePath) fileDescGZIP { 59 | if v, ok := fileCache.Load(s); ok { 60 | return v.(fileDescGZIP) 61 | } 62 | 63 | // Find the descriptor in the v2 registry. 64 | var b []byte 65 | if fd, _ := protoregistry.GlobalFiles.FindFileByPath(s); fd != nil { 66 | b, _ = Marshal(protodesc.ToFileDescriptorProto(fd)) 67 | } 68 | 69 | // Locally cache the raw descriptor form for the file. 70 | if len(b) > 0 { 71 | v, _ := fileCache.LoadOrStore(s, protoimpl.X.CompressGZIP(b)) 72 | return v.(fileDescGZIP) 73 | } 74 | return nil 75 | } 76 | 77 | // enumName is the name of an enum. For historical reasons, the enum name is 78 | // neither the full Go name nor the full protobuf name of the enum. 79 | // The name is the dot-separated combination of just the proto package that the 80 | // enum is declared within followed by the Go type name of the generated enum. 81 | type enumName = string // e.g., "my.proto.package.GoMessage_GoEnum" 82 | 83 | // enumsByName maps enum values by name to their numeric counterpart. 84 | type enumsByName = map[string]int32 85 | 86 | // enumsByNumber maps enum values by number to their name counterpart. 87 | type enumsByNumber = map[int32]string 88 | 89 | var enumCache sync.Map // map[enumName]enumsByName 90 | var numFilesCache sync.Map // map[protoreflect.FullName]int 91 | 92 | // RegisterEnum is called from the generated code to register the mapping of 93 | // enum value names to enum numbers for the enum identified by s. 94 | // 95 | // Deprecated: Use protoregistry.GlobalTypes.RegisterEnum instead. 96 | func RegisterEnum(s enumName, _ enumsByNumber, m enumsByName) { 97 | if _, ok := enumCache.Load(s); ok { 98 | panic("proto: duplicate enum registered: " + s) 99 | } 100 | enumCache.Store(s, m) 101 | 102 | // This does not forward registration to the v2 registry since this API 103 | // lacks sufficient information to construct a complete v2 enum descriptor. 104 | } 105 | 106 | // EnumValueMap returns the mapping from enum value names to enum numbers for 107 | // the enum of the given name. It returns nil if not found. 108 | // 109 | // Deprecated: Use protoregistry.GlobalTypes.FindEnumByName instead. 110 | func EnumValueMap(s enumName) enumsByName { 111 | if v, ok := enumCache.Load(s); ok { 112 | return v.(enumsByName) 113 | } 114 | 115 | // Check whether the cache is stale. If the number of files in the current 116 | // package differs, then it means that some enums may have been recently 117 | // registered upstream that we do not know about. 118 | var protoPkg protoreflect.FullName 119 | if i := strings.LastIndexByte(s, '.'); i >= 0 { 120 | protoPkg = protoreflect.FullName(s[:i]) 121 | } 122 | v, _ := numFilesCache.Load(protoPkg) 123 | numFiles, _ := v.(int) 124 | if protoregistry.GlobalFiles.NumFilesByPackage(protoPkg) == numFiles { 125 | return nil // cache is up-to-date; was not found earlier 126 | } 127 | 128 | // Update the enum cache for all enums declared in the given proto package. 129 | numFiles = 0 130 | protoregistry.GlobalFiles.RangeFilesByPackage(protoPkg, func(fd protoreflect.FileDescriptor) bool { 131 | walkEnums(fd, func(ed protoreflect.EnumDescriptor) { 132 | name := protoimpl.X.LegacyEnumName(ed) 133 | if _, ok := enumCache.Load(name); !ok { 134 | m := make(enumsByName) 135 | evs := ed.Values() 136 | for i := evs.Len() - 1; i >= 0; i-- { 137 | ev := evs.Get(i) 138 | m[string(ev.Name())] = int32(ev.Number()) 139 | } 140 | enumCache.LoadOrStore(name, m) 141 | } 142 | }) 143 | numFiles++ 144 | return true 145 | }) 146 | numFilesCache.Store(protoPkg, numFiles) 147 | 148 | // Check cache again for enum map. 149 | if v, ok := enumCache.Load(s); ok { 150 | return v.(enumsByName) 151 | } 152 | return nil 153 | } 154 | 155 | // walkEnums recursively walks all enums declared in d. 156 | func walkEnums(d interface { 157 | Enums() protoreflect.EnumDescriptors 158 | Messages() protoreflect.MessageDescriptors 159 | }, f func(protoreflect.EnumDescriptor)) { 160 | eds := d.Enums() 161 | for i := eds.Len() - 1; i >= 0; i-- { 162 | f(eds.Get(i)) 163 | } 164 | mds := d.Messages() 165 | for i := mds.Len() - 1; i >= 0; i-- { 166 | walkEnums(mds.Get(i), f) 167 | } 168 | } 169 | 170 | // messageName is the full name of protobuf message. 171 | type messageName = string 172 | 173 | var messageTypeCache sync.Map // map[messageName]reflect.Type 174 | 175 | // RegisterType is called from generated code to register the message Go type 176 | // for a message of the given name. 177 | // 178 | // Deprecated: Use protoregistry.GlobalTypes.RegisterMessage instead. 179 | func RegisterType(m Message, s messageName) { 180 | mt := protoimpl.X.LegacyMessageTypeOf(m, protoreflect.FullName(s)) 181 | if err := protoregistry.GlobalTypes.RegisterMessage(mt); err != nil { 182 | panic(err) 183 | } 184 | messageTypeCache.Store(s, reflect.TypeOf(m)) 185 | } 186 | 187 | // RegisterMapType is called from generated code to register the Go map type 188 | // for a protobuf message representing a map entry. 189 | // 190 | // Deprecated: Do not use. 191 | func RegisterMapType(m interface{}, s messageName) { 192 | t := reflect.TypeOf(m) 193 | if t.Kind() != reflect.Map { 194 | panic(fmt.Sprintf("invalid map kind: %v", t)) 195 | } 196 | if _, ok := messageTypeCache.Load(s); ok { 197 | panic(fmt.Errorf("proto: duplicate proto message registered: %s", s)) 198 | } 199 | messageTypeCache.Store(s, t) 200 | } 201 | 202 | // MessageType returns the message type for a named message. 203 | // It returns nil if not found. 204 | // 205 | // Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead. 206 | func MessageType(s messageName) reflect.Type { 207 | if v, ok := messageTypeCache.Load(s); ok { 208 | return v.(reflect.Type) 209 | } 210 | 211 | // Derive the message type from the v2 registry. 212 | var t reflect.Type 213 | if mt, _ := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(s)); mt != nil { 214 | t = messageGoType(mt) 215 | } 216 | 217 | // If we could not get a concrete type, it is possible that it is a 218 | // pseudo-message for a map entry. 219 | if t == nil { 220 | d, _ := protoregistry.GlobalFiles.FindDescriptorByName(protoreflect.FullName(s)) 221 | if md, _ := d.(protoreflect.MessageDescriptor); md != nil && md.IsMapEntry() { 222 | kt := goTypeForField(md.Fields().ByNumber(1)) 223 | vt := goTypeForField(md.Fields().ByNumber(2)) 224 | t = reflect.MapOf(kt, vt) 225 | } 226 | } 227 | 228 | // Locally cache the message type for the given name. 229 | if t != nil { 230 | v, _ := messageTypeCache.LoadOrStore(s, t) 231 | return v.(reflect.Type) 232 | } 233 | return nil 234 | } 235 | 236 | func goTypeForField(fd protoreflect.FieldDescriptor) reflect.Type { 237 | switch k := fd.Kind(); k { 238 | case protoreflect.EnumKind: 239 | if et, _ := protoregistry.GlobalTypes.FindEnumByName(fd.Enum().FullName()); et != nil { 240 | return enumGoType(et) 241 | } 242 | return reflect.TypeOf(protoreflect.EnumNumber(0)) 243 | case protoreflect.MessageKind, protoreflect.GroupKind: 244 | if mt, _ := protoregistry.GlobalTypes.FindMessageByName(fd.Message().FullName()); mt != nil { 245 | return messageGoType(mt) 246 | } 247 | return reflect.TypeOf((*protoreflect.Message)(nil)).Elem() 248 | default: 249 | return reflect.TypeOf(fd.Default().Interface()) 250 | } 251 | } 252 | 253 | func enumGoType(et protoreflect.EnumType) reflect.Type { 254 | return reflect.TypeOf(et.New(0)) 255 | } 256 | 257 | func messageGoType(mt protoreflect.MessageType) reflect.Type { 258 | return reflect.TypeOf(MessageV1(mt.Zero().Interface())) 259 | } 260 | 261 | // MessageName returns the full protobuf name for the given message type. 262 | // 263 | // Deprecated: Use protoreflect.MessageDescriptor.FullName instead. 264 | func MessageName(m Message) messageName { 265 | if m == nil { 266 | return "" 267 | } 268 | if m, ok := m.(interface{ XXX_MessageName() messageName }); ok { 269 | return m.XXX_MessageName() 270 | } 271 | return messageName(protoimpl.X.MessageDescriptorOf(m).FullName()) 272 | } 273 | 274 | // RegisterExtension is called from the generated code to register 275 | // the extension descriptor. 276 | // 277 | // Deprecated: Use protoregistry.GlobalTypes.RegisterExtension instead. 278 | func RegisterExtension(d *ExtensionDesc) { 279 | if err := protoregistry.GlobalTypes.RegisterExtension(d); err != nil { 280 | panic(err) 281 | } 282 | } 283 | 284 | type extensionsByNumber = map[int32]*ExtensionDesc 285 | 286 | var extensionCache sync.Map // map[messageName]extensionsByNumber 287 | 288 | // RegisteredExtensions returns a map of the registered extensions for the 289 | // provided protobuf message, indexed by the extension field number. 290 | // 291 | // Deprecated: Use protoregistry.GlobalTypes.RangeExtensionsByMessage instead. 292 | func RegisteredExtensions(m Message) extensionsByNumber { 293 | // Check whether the cache is stale. If the number of extensions for 294 | // the given message differs, then it means that some extensions were 295 | // recently registered upstream that we do not know about. 296 | s := MessageName(m) 297 | v, _ := extensionCache.Load(s) 298 | xs, _ := v.(extensionsByNumber) 299 | if protoregistry.GlobalTypes.NumExtensionsByMessage(protoreflect.FullName(s)) == len(xs) { 300 | return xs // cache is up-to-date 301 | } 302 | 303 | // Cache is stale, re-compute the extensions map. 304 | xs = make(extensionsByNumber) 305 | protoregistry.GlobalTypes.RangeExtensionsByMessage(protoreflect.FullName(s), func(xt protoreflect.ExtensionType) bool { 306 | if xd, ok := xt.(*ExtensionDesc); ok { 307 | xs[int32(xt.TypeDescriptor().Number())] = xd 308 | } else { 309 | // TODO: This implies that the protoreflect.ExtensionType is a 310 | // custom type not generated by protoc-gen-go. We could try and 311 | // convert the type to an ExtensionDesc. 312 | } 313 | return true 314 | }) 315 | extensionCache.Store(s, xs) 316 | return xs 317 | } 318 | -------------------------------------------------------------------------------- /proto/registry_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package proto_test 6 | 7 | import ( 8 | "reflect" 9 | "testing" 10 | 11 | "github.com/golang/protobuf/proto" 12 | "google.golang.org/protobuf/reflect/protoreflect" 13 | 14 | descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" 15 | ) 16 | 17 | func TestRegistry(t *testing.T) { 18 | file := new(descpb.DescriptorProto).ProtoReflect().Descriptor().ParentFile() 19 | path := file.Path() 20 | pkg := file.Package() 21 | if got := proto.FileDescriptor(path); len(got) == 0 { 22 | t.Errorf("FileDescriptor(%q) = empty, want non-empty", path) 23 | } 24 | 25 | name := protoreflect.FullName(pkg + ".FieldDescriptorProto_Label") 26 | if got := proto.EnumValueMap(string(name)); len(got) == 0 { 27 | t.Errorf("EnumValueMap(%q) = empty, want non-empty", name) 28 | } 29 | 30 | msg := new(descpb.EnumDescriptorProto_EnumReservedRange) 31 | name = msg.ProtoReflect().Descriptor().FullName() 32 | wantType := reflect.TypeOf(msg) 33 | gotType := proto.MessageType(string(name)) 34 | if gotType != wantType { 35 | t.Errorf("MessageType(%q) = %v, want %v", name, gotType, wantType) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /proto/wire.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package proto 6 | 7 | import ( 8 | protoV2 "google.golang.org/protobuf/proto" 9 | "google.golang.org/protobuf/runtime/protoiface" 10 | ) 11 | 12 | // Size returns the size in bytes of the wire-format encoding of m. 13 | func Size(m Message) int { 14 | if m == nil { 15 | return 0 16 | } 17 | mi := MessageV2(m) 18 | return protoV2.Size(mi) 19 | } 20 | 21 | // Marshal returns the wire-format encoding of m. 22 | func Marshal(m Message) ([]byte, error) { 23 | b, err := marshalAppend(nil, m, false) 24 | if b == nil { 25 | b = zeroBytes 26 | } 27 | return b, err 28 | } 29 | 30 | var zeroBytes = make([]byte, 0, 0) 31 | 32 | func marshalAppend(buf []byte, m Message, deterministic bool) ([]byte, error) { 33 | if m == nil { 34 | return nil, ErrNil 35 | } 36 | mi := MessageV2(m) 37 | nbuf, err := protoV2.MarshalOptions{ 38 | Deterministic: deterministic, 39 | AllowPartial: true, 40 | }.MarshalAppend(buf, mi) 41 | if err != nil { 42 | return buf, err 43 | } 44 | if len(buf) == len(nbuf) { 45 | if !mi.ProtoReflect().IsValid() { 46 | return buf, ErrNil 47 | } 48 | } 49 | return nbuf, checkRequiredNotSet(mi) 50 | } 51 | 52 | // Unmarshal parses a wire-format message in b and places the decoded results in m. 53 | // 54 | // Unmarshal resets m before starting to unmarshal, so any existing data in m is always 55 | // removed. Use UnmarshalMerge to preserve and append to existing data. 56 | func Unmarshal(b []byte, m Message) error { 57 | m.Reset() 58 | return UnmarshalMerge(b, m) 59 | } 60 | 61 | // UnmarshalMerge parses a wire-format message in b and places the decoded results in m. 62 | func UnmarshalMerge(b []byte, m Message) error { 63 | mi := MessageV2(m) 64 | out, err := protoV2.UnmarshalOptions{ 65 | AllowPartial: true, 66 | Merge: true, 67 | }.UnmarshalState(protoiface.UnmarshalInput{ 68 | Buf: b, 69 | Message: mi.ProtoReflect(), 70 | }) 71 | if err != nil { 72 | return err 73 | } 74 | if out.Flags&protoiface.UnmarshalInitialized > 0 { 75 | return nil 76 | } 77 | return checkRequiredNotSet(mi) 78 | } 79 | -------------------------------------------------------------------------------- /proto/wrappers.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package proto 6 | 7 | // Bool stores v in a new bool value and returns a pointer to it. 8 | func Bool(v bool) *bool { return &v } 9 | 10 | // Int stores v in a new int32 value and returns a pointer to it. 11 | // 12 | // Deprecated: Use Int32 instead. 13 | func Int(v int) *int32 { return Int32(int32(v)) } 14 | 15 | // Int32 stores v in a new int32 value and returns a pointer to it. 16 | func Int32(v int32) *int32 { return &v } 17 | 18 | // Int64 stores v in a new int64 value and returns a pointer to it. 19 | func Int64(v int64) *int64 { return &v } 20 | 21 | // Uint32 stores v in a new uint32 value and returns a pointer to it. 22 | func Uint32(v uint32) *uint32 { return &v } 23 | 24 | // Uint64 stores v in a new uint64 value and returns a pointer to it. 25 | func Uint64(v uint64) *uint64 { return &v } 26 | 27 | // Float32 stores v in a new float32 value and returns a pointer to it. 28 | func Float32(v float32) *float32 { return &v } 29 | 30 | // Float64 stores v in a new float64 value and returns a pointer to it. 31 | func Float64(v float64) *float64 { return &v } 32 | 33 | // String stores v in a new string value and returns a pointer to it. 34 | func String(v string) *string { return &v } 35 | -------------------------------------------------------------------------------- /protoc-gen-go/generator/internal/remap/remap.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package remap handles tracking the locations of Go tokens in a source text 6 | // across a rewrite by the Go formatter. 7 | package remap 8 | 9 | import ( 10 | "fmt" 11 | "go/scanner" 12 | "go/token" 13 | ) 14 | 15 | // A Location represents a span of byte offsets in the source text. 16 | type Location struct { 17 | Pos, End int // End is exclusive 18 | } 19 | 20 | // A Map represents a mapping between token locations in an input source text 21 | // and locations in the correspnding output text. 22 | type Map map[Location]Location 23 | 24 | // Find reports whether the specified span is recorded by m, and if so returns 25 | // the new location it was mapped to. If the input span was not found, the 26 | // returned location is the same as the input. 27 | func (m Map) Find(pos, end int) (Location, bool) { 28 | key := Location{ 29 | Pos: pos, 30 | End: end, 31 | } 32 | if loc, ok := m[key]; ok { 33 | return loc, true 34 | } 35 | return key, false 36 | } 37 | 38 | func (m Map) add(opos, oend, npos, nend int) { 39 | m[Location{Pos: opos, End: oend}] = Location{Pos: npos, End: nend} 40 | } 41 | 42 | // Compute constructs a location mapping from input to output. An error is 43 | // reported if any of the tokens of output cannot be mapped. 44 | func Compute(input, output []byte) (Map, error) { 45 | itok := tokenize(input) 46 | otok := tokenize(output) 47 | if len(itok) != len(otok) { 48 | return nil, fmt.Errorf("wrong number of tokens, %d ≠ %d", len(itok), len(otok)) 49 | } 50 | m := make(Map) 51 | for i, ti := range itok { 52 | to := otok[i] 53 | if ti.Token != to.Token { 54 | return nil, fmt.Errorf("token %d type mismatch: %s ≠ %s", i+1, ti, to) 55 | } 56 | m.add(ti.pos, ti.end, to.pos, to.end) 57 | } 58 | return m, nil 59 | } 60 | 61 | // tokinfo records the span and type of a source token. 62 | type tokinfo struct { 63 | pos, end int 64 | token.Token 65 | } 66 | 67 | func tokenize(src []byte) []tokinfo { 68 | fs := token.NewFileSet() 69 | var s scanner.Scanner 70 | s.Init(fs.AddFile("src", fs.Base(), len(src)), src, nil, scanner.ScanComments) 71 | var info []tokinfo 72 | for { 73 | pos, next, lit := s.Scan() 74 | switch next { 75 | case token.SEMICOLON: 76 | continue 77 | } 78 | info = append(info, tokinfo{ 79 | pos: int(pos - 1), 80 | end: int(pos + token.Pos(len(lit)) - 1), 81 | Token: next, 82 | }) 83 | if next == token.EOF { 84 | break 85 | } 86 | } 87 | return info 88 | } 89 | -------------------------------------------------------------------------------- /protoc-gen-go/generator/internal/remap/remap_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package remap 6 | 7 | import ( 8 | "go/format" 9 | "testing" 10 | ) 11 | 12 | func TestErrors(t *testing.T) { 13 | tests := []struct { 14 | in, out string 15 | }{ 16 | {"", "x"}, 17 | {"x", ""}, 18 | {"var x int = 5\n", "var x = 5\n"}, 19 | {"these are \"one\" thing", "those are 'another' thing"}, 20 | } 21 | for _, test := range tests { 22 | m, err := Compute([]byte(test.in), []byte(test.out)) 23 | if err != nil { 24 | t.Logf("Got expected error: %v", err) 25 | continue 26 | } 27 | t.Errorf("Compute(%q, %q): got %+v, wanted error", test.in, test.out, m) 28 | } 29 | } 30 | 31 | func TestMatching(t *testing.T) { 32 | // The input is a source text that will be rearranged by the formatter. 33 | const input = `package foo 34 | var s int 35 | func main(){} 36 | ` 37 | 38 | output, err := format.Source([]byte(input)) 39 | if err != nil { 40 | t.Fatalf("Formatting failed: %v", err) 41 | } 42 | m, err := Compute([]byte(input), output) 43 | if err != nil { 44 | t.Fatalf("Unexpected error: %v", err) 45 | } 46 | 47 | // Verify that the mapped locations have the same text. 48 | for key, val := range m { 49 | want := input[key.Pos:key.End] 50 | got := string(output[val.Pos:val.End]) 51 | if got != want { 52 | t.Errorf("Token at %d:%d: got %q, want %q", key.Pos, key.End, got, want) 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /protoc-gen-go/main.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // protoc-gen-go is a plugin for the Google protocol buffer compiler to generate 6 | // Go code. Install it by building this program and making it accessible within 7 | // your PATH with the name: 8 | // 9 | // protoc-gen-go 10 | // 11 | // The 'go' suffix becomes part of the argument for the protocol compiler, 12 | // such that it can be invoked as: 13 | // 14 | // protoc --go_out=paths=source_relative:. path/to/file.proto 15 | // 16 | // This generates Go bindings for the protocol buffer defined by file.proto. 17 | // With that input, the output will be written to: 18 | // 19 | // path/to/file.pb.go 20 | // 21 | // See the README and documentation for protocol buffers to learn more: 22 | // 23 | // https://developers.google.com/protocol-buffers/ 24 | package main 25 | 26 | import ( 27 | "flag" 28 | "fmt" 29 | "strings" 30 | 31 | "github.com/golang/protobuf/internal/gengogrpc" 32 | gengo "google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo" 33 | "google.golang.org/protobuf/compiler/protogen" 34 | ) 35 | 36 | func main() { 37 | var ( 38 | flags flag.FlagSet 39 | plugins = flags.String("plugins", "", "list of plugins to enable (supported values: grpc)") 40 | importPrefix = flags.String("import_prefix", "", "prefix to prepend to import paths") 41 | ) 42 | importRewriteFunc := func(importPath protogen.GoImportPath) protogen.GoImportPath { 43 | switch importPath { 44 | case "context", "fmt", "math": 45 | return importPath 46 | } 47 | if *importPrefix != "" { 48 | return protogen.GoImportPath(*importPrefix) + importPath 49 | } 50 | return importPath 51 | } 52 | protogen.Options{ 53 | ParamFunc: flags.Set, 54 | ImportRewriteFunc: importRewriteFunc, 55 | }.Run(func(gen *protogen.Plugin) error { 56 | grpc := false 57 | for _, plugin := range strings.Split(*plugins, ",") { 58 | switch plugin { 59 | case "grpc": 60 | grpc = true 61 | case "": 62 | default: 63 | return fmt.Errorf("protoc-gen-go: unknown plugin %q", plugin) 64 | } 65 | } 66 | for _, f := range gen.Files { 67 | if !f.Generate { 68 | continue 69 | } 70 | g := gengo.GenerateFile(gen, f) 71 | if grpc { 72 | gengogrpc.GenerateFileContent(gen, f, g) 73 | } 74 | } 75 | gen.SupportedFeatures = gengo.SupportedFeatures 76 | return nil 77 | }) 78 | } 79 | -------------------------------------------------------------------------------- /protoc-gen-go/plugin/plugin.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // source: github.com/golang/protobuf/protoc-gen-go/plugin/plugin.proto 3 | 4 | package plugin_go 5 | 6 | import ( 7 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 8 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 9 | pluginpb "google.golang.org/protobuf/types/pluginpb" 10 | reflect "reflect" 11 | ) 12 | 13 | // Symbols defined in public import of google/protobuf/compiler/plugin.proto. 14 | 15 | type CodeGeneratorResponse_Feature = pluginpb.CodeGeneratorResponse_Feature 16 | 17 | const CodeGeneratorResponse_FEATURE_NONE = pluginpb.CodeGeneratorResponse_FEATURE_NONE 18 | const CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL = pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL 19 | const CodeGeneratorResponse_FEATURE_SUPPORTS_EDITIONS = pluginpb.CodeGeneratorResponse_FEATURE_SUPPORTS_EDITIONS 20 | 21 | var CodeGeneratorResponse_Feature_name = pluginpb.CodeGeneratorResponse_Feature_name 22 | var CodeGeneratorResponse_Feature_value = pluginpb.CodeGeneratorResponse_Feature_value 23 | 24 | type Version = pluginpb.Version 25 | type CodeGeneratorRequest = pluginpb.CodeGeneratorRequest 26 | type CodeGeneratorResponse = pluginpb.CodeGeneratorResponse 27 | type CodeGeneratorResponse_File = pluginpb.CodeGeneratorResponse_File 28 | 29 | var File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto protoreflect.FileDescriptor 30 | 31 | var file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_rawDesc = []byte{ 32 | 0x0a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 33 | 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f, 34 | 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 35 | 0x6e, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x25, 36 | 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 37 | 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 38 | 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 39 | 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 40 | 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 41 | 0x6f, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x3b, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, 42 | 0x67, 0x6f, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 43 | } 44 | 45 | var file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_goTypes = []interface{}{} 46 | var file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_depIdxs = []int32{ 47 | 0, // [0:0] is the sub-list for method output_type 48 | 0, // [0:0] is the sub-list for method input_type 49 | 0, // [0:0] is the sub-list for extension type_name 50 | 0, // [0:0] is the sub-list for extension extendee 51 | 0, // [0:0] is the sub-list for field type_name 52 | } 53 | 54 | func init() { file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_init() } 55 | func file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_init() { 56 | if File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto != nil { 57 | return 58 | } 59 | type x struct{} 60 | out := protoimpl.TypeBuilder{ 61 | File: protoimpl.DescBuilder{ 62 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 63 | RawDescriptor: file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_rawDesc, 64 | NumEnums: 0, 65 | NumMessages: 0, 66 | NumExtensions: 0, 67 | NumServices: 0, 68 | }, 69 | GoTypes: file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_goTypes, 70 | DependencyIndexes: file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_depIdxs, 71 | }.Build() 72 | File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto = out.File 73 | file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_rawDesc = nil 74 | file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_goTypes = nil 75 | file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_depIdxs = nil 76 | } 77 | -------------------------------------------------------------------------------- /ptypes/any.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ptypes 6 | 7 | import ( 8 | "fmt" 9 | "strings" 10 | 11 | "github.com/golang/protobuf/proto" 12 | "google.golang.org/protobuf/reflect/protoreflect" 13 | "google.golang.org/protobuf/reflect/protoregistry" 14 | 15 | anypb "github.com/golang/protobuf/ptypes/any" 16 | ) 17 | 18 | const urlPrefix = "type.googleapis.com/" 19 | 20 | // AnyMessageName returns the message name contained in an anypb.Any message. 21 | // Most type assertions should use the Is function instead. 22 | // 23 | // Deprecated: Call the any.MessageName method instead. 24 | func AnyMessageName(any *anypb.Any) (string, error) { 25 | name, err := anyMessageName(any) 26 | return string(name), err 27 | } 28 | func anyMessageName(any *anypb.Any) (protoreflect.FullName, error) { 29 | if any == nil { 30 | return "", fmt.Errorf("message is nil") 31 | } 32 | name := protoreflect.FullName(any.TypeUrl) 33 | if i := strings.LastIndex(any.TypeUrl, "/"); i >= 0 { 34 | name = name[i+len("/"):] 35 | } 36 | if !name.IsValid() { 37 | return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl) 38 | } 39 | return name, nil 40 | } 41 | 42 | // MarshalAny marshals the given message m into an anypb.Any message. 43 | // 44 | // Deprecated: Call the anypb.New function instead. 45 | func MarshalAny(m proto.Message) (*anypb.Any, error) { 46 | switch dm := m.(type) { 47 | case DynamicAny: 48 | m = dm.Message 49 | case *DynamicAny: 50 | if dm == nil { 51 | return nil, proto.ErrNil 52 | } 53 | m = dm.Message 54 | } 55 | b, err := proto.Marshal(m) 56 | if err != nil { 57 | return nil, err 58 | } 59 | return &anypb.Any{TypeUrl: urlPrefix + proto.MessageName(m), Value: b}, nil 60 | } 61 | 62 | // Empty returns a new message of the type specified in an anypb.Any message. 63 | // It returns protoregistry.NotFound if the corresponding message type could not 64 | // be resolved in the global registry. 65 | // 66 | // Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead 67 | // to resolve the message name and create a new instance of it. 68 | func Empty(any *anypb.Any) (proto.Message, error) { 69 | name, err := anyMessageName(any) 70 | if err != nil { 71 | return nil, err 72 | } 73 | mt, err := protoregistry.GlobalTypes.FindMessageByName(name) 74 | if err != nil { 75 | return nil, err 76 | } 77 | return proto.MessageV1(mt.New().Interface()), nil 78 | } 79 | 80 | // UnmarshalAny unmarshals the encoded value contained in the anypb.Any message 81 | // into the provided message m. It returns an error if the target message 82 | // does not match the type in the Any message or if an unmarshal error occurs. 83 | // 84 | // The target message m may be a *DynamicAny message. If the underlying message 85 | // type could not be resolved, then this returns protoregistry.NotFound. 86 | // 87 | // Deprecated: Call the any.UnmarshalTo method instead. 88 | func UnmarshalAny(any *anypb.Any, m proto.Message) error { 89 | if dm, ok := m.(*DynamicAny); ok { 90 | if dm.Message == nil { 91 | var err error 92 | dm.Message, err = Empty(any) 93 | if err != nil { 94 | return err 95 | } 96 | } 97 | m = dm.Message 98 | } 99 | 100 | anyName, err := AnyMessageName(any) 101 | if err != nil { 102 | return err 103 | } 104 | msgName := proto.MessageName(m) 105 | if anyName != msgName { 106 | return fmt.Errorf("mismatched message type: got %q want %q", anyName, msgName) 107 | } 108 | return proto.Unmarshal(any.Value, m) 109 | } 110 | 111 | // Is reports whether the Any message contains a message of the specified type. 112 | // 113 | // Deprecated: Call the any.MessageIs method instead. 114 | func Is(any *anypb.Any, m proto.Message) bool { 115 | if any == nil || m == nil { 116 | return false 117 | } 118 | name := proto.MessageName(m) 119 | if !strings.HasSuffix(any.TypeUrl, name) { 120 | return false 121 | } 122 | return len(any.TypeUrl) == len(name) || any.TypeUrl[len(any.TypeUrl)-len(name)-1] == '/' 123 | } 124 | 125 | // DynamicAny is a value that can be passed to UnmarshalAny to automatically 126 | // allocate a proto.Message for the type specified in an anypb.Any message. 127 | // The allocated message is stored in the embedded proto.Message. 128 | // 129 | // Example: 130 | // 131 | // var x ptypes.DynamicAny 132 | // if err := ptypes.UnmarshalAny(a, &x); err != nil { ... } 133 | // fmt.Printf("unmarshaled message: %v", x.Message) 134 | // 135 | // Deprecated: Use the any.UnmarshalNew method instead to unmarshal 136 | // the any message contents into a new instance of the underlying message. 137 | type DynamicAny struct{ proto.Message } 138 | 139 | func (m DynamicAny) String() string { 140 | if m.Message == nil { 141 | return "" 142 | } 143 | return m.Message.String() 144 | } 145 | func (m DynamicAny) Reset() { 146 | if m.Message == nil { 147 | return 148 | } 149 | m.Message.Reset() 150 | } 151 | func (m DynamicAny) ProtoMessage() { 152 | return 153 | } 154 | func (m DynamicAny) ProtoReflect() protoreflect.Message { 155 | if m.Message == nil { 156 | return nil 157 | } 158 | return dynamicAny{proto.MessageReflect(m.Message)} 159 | } 160 | 161 | type dynamicAny struct{ protoreflect.Message } 162 | 163 | func (m dynamicAny) Type() protoreflect.MessageType { 164 | return dynamicAnyType{m.Message.Type()} 165 | } 166 | func (m dynamicAny) New() protoreflect.Message { 167 | return dynamicAnyType{m.Message.Type()}.New() 168 | } 169 | func (m dynamicAny) Interface() protoreflect.ProtoMessage { 170 | return DynamicAny{proto.MessageV1(m.Message.Interface())} 171 | } 172 | 173 | type dynamicAnyType struct{ protoreflect.MessageType } 174 | 175 | func (t dynamicAnyType) New() protoreflect.Message { 176 | return dynamicAny{t.MessageType.New()} 177 | } 178 | func (t dynamicAnyType) Zero() protoreflect.Message { 179 | return dynamicAny{t.MessageType.Zero()} 180 | } 181 | -------------------------------------------------------------------------------- /ptypes/any/any.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // source: github.com/golang/protobuf/ptypes/any/any.proto 3 | 4 | package any 5 | 6 | import ( 7 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 8 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 9 | anypb "google.golang.org/protobuf/types/known/anypb" 10 | reflect "reflect" 11 | ) 12 | 13 | // Symbols defined in public import of google/protobuf/any.proto. 14 | 15 | type Any = anypb.Any 16 | 17 | var File_github_com_golang_protobuf_ptypes_any_any_proto protoreflect.FileDescriptor 18 | 19 | var file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = []byte{ 20 | 0x0a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 21 | 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 22 | 0x70, 0x65, 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 23 | 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 24 | 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x2b, 0x5a, 0x29, 25 | 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 26 | 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 27 | 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x3b, 0x61, 0x6e, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 28 | 0x74, 0x6f, 0x33, 29 | } 30 | 31 | var file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = []interface{}{} 32 | var file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = []int32{ 33 | 0, // [0:0] is the sub-list for method output_type 34 | 0, // [0:0] is the sub-list for method input_type 35 | 0, // [0:0] is the sub-list for extension type_name 36 | 0, // [0:0] is the sub-list for extension extendee 37 | 0, // [0:0] is the sub-list for field type_name 38 | } 39 | 40 | func init() { file_github_com_golang_protobuf_ptypes_any_any_proto_init() } 41 | func file_github_com_golang_protobuf_ptypes_any_any_proto_init() { 42 | if File_github_com_golang_protobuf_ptypes_any_any_proto != nil { 43 | return 44 | } 45 | type x struct{} 46 | out := protoimpl.TypeBuilder{ 47 | File: protoimpl.DescBuilder{ 48 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 49 | RawDescriptor: file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc, 50 | NumEnums: 0, 51 | NumMessages: 0, 52 | NumExtensions: 0, 53 | NumServices: 0, 54 | }, 55 | GoTypes: file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes, 56 | DependencyIndexes: file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs, 57 | }.Build() 58 | File_github_com_golang_protobuf_ptypes_any_any_proto = out.File 59 | file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = nil 60 | file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = nil 61 | file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = nil 62 | } 63 | -------------------------------------------------------------------------------- /ptypes/any_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ptypes 6 | 7 | import ( 8 | "reflect" 9 | "testing" 10 | 11 | "github.com/golang/protobuf/proto" 12 | 13 | descriptorpb "github.com/golang/protobuf/protoc-gen-go/descriptor" 14 | anypb "github.com/golang/protobuf/ptypes/any" 15 | ) 16 | 17 | func TestMarshalUnmarshal(t *testing.T) { 18 | orig := &anypb.Any{Value: []byte("test")} 19 | 20 | packed, err := MarshalAny(orig) 21 | if err != nil { 22 | t.Errorf("MarshalAny(%+v): got: _, %v exp: _, nil", orig, err) 23 | } 24 | 25 | unpacked := &anypb.Any{} 26 | err = UnmarshalAny(packed, unpacked) 27 | if err != nil || !proto.Equal(unpacked, orig) { 28 | t.Errorf("got: %v, %+v; want nil, %+v", err, unpacked, orig) 29 | } 30 | } 31 | 32 | func TestIs(t *testing.T) { 33 | a, err := MarshalAny(&descriptorpb.FileDescriptorProto{}) 34 | if err != nil { 35 | t.Fatal(err) 36 | } 37 | if Is(a, &descriptorpb.DescriptorProto{}) { 38 | // No spurious match for message names of different length. 39 | t.Error("FileDescriptorProto is not a DescriptorProto, but Is says it is") 40 | } 41 | if Is(a, &descriptorpb.EnumDescriptorProto{}) { 42 | // No spurious match for message names of equal length. 43 | t.Error("FileDescriptorProto is not an EnumDescriptorProto, but Is says it is") 44 | } 45 | if !Is(a, &descriptorpb.FileDescriptorProto{}) { 46 | t.Error("FileDescriptorProto is indeed a FileDescriptorProto, but Is says it is not") 47 | } 48 | } 49 | 50 | func TestIsDifferentUrlPrefixes(t *testing.T) { 51 | m := &descriptorpb.FileDescriptorProto{} 52 | a := &anypb.Any{TypeUrl: "foo/bar/" + proto.MessageName(m)} 53 | if !Is(a, m) { 54 | t.Errorf("message with type url %q didn't satisfy Is for type %q", a.TypeUrl, proto.MessageName(m)) 55 | } 56 | } 57 | 58 | func TestIsCornerCases(t *testing.T) { 59 | m := &descriptorpb.FileDescriptorProto{} 60 | if Is(nil, m) { 61 | t.Errorf("message with nil type url incorrectly claimed to be %q", proto.MessageName(m)) 62 | } 63 | noPrefix := &anypb.Any{TypeUrl: proto.MessageName(m)} 64 | if !Is(noPrefix, m) { 65 | t.Errorf("message with type url %q didn't satisfy Is for type %q", noPrefix.TypeUrl, proto.MessageName(m)) 66 | } 67 | shortPrefix := &anypb.Any{TypeUrl: "/" + proto.MessageName(m)} 68 | if !Is(shortPrefix, m) { 69 | t.Errorf("message with type url %q didn't satisfy Is for type %q", shortPrefix.TypeUrl, proto.MessageName(m)) 70 | } 71 | } 72 | 73 | func TestUnmarshalDynamic(t *testing.T) { 74 | want := &descriptorpb.FileDescriptorProto{Name: proto.String("foo")} 75 | a, err := MarshalAny(want) 76 | if err != nil { 77 | t.Fatal(err) 78 | } 79 | var got DynamicAny 80 | if err := UnmarshalAny(a, &got); err != nil { 81 | t.Fatal(err) 82 | } 83 | if !proto.Equal(got.Message, want) { 84 | t.Errorf("invalid result from UnmarshalAny, got %q want %q", got.Message, want) 85 | } 86 | } 87 | 88 | func TestEmpty(t *testing.T) { 89 | want := &descriptorpb.FileDescriptorProto{} 90 | a, err := MarshalAny(want) 91 | if err != nil { 92 | t.Fatal(err) 93 | } 94 | got, err := Empty(a) 95 | if err != nil { 96 | t.Fatal(err) 97 | } 98 | if !proto.Equal(got, want) { 99 | t.Errorf("unequal empty message, got %q, want %q", got, want) 100 | } 101 | 102 | // that's a valid type_url for a message which shouldn't be linked into this 103 | // test binary. We want an error. 104 | a.TypeUrl = "type.googleapis.com/google.protobuf.FieldMask" 105 | if _, err := Empty(a); err == nil { 106 | t.Errorf("got no error for an attempt to create a message of type %q, which shouldn't be linked in", a.TypeUrl) 107 | } 108 | } 109 | 110 | func TestEmptyCornerCases(t *testing.T) { 111 | _, err := Empty(nil) 112 | if err == nil { 113 | t.Error("expected Empty for nil to fail") 114 | } 115 | want := &descriptorpb.FileDescriptorProto{} 116 | noPrefix := &anypb.Any{TypeUrl: proto.MessageName(want)} 117 | got, err := Empty(noPrefix) 118 | if err != nil { 119 | t.Errorf("Empty for any type %q failed: %s", noPrefix.TypeUrl, err) 120 | } 121 | if !proto.Equal(got, want) { 122 | t.Errorf("Empty for any type %q differs, got %q, want %q", noPrefix.TypeUrl, got, want) 123 | } 124 | shortPrefix := &anypb.Any{TypeUrl: "/" + proto.MessageName(want)} 125 | got, err = Empty(shortPrefix) 126 | if err != nil { 127 | t.Errorf("Empty for any type %q failed: %s", shortPrefix.TypeUrl, err) 128 | } 129 | if !proto.Equal(got, want) { 130 | t.Errorf("Empty for any type %q differs, got %q, want %q", shortPrefix.TypeUrl, got, want) 131 | } 132 | } 133 | 134 | func TestAnyReflect(t *testing.T) { 135 | want := &descriptorpb.FileDescriptorProto{Name: proto.String("foo")} 136 | a, err := MarshalAny(want) 137 | if err != nil { 138 | t.Fatal(err) 139 | } 140 | var got DynamicAny 141 | if err := UnmarshalAny(a, &got); err != nil { 142 | t.Fatal(err) 143 | } 144 | wantName := want.ProtoReflect().Descriptor().FullName() 145 | gotName := got.ProtoReflect().Descriptor().FullName() 146 | if gotName != wantName { 147 | t.Errorf("name mismatch: got %v, want %v", gotName, wantName) 148 | } 149 | wantType := reflect.TypeOf(got) 150 | gotType := reflect.TypeOf(got.ProtoReflect().Interface()) 151 | if gotType != wantType { 152 | t.Errorf("ProtoReflect().Interface() round-trip type mismatch: got %v, want %v", gotType, wantType) 153 | } 154 | gotType = reflect.TypeOf(got.ProtoReflect().New().Interface()) 155 | if gotType != wantType { 156 | t.Errorf("ProtoReflect().New().Interface() type mismatch: got %v, want %v", gotType, wantType) 157 | } 158 | gotType = reflect.TypeOf(got.ProtoReflect().Type().New().Interface()) 159 | if gotType != wantType { 160 | t.Errorf("ProtoReflect().Type().New().Interface() type mismatch: got %v, want %v", gotType, wantType) 161 | } 162 | gotType = reflect.TypeOf(got.ProtoReflect().Type().Zero().Interface()) 163 | if gotType != wantType { 164 | t.Errorf("ProtoReflect().Type().Zero().Interface() type mismatch: got %v, want %v", gotType, wantType) 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /ptypes/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package ptypes provides functionality for interacting with well-known types. 6 | // 7 | // Deprecated: Well-known types have specialized functionality directly 8 | // injected into the generated packages for each message type. 9 | // See the deprecation notice for each function for the suggested alternative. 10 | package ptypes 11 | -------------------------------------------------------------------------------- /ptypes/duration.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ptypes 6 | 7 | import ( 8 | "errors" 9 | "fmt" 10 | "time" 11 | 12 | durationpb "github.com/golang/protobuf/ptypes/duration" 13 | ) 14 | 15 | // Range of google.protobuf.Duration as specified in duration.proto. 16 | // This is about 10,000 years in seconds. 17 | const ( 18 | maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60) 19 | minSeconds = -maxSeconds 20 | ) 21 | 22 | // Duration converts a durationpb.Duration to a time.Duration. 23 | // Duration returns an error if dur is invalid or overflows a time.Duration. 24 | // 25 | // Deprecated: Call the dur.AsDuration and dur.CheckValid methods instead. 26 | func Duration(dur *durationpb.Duration) (time.Duration, error) { 27 | if err := validateDuration(dur); err != nil { 28 | return 0, err 29 | } 30 | d := time.Duration(dur.Seconds) * time.Second 31 | if int64(d/time.Second) != dur.Seconds { 32 | return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur) 33 | } 34 | if dur.Nanos != 0 { 35 | d += time.Duration(dur.Nanos) * time.Nanosecond 36 | if (d < 0) != (dur.Nanos < 0) { 37 | return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur) 38 | } 39 | } 40 | return d, nil 41 | } 42 | 43 | // DurationProto converts a time.Duration to a durationpb.Duration. 44 | // 45 | // Deprecated: Call the durationpb.New function instead. 46 | func DurationProto(d time.Duration) *durationpb.Duration { 47 | nanos := d.Nanoseconds() 48 | secs := nanos / 1e9 49 | nanos -= secs * 1e9 50 | return &durationpb.Duration{ 51 | Seconds: int64(secs), 52 | Nanos: int32(nanos), 53 | } 54 | } 55 | 56 | // validateDuration determines whether the durationpb.Duration is valid 57 | // according to the definition in google/protobuf/duration.proto. 58 | // A valid durpb.Duration may still be too large to fit into a time.Duration 59 | // Note that the range of durationpb.Duration is about 10,000 years, 60 | // while the range of time.Duration is about 290 years. 61 | func validateDuration(dur *durationpb.Duration) error { 62 | if dur == nil { 63 | return errors.New("duration: nil Duration") 64 | } 65 | if dur.Seconds < minSeconds || dur.Seconds > maxSeconds { 66 | return fmt.Errorf("duration: %v: seconds out of range", dur) 67 | } 68 | if dur.Nanos <= -1e9 || dur.Nanos >= 1e9 { 69 | return fmt.Errorf("duration: %v: nanos out of range", dur) 70 | } 71 | // Seconds and Nanos must have the same sign, unless d.Nanos is zero. 72 | if (dur.Seconds < 0 && dur.Nanos > 0) || (dur.Seconds > 0 && dur.Nanos < 0) { 73 | return fmt.Errorf("duration: %v: seconds and nanos have different signs", dur) 74 | } 75 | return nil 76 | } 77 | -------------------------------------------------------------------------------- /ptypes/duration/duration.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // source: github.com/golang/protobuf/ptypes/duration/duration.proto 3 | 4 | package duration 5 | 6 | import ( 7 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 8 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 9 | durationpb "google.golang.org/protobuf/types/known/durationpb" 10 | reflect "reflect" 11 | ) 12 | 13 | // Symbols defined in public import of google/protobuf/duration.proto. 14 | 15 | type Duration = durationpb.Duration 16 | 17 | var File_github_com_golang_protobuf_ptypes_duration_duration_proto protoreflect.FileDescriptor 18 | 19 | var file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = []byte{ 20 | 0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 21 | 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 22 | 0x70, 0x65, 0x73, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x75, 0x72, 23 | 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 24 | 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 25 | 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x35, 0x5a, 0x33, 0x67, 26 | 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 27 | 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 28 | 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 29 | 0x6f, 0x6e, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 30 | } 31 | 32 | var file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = []interface{}{} 33 | var file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = []int32{ 34 | 0, // [0:0] is the sub-list for method output_type 35 | 0, // [0:0] is the sub-list for method input_type 36 | 0, // [0:0] is the sub-list for extension type_name 37 | 0, // [0:0] is the sub-list for extension extendee 38 | 0, // [0:0] is the sub-list for field type_name 39 | } 40 | 41 | func init() { file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() } 42 | func file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() { 43 | if File_github_com_golang_protobuf_ptypes_duration_duration_proto != nil { 44 | return 45 | } 46 | type x struct{} 47 | out := protoimpl.TypeBuilder{ 48 | File: protoimpl.DescBuilder{ 49 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 50 | RawDescriptor: file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc, 51 | NumEnums: 0, 52 | NumMessages: 0, 53 | NumExtensions: 0, 54 | NumServices: 0, 55 | }, 56 | GoTypes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes, 57 | DependencyIndexes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs, 58 | }.Build() 59 | File_github_com_golang_protobuf_ptypes_duration_duration_proto = out.File 60 | file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = nil 61 | file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = nil 62 | file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = nil 63 | } 64 | -------------------------------------------------------------------------------- /ptypes/duration_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ptypes 6 | 7 | import ( 8 | "math" 9 | "testing" 10 | "time" 11 | 12 | "github.com/golang/protobuf/proto" 13 | 14 | durpb "github.com/golang/protobuf/ptypes/duration" 15 | ) 16 | 17 | const ( 18 | minGoSeconds = math.MinInt64 / int64(1e9) 19 | maxGoSeconds = math.MaxInt64 / int64(1e9) 20 | ) 21 | 22 | var durationTests = []struct { 23 | proto *durpb.Duration 24 | isValid bool 25 | inRange bool 26 | dur time.Duration 27 | }{ 28 | // The zero duration. 29 | {&durpb.Duration{Seconds: 0, Nanos: 0}, true, true, 0}, 30 | // Some ordinary non-zero durations. 31 | {&durpb.Duration{Seconds: 100, Nanos: 0}, true, true, 100 * time.Second}, 32 | {&durpb.Duration{Seconds: -100, Nanos: 0}, true, true, -100 * time.Second}, 33 | {&durpb.Duration{Seconds: 100, Nanos: 987}, true, true, 100*time.Second + 987}, 34 | {&durpb.Duration{Seconds: -100, Nanos: -987}, true, true, -(100*time.Second + 987)}, 35 | // The largest duration representable in Go. 36 | {&durpb.Duration{Seconds: maxGoSeconds, Nanos: int32(math.MaxInt64 - 1e9*maxGoSeconds)}, true, true, math.MaxInt64}, 37 | // The smallest duration representable in Go. 38 | {&durpb.Duration{Seconds: minGoSeconds, Nanos: int32(math.MinInt64 - 1e9*minGoSeconds)}, true, true, math.MinInt64}, 39 | {nil, false, false, 0}, 40 | {&durpb.Duration{Seconds: -100, Nanos: 987}, false, false, 0}, 41 | {&durpb.Duration{Seconds: 100, Nanos: -987}, false, false, 0}, 42 | {&durpb.Duration{Seconds: math.MinInt64, Nanos: 0}, false, false, 0}, 43 | {&durpb.Duration{Seconds: math.MaxInt64, Nanos: 0}, false, false, 0}, 44 | // The largest valid duration. 45 | {&durpb.Duration{Seconds: maxSeconds, Nanos: 1e9 - 1}, true, false, 0}, 46 | // The smallest valid duration. 47 | {&durpb.Duration{Seconds: minSeconds, Nanos: -(1e9 - 1)}, true, false, 0}, 48 | // The smallest invalid duration above the valid range. 49 | {&durpb.Duration{Seconds: maxSeconds + 1, Nanos: 0}, false, false, 0}, 50 | // The largest invalid duration below the valid range. 51 | {&durpb.Duration{Seconds: minSeconds - 1, Nanos: -(1e9 - 1)}, false, false, 0}, 52 | // One nanosecond past the largest duration representable in Go. 53 | {&durpb.Duration{Seconds: maxGoSeconds, Nanos: int32(math.MaxInt64-1e9*maxGoSeconds) + 1}, true, false, 0}, 54 | // One nanosecond past the smallest duration representable in Go. 55 | {&durpb.Duration{Seconds: minGoSeconds, Nanos: int32(math.MinInt64-1e9*minGoSeconds) - 1}, true, false, 0}, 56 | // One second past the largest duration representable in Go. 57 | {&durpb.Duration{Seconds: maxGoSeconds + 1, Nanos: int32(math.MaxInt64 - 1e9*maxGoSeconds)}, true, false, 0}, 58 | // One second past the smallest duration representable in Go. 59 | {&durpb.Duration{Seconds: minGoSeconds - 1, Nanos: int32(math.MinInt64 - 1e9*minGoSeconds)}, true, false, 0}, 60 | } 61 | 62 | func TestValidateDuration(t *testing.T) { 63 | for _, test := range durationTests { 64 | err := validateDuration(test.proto) 65 | gotValid := (err == nil) 66 | if gotValid != test.isValid { 67 | t.Errorf("validateDuration(%v) = %t, want %t", test.proto, gotValid, test.isValid) 68 | } 69 | } 70 | } 71 | 72 | func TestDuration(t *testing.T) { 73 | for _, test := range durationTests { 74 | got, err := Duration(test.proto) 75 | gotOK := (err == nil) 76 | wantOK := test.isValid && test.inRange 77 | if gotOK != wantOK { 78 | t.Errorf("Duration(%v) ok = %t, want %t", test.proto, gotOK, wantOK) 79 | } 80 | if err == nil && got != test.dur { 81 | t.Errorf("Duration(%v) = %v, want %v", test.proto, got, test.dur) 82 | } 83 | } 84 | } 85 | 86 | func TestDurationProto(t *testing.T) { 87 | for _, test := range durationTests { 88 | if test.isValid && test.inRange { 89 | got := DurationProto(test.dur) 90 | if !proto.Equal(got, test.proto) { 91 | t.Errorf("DurationProto(%v) = %v, want %v", test.dur, got, test.proto) 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /ptypes/empty/empty.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // source: github.com/golang/protobuf/ptypes/empty/empty.proto 3 | 4 | package empty 5 | 6 | import ( 7 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 8 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 9 | emptypb "google.golang.org/protobuf/types/known/emptypb" 10 | reflect "reflect" 11 | ) 12 | 13 | // Symbols defined in public import of google/protobuf/empty.proto. 14 | 15 | type Empty = emptypb.Empty 16 | 17 | var File_github_com_golang_protobuf_ptypes_empty_empty_proto protoreflect.FileDescriptor 18 | 19 | var file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc = []byte{ 20 | 0x0a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 21 | 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 22 | 0x70, 0x65, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 23 | 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 24 | 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 25 | 0x74, 0x6f, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 26 | 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 27 | 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3b, 0x65, 0x6d, 28 | 0x70, 0x74, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 29 | } 30 | 31 | var file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = []interface{}{} 32 | var file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = []int32{ 33 | 0, // [0:0] is the sub-list for method output_type 34 | 0, // [0:0] is the sub-list for method input_type 35 | 0, // [0:0] is the sub-list for extension type_name 36 | 0, // [0:0] is the sub-list for extension extendee 37 | 0, // [0:0] is the sub-list for field type_name 38 | } 39 | 40 | func init() { file_github_com_golang_protobuf_ptypes_empty_empty_proto_init() } 41 | func file_github_com_golang_protobuf_ptypes_empty_empty_proto_init() { 42 | if File_github_com_golang_protobuf_ptypes_empty_empty_proto != nil { 43 | return 44 | } 45 | type x struct{} 46 | out := protoimpl.TypeBuilder{ 47 | File: protoimpl.DescBuilder{ 48 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 49 | RawDescriptor: file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc, 50 | NumEnums: 0, 51 | NumMessages: 0, 52 | NumExtensions: 0, 53 | NumServices: 0, 54 | }, 55 | GoTypes: file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes, 56 | DependencyIndexes: file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs, 57 | }.Build() 58 | File_github_com_golang_protobuf_ptypes_empty_empty_proto = out.File 59 | file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc = nil 60 | file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = nil 61 | file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = nil 62 | } 63 | -------------------------------------------------------------------------------- /ptypes/struct/struct.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // source: github.com/golang/protobuf/ptypes/struct/struct.proto 3 | 4 | package structpb 5 | 6 | import ( 7 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 8 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 9 | structpb "google.golang.org/protobuf/types/known/structpb" 10 | reflect "reflect" 11 | ) 12 | 13 | // Symbols defined in public import of google/protobuf/struct.proto. 14 | 15 | type NullValue = structpb.NullValue 16 | 17 | const NullValue_NULL_VALUE = structpb.NullValue_NULL_VALUE 18 | 19 | var NullValue_name = structpb.NullValue_name 20 | var NullValue_value = structpb.NullValue_value 21 | 22 | type Struct = structpb.Struct 23 | type Value = structpb.Value 24 | type Value_NullValue = structpb.Value_NullValue 25 | type Value_NumberValue = structpb.Value_NumberValue 26 | type Value_StringValue = structpb.Value_StringValue 27 | type Value_BoolValue = structpb.Value_BoolValue 28 | type Value_StructValue = structpb.Value_StructValue 29 | type Value_ListValue = structpb.Value_ListValue 30 | type ListValue = structpb.ListValue 31 | 32 | var File_github_com_golang_protobuf_ptypes_struct_struct_proto protoreflect.FileDescriptor 33 | 34 | var file_github_com_golang_protobuf_ptypes_struct_struct_proto_rawDesc = []byte{ 35 | 0x0a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 36 | 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 37 | 0x70, 0x65, 0x73, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 38 | 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 39 | 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 40 | 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 41 | 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 42 | 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 43 | 0x74, 0x3b, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x70, 0x62, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 44 | 0x6f, 0x74, 0x6f, 0x33, 45 | } 46 | 47 | var file_github_com_golang_protobuf_ptypes_struct_struct_proto_goTypes = []interface{}{} 48 | var file_github_com_golang_protobuf_ptypes_struct_struct_proto_depIdxs = []int32{ 49 | 0, // [0:0] is the sub-list for method output_type 50 | 0, // [0:0] is the sub-list for method input_type 51 | 0, // [0:0] is the sub-list for extension type_name 52 | 0, // [0:0] is the sub-list for extension extendee 53 | 0, // [0:0] is the sub-list for field type_name 54 | } 55 | 56 | func init() { file_github_com_golang_protobuf_ptypes_struct_struct_proto_init() } 57 | func file_github_com_golang_protobuf_ptypes_struct_struct_proto_init() { 58 | if File_github_com_golang_protobuf_ptypes_struct_struct_proto != nil { 59 | return 60 | } 61 | type x struct{} 62 | out := protoimpl.TypeBuilder{ 63 | File: protoimpl.DescBuilder{ 64 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 65 | RawDescriptor: file_github_com_golang_protobuf_ptypes_struct_struct_proto_rawDesc, 66 | NumEnums: 0, 67 | NumMessages: 0, 68 | NumExtensions: 0, 69 | NumServices: 0, 70 | }, 71 | GoTypes: file_github_com_golang_protobuf_ptypes_struct_struct_proto_goTypes, 72 | DependencyIndexes: file_github_com_golang_protobuf_ptypes_struct_struct_proto_depIdxs, 73 | }.Build() 74 | File_github_com_golang_protobuf_ptypes_struct_struct_proto = out.File 75 | file_github_com_golang_protobuf_ptypes_struct_struct_proto_rawDesc = nil 76 | file_github_com_golang_protobuf_ptypes_struct_struct_proto_goTypes = nil 77 | file_github_com_golang_protobuf_ptypes_struct_struct_proto_depIdxs = nil 78 | } 79 | -------------------------------------------------------------------------------- /ptypes/timestamp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ptypes 6 | 7 | import ( 8 | "errors" 9 | "fmt" 10 | "time" 11 | 12 | timestamppb "github.com/golang/protobuf/ptypes/timestamp" 13 | ) 14 | 15 | // Range of google.protobuf.Duration as specified in timestamp.proto. 16 | const ( 17 | // Seconds field of the earliest valid Timestamp. 18 | // This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). 19 | minValidSeconds = -62135596800 20 | // Seconds field just after the latest valid Timestamp. 21 | // This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). 22 | maxValidSeconds = 253402300800 23 | ) 24 | 25 | // Timestamp converts a timestamppb.Timestamp to a time.Time. 26 | // It returns an error if the argument is invalid. 27 | // 28 | // Unlike most Go functions, if Timestamp returns an error, the first return 29 | // value is not the zero time.Time. Instead, it is the value obtained from the 30 | // time.Unix function when passed the contents of the Timestamp, in the UTC 31 | // locale. This may or may not be a meaningful time; many invalid Timestamps 32 | // do map to valid time.Times. 33 | // 34 | // A nil Timestamp returns an error. The first return value in that case is 35 | // undefined. 36 | // 37 | // Deprecated: Call the ts.AsTime and ts.CheckValid methods instead. 38 | func Timestamp(ts *timestamppb.Timestamp) (time.Time, error) { 39 | // Don't return the zero value on error, because corresponds to a valid 40 | // timestamp. Instead return whatever time.Unix gives us. 41 | var t time.Time 42 | if ts == nil { 43 | t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp 44 | } else { 45 | t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC() 46 | } 47 | return t, validateTimestamp(ts) 48 | } 49 | 50 | // TimestampNow returns a google.protobuf.Timestamp for the current time. 51 | // 52 | // Deprecated: Call the timestamppb.Now function instead. 53 | func TimestampNow() *timestamppb.Timestamp { 54 | ts, err := TimestampProto(time.Now()) 55 | if err != nil { 56 | panic("ptypes: time.Now() out of Timestamp range") 57 | } 58 | return ts 59 | } 60 | 61 | // TimestampProto converts the time.Time to a google.protobuf.Timestamp proto. 62 | // It returns an error if the resulting Timestamp is invalid. 63 | // 64 | // Deprecated: Call the timestamppb.New function instead. 65 | func TimestampProto(t time.Time) (*timestamppb.Timestamp, error) { 66 | ts := ×tamppb.Timestamp{ 67 | Seconds: t.Unix(), 68 | Nanos: int32(t.Nanosecond()), 69 | } 70 | if err := validateTimestamp(ts); err != nil { 71 | return nil, err 72 | } 73 | return ts, nil 74 | } 75 | 76 | // TimestampString returns the RFC 3339 string for valid Timestamps. 77 | // For invalid Timestamps, it returns an error message in parentheses. 78 | // 79 | // Deprecated: Call the ts.AsTime method instead, 80 | // followed by a call to the Format method on the time.Time value. 81 | func TimestampString(ts *timestamppb.Timestamp) string { 82 | t, err := Timestamp(ts) 83 | if err != nil { 84 | return fmt.Sprintf("(%v)", err) 85 | } 86 | return t.Format(time.RFC3339Nano) 87 | } 88 | 89 | // validateTimestamp determines whether a Timestamp is valid. 90 | // A valid timestamp represents a time in the range [0001-01-01, 10000-01-01) 91 | // and has a Nanos field in the range [0, 1e9). 92 | // 93 | // If the Timestamp is valid, validateTimestamp returns nil. 94 | // Otherwise, it returns an error that describes the problem. 95 | // 96 | // Every valid Timestamp can be represented by a time.Time, 97 | // but the converse is not true. 98 | func validateTimestamp(ts *timestamppb.Timestamp) error { 99 | if ts == nil { 100 | return errors.New("timestamp: nil Timestamp") 101 | } 102 | if ts.Seconds < minValidSeconds { 103 | return fmt.Errorf("timestamp: %v before 0001-01-01", ts) 104 | } 105 | if ts.Seconds >= maxValidSeconds { 106 | return fmt.Errorf("timestamp: %v after 10000-01-01", ts) 107 | } 108 | if ts.Nanos < 0 || ts.Nanos >= 1e9 { 109 | return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts) 110 | } 111 | return nil 112 | } 113 | -------------------------------------------------------------------------------- /ptypes/timestamp/timestamp.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // source: github.com/golang/protobuf/ptypes/timestamp/timestamp.proto 3 | 4 | package timestamp 5 | 6 | import ( 7 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 8 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 9 | timestamppb "google.golang.org/protobuf/types/known/timestamppb" 10 | reflect "reflect" 11 | ) 12 | 13 | // Symbols defined in public import of google/protobuf/timestamp.proto. 14 | 15 | type Timestamp = timestamppb.Timestamp 16 | 17 | var File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto protoreflect.FileDescriptor 18 | 19 | var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc = []byte{ 20 | 0x0a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 21 | 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 22 | 0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2f, 0x74, 0x69, 23 | 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 24 | 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 25 | 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x37, 26 | 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 27 | 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 28 | 0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x3b, 0x74, 0x69, 29 | 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 30 | 0x33, 31 | } 32 | 33 | var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = []interface{}{} 34 | var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = []int32{ 35 | 0, // [0:0] is the sub-list for method output_type 36 | 0, // [0:0] is the sub-list for method input_type 37 | 0, // [0:0] is the sub-list for extension type_name 38 | 0, // [0:0] is the sub-list for extension extendee 39 | 0, // [0:0] is the sub-list for field type_name 40 | } 41 | 42 | func init() { file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init() } 43 | func file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init() { 44 | if File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto != nil { 45 | return 46 | } 47 | type x struct{} 48 | out := protoimpl.TypeBuilder{ 49 | File: protoimpl.DescBuilder{ 50 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 51 | RawDescriptor: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc, 52 | NumEnums: 0, 53 | NumMessages: 0, 54 | NumExtensions: 0, 55 | NumServices: 0, 56 | }, 57 | GoTypes: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes, 58 | DependencyIndexes: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs, 59 | }.Build() 60 | File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto = out.File 61 | file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc = nil 62 | file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = nil 63 | file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = nil 64 | } 65 | -------------------------------------------------------------------------------- /ptypes/timestamp_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package ptypes 6 | 7 | import ( 8 | "math" 9 | "testing" 10 | "time" 11 | 12 | "github.com/golang/protobuf/proto" 13 | 14 | tspb "github.com/golang/protobuf/ptypes/timestamp" 15 | ) 16 | 17 | var tests = []struct { 18 | ts *tspb.Timestamp 19 | valid bool 20 | t time.Time 21 | }{ 22 | // The timestamp representing the Unix epoch date. 23 | {&tspb.Timestamp{Seconds: 0, Nanos: 0}, true, utcDate(1970, 1, 1)}, 24 | // The smallest representable timestamp. 25 | {&tspb.Timestamp{Seconds: math.MinInt64, Nanos: math.MinInt32}, false, 26 | time.Unix(math.MinInt64, math.MinInt32).UTC()}, 27 | // The smallest representable timestamp with non-negative nanos. 28 | {&tspb.Timestamp{Seconds: math.MinInt64, Nanos: 0}, false, time.Unix(math.MinInt64, 0).UTC()}, 29 | // The earliest valid timestamp. 30 | {&tspb.Timestamp{Seconds: minValidSeconds, Nanos: 0}, true, utcDate(1, 1, 1)}, 31 | //"0001-01-01T00:00:00Z"}, 32 | // The largest representable timestamp. 33 | {&tspb.Timestamp{Seconds: math.MaxInt64, Nanos: math.MaxInt32}, false, 34 | time.Unix(math.MaxInt64, math.MaxInt32).UTC()}, 35 | // The largest representable timestamp with nanos in range. 36 | {&tspb.Timestamp{Seconds: math.MaxInt64, Nanos: 1e9 - 1}, false, 37 | time.Unix(math.MaxInt64, 1e9-1).UTC()}, 38 | // The largest valid timestamp. 39 | {&tspb.Timestamp{Seconds: maxValidSeconds - 1, Nanos: 1e9 - 1}, true, 40 | time.Date(9999, 12, 31, 23, 59, 59, 1e9-1, time.UTC)}, 41 | // The smallest invalid timestamp that is larger than the valid range. 42 | {&tspb.Timestamp{Seconds: maxValidSeconds, Nanos: 0}, false, time.Unix(maxValidSeconds, 0).UTC()}, 43 | // A date before the epoch. 44 | {&tspb.Timestamp{Seconds: -281836800, Nanos: 0}, true, utcDate(1961, 1, 26)}, 45 | // A date after the epoch. 46 | {&tspb.Timestamp{Seconds: 1296000000, Nanos: 0}, true, utcDate(2011, 1, 26)}, 47 | // A date after the epoch, in the middle of the day. 48 | {&tspb.Timestamp{Seconds: 1296012345, Nanos: 940483}, true, 49 | time.Date(2011, 1, 26, 3, 25, 45, 940483, time.UTC)}, 50 | } 51 | 52 | func TestValidateTimestamp(t *testing.T) { 53 | for _, s := range tests { 54 | got := validateTimestamp(s.ts) 55 | if (got == nil) != s.valid { 56 | t.Errorf("validateTimestamp(%v) = %v, want %v", s.ts, got, s.valid) 57 | } 58 | } 59 | } 60 | 61 | func TestTimestamp(t *testing.T) { 62 | for _, s := range tests { 63 | got, err := Timestamp(s.ts) 64 | if (err == nil) != s.valid { 65 | t.Errorf("Timestamp(%v) error = %v, but valid = %t", s.ts, err, s.valid) 66 | } else if s.valid && got != s.t { 67 | t.Errorf("Timestamp(%v) = %v, want %v", s.ts, got, s.t) 68 | } 69 | } 70 | // Special case: a nil Timestamp is an error, but returns the 0 Unix time. 71 | got, err := Timestamp(nil) 72 | want := time.Unix(0, 0).UTC() 73 | if got != want { 74 | t.Errorf("Timestamp(nil) = %v, want %v", got, want) 75 | } 76 | if err == nil { 77 | t.Errorf("Timestamp(nil) error = nil, expected error") 78 | } 79 | } 80 | 81 | func TestTimestampProto(t *testing.T) { 82 | for _, s := range tests { 83 | got, err := TimestampProto(s.t) 84 | if (err == nil) != s.valid { 85 | t.Errorf("TimestampProto(%v) error = %v, but valid = %t", s.t, err, s.valid) 86 | } else if s.valid && !proto.Equal(got, s.ts) { 87 | t.Errorf("TimestampProto(%v) = %v, want %v", s.t, got, s.ts) 88 | } 89 | } 90 | // No corresponding special case here: no time.Time results in a nil Timestamp. 91 | } 92 | 93 | func TestTimestampString(t *testing.T) { 94 | for _, test := range []struct { 95 | ts *tspb.Timestamp 96 | want string 97 | }{ 98 | // Not much testing needed because presumably time.Format is 99 | // well-tested. 100 | {&tspb.Timestamp{Seconds: 0, Nanos: 0}, "1970-01-01T00:00:00Z"}, 101 | } { 102 | got := TimestampString(test.ts) 103 | if got != test.want { 104 | t.Errorf("TimestampString(%v) = %q, want %q", test.ts, got, test.want) 105 | } 106 | } 107 | } 108 | 109 | func utcDate(year, month, day int) time.Time { 110 | return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC) 111 | } 112 | 113 | func TestTimestampNow(t *testing.T) { 114 | // Bracket the expected time. 115 | before := time.Now() 116 | ts := TimestampNow() 117 | after := time.Now() 118 | 119 | tm, err := Timestamp(ts) 120 | if err != nil { 121 | t.Errorf("between %v and %v\nTimestampNow() = %v\nwhich is invalid (%v)", before, after, ts, err) 122 | } 123 | if tm.Before(before) || tm.After(after) { 124 | t.Errorf("between %v and %v\nTimestamp(TimestampNow()) = %v", before, after, tm) 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /ptypes/wrappers/wrappers.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // source: github.com/golang/protobuf/ptypes/wrappers/wrappers.proto 3 | 4 | package wrappers 5 | 6 | import ( 7 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 8 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 9 | wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" 10 | reflect "reflect" 11 | ) 12 | 13 | // Symbols defined in public import of google/protobuf/wrappers.proto. 14 | 15 | type DoubleValue = wrapperspb.DoubleValue 16 | type FloatValue = wrapperspb.FloatValue 17 | type Int64Value = wrapperspb.Int64Value 18 | type UInt64Value = wrapperspb.UInt64Value 19 | type Int32Value = wrapperspb.Int32Value 20 | type UInt32Value = wrapperspb.UInt32Value 21 | type BoolValue = wrapperspb.BoolValue 22 | type StringValue = wrapperspb.StringValue 23 | type BytesValue = wrapperspb.BytesValue 24 | 25 | var File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto protoreflect.FileDescriptor 26 | 27 | var file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawDesc = []byte{ 28 | 0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 29 | 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 30 | 0x70, 0x65, 0x73, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2f, 0x77, 0x72, 0x61, 31 | 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 32 | 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 33 | 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x35, 0x5a, 0x33, 0x67, 34 | 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 35 | 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 36 | 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x3b, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 37 | 0x72, 0x73, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 38 | } 39 | 40 | var file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_goTypes = []interface{}{} 41 | var file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_depIdxs = []int32{ 42 | 0, // [0:0] is the sub-list for method output_type 43 | 0, // [0:0] is the sub-list for method input_type 44 | 0, // [0:0] is the sub-list for extension type_name 45 | 0, // [0:0] is the sub-list for extension extendee 46 | 0, // [0:0] is the sub-list for field type_name 47 | } 48 | 49 | func init() { file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_init() } 50 | func file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_init() { 51 | if File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto != nil { 52 | return 53 | } 54 | type x struct{} 55 | out := protoimpl.TypeBuilder{ 56 | File: protoimpl.DescBuilder{ 57 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 58 | RawDescriptor: file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawDesc, 59 | NumEnums: 0, 60 | NumMessages: 0, 61 | NumExtensions: 0, 62 | NumServices: 0, 63 | }, 64 | GoTypes: file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_goTypes, 65 | DependencyIndexes: file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_depIdxs, 66 | }.Build() 67 | File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto = out.File 68 | file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawDesc = nil 69 | file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_goTypes = nil 70 | file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_depIdxs = nil 71 | } 72 | -------------------------------------------------------------------------------- /regenerate.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 The Go Authors. All rights reserved. 3 | # Use of this source code is governed by a BSD-style 4 | # license that can be found in the LICENSE file. 5 | 6 | cd "$(git rev-parse --show-toplevel)" 7 | set -e 8 | go run ./internal/cmd/generate-alias -execute 9 | go test ./protoc-gen-go -regenerate 10 | -------------------------------------------------------------------------------- /test.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 The Go Authors. All rights reserved. 3 | # Use of this source code is governed by a BSD-style 4 | # license that can be found in the LICENSE file. 5 | 6 | cd "$(git rev-parse --show-toplevel)" 7 | 8 | BOLD="\x1b[1mRunning: " 9 | PASS="\x1b[32mPASS" 10 | FAIL="\x1b[31mFAIL" 11 | RESET="\x1b[0m" 12 | 13 | echo -e "${BOLD}go test ./...${RESET}" 14 | RET_TEST0=$(go test ./... | egrep -v "^(ok|[?])\s+") 15 | if [[ ! -z "$RET_TEST0" ]]; then echo "$RET_TEST0"; echo; fi 16 | 17 | echo -e "${BOLD}go test -tags purego ./...${RESET}" 18 | RET_TEST1=$(go test -tags purego ./... | egrep -v "^(ok|[?])\s+") 19 | if [[ ! -z "$RET_TEST1" ]]; then echo "$RET_TEST1"; echo; fi 20 | 21 | echo -e "${BOLD}go generate${RESET}" 22 | RET_GEN=$(go run ./internal/cmd/generate-alias 2>&1) 23 | if [[ ! -z "$RET_GEN" ]]; then echo "$RET_GEN"; echo; fi 24 | 25 | echo -e "${BOLD}go fmt${RESET}" 26 | RET_FMT=$(gofmt -d $(git ls-files *.go) 2>&1) 27 | if [[ ! -z "$RET_FMT" ]]; then echo "$RET_FMT"; echo; fi 28 | 29 | echo -e "${BOLD}git diff${RESET}" 30 | RET_DIFF=$(git diff --no-prefix HEAD 2>&1) 31 | if [[ ! -z "$RET_DIFF" ]]; then echo "$RET_DIFF"; echo; fi 32 | 33 | echo -e "${BOLD}git ls-files${RESET}" 34 | RET_FILES=$(git ls-files --others --exclude-standard 2>&1) 35 | if [[ ! -z "$RET_FILES" ]]; then echo "$RET_FILES"; echo; fi 36 | 37 | if [[ ! -z "$RET_TEST0" ]] || [[ ! -z "$RET_TEST1" ]] || [[ ! -z "$RET_GEN" ]] || [ ! -z "$RET_FMT" ] || [[ ! -z "$RET_DIFF" ]] || [[ ! -z "$RET_FILES" ]]; then 38 | echo -e "${FAIL}${RESET}"; exit 1 39 | else 40 | echo -e "${PASS}${RESET}"; exit 0 41 | fi 42 | --------------------------------------------------------------------------------