├── .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 | [](https://pkg.go.dev/mod/github.com/golang/protobuf)
4 | [](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 |
--------------------------------------------------------------------------------