From 09a7bd78ebc2332a9dd95a07b3e415e28fd5a2b7 Mon Sep 17 00:00:00 2001 From: sabban <15465465+sabban@users.noreply.github.com> Date: Wed, 19 Oct 2022 17:22:18 +0200 Subject: [PATCH] add vendored stuff --- go.mod | 1 + .../.github/ISSUE_TEMPLATE/bug_report.md | 20 + .../.github/ISSUE_TEMPLATE/feature_request.md | 17 + .../.github/ISSUE_TEMPLATE/question.md | 7 + .../.github/workflows/test.yml | 22 + pkg/golang-protobuf/.gitignore | 3 + pkg/golang-protobuf/AUTHORS | 3 + pkg/golang-protobuf/CONTRIBUTING.md | 30 + pkg/golang-protobuf/CONTRIBUTORS | 3 + pkg/golang-protobuf/LICENSE | 28 + pkg/golang-protobuf/README.md | 122 + pkg/golang-protobuf/descriptor/descriptor.go | 180 + .../descriptor/descriptor_test.go | 85 + pkg/golang-protobuf/go.mod | 9 + pkg/golang-protobuf/go.sum | 8 + .../internal/cmd/generate-alias/main.go | 132 + .../internal/gengogrpc/grpc.go | 398 ++ .../testprotos/jsonpb_proto/test2.pb.go | 1293 +++++ .../testprotos/jsonpb_proto/test2.proto | 155 + .../testprotos/jsonpb_proto/test3.pb.go | 378 ++ .../testprotos/jsonpb_proto/test3.proto | 44 + .../testprotos/proto2_proto/test.pb.go | 4356 +++++++++++++++++ .../testprotos/proto2_proto/test.proto | 485 ++ .../testprotos/proto3_proto/test.pb.go | 579 +++ .../testprotos/proto3_proto/test.proto | 72 + .../internal/testprotos/regenerate.bash | 17 + pkg/golang-protobuf/jsonpb/decode.go | 530 ++ pkg/golang-protobuf/jsonpb/encode.go | 559 +++ pkg/golang-protobuf/jsonpb/json.go | 69 + pkg/golang-protobuf/jsonpb/json_test.go | 1264 +++++ pkg/golang-protobuf/proto/buffer.go | 324 ++ pkg/golang-protobuf/proto/defaults.go | 63 + pkg/golang-protobuf/proto/deprecated.go | 113 + pkg/golang-protobuf/proto/discard.go | 58 + pkg/golang-protobuf/proto/discard_test.go | 115 + pkg/golang-protobuf/proto/extensions.go | 356 ++ pkg/golang-protobuf/proto/extensions_test.go | 645 +++ pkg/golang-protobuf/proto/properties.go | 306 ++ pkg/golang-protobuf/proto/proto.go | 167 + pkg/golang-protobuf/proto/proto_clone_test.go | 379 ++ pkg/golang-protobuf/proto/proto_equal_test.go | 218 + pkg/golang-protobuf/proto/proto_test.go | 2593 ++++++++++ pkg/golang-protobuf/proto/registry.go | 317 ++ pkg/golang-protobuf/proto/registry_test.go | 37 + pkg/golang-protobuf/proto/text_decode.go | 801 +++ pkg/golang-protobuf/proto/text_encode.go | 560 +++ pkg/golang-protobuf/proto/text_test.go | 1370 ++++++ pkg/golang-protobuf/proto/wire.go | 78 + pkg/golang-protobuf/proto/wrappers.go | 34 + .../protoc-gen-go/descriptor/descriptor.pb.go | 200 + .../protoc-gen-go/generator/generator.go | 2789 +++++++++++ .../generator/internal/remap/remap.go | 88 + .../generator/internal/remap/remap_test.go | 55 + .../protoc-gen-go/grpc/grpc.go | 521 ++ pkg/golang-protobuf/protoc-gen-go/main.go | 74 + .../protoc-gen-go/plugin/plugin.pb.go | 75 + pkg/golang-protobuf/ptypes/any.go | 179 + pkg/golang-protobuf/ptypes/any/any.pb.go | 62 + pkg/golang-protobuf/ptypes/any_test.go | 166 + pkg/golang-protobuf/ptypes/doc.go | 10 + pkg/golang-protobuf/ptypes/duration.go | 76 + .../ptypes/duration/duration.pb.go | 63 + pkg/golang-protobuf/ptypes/duration_test.go | 95 + pkg/golang-protobuf/ptypes/empty/empty.pb.go | 62 + .../ptypes/struct/struct.pb.go | 78 + pkg/golang-protobuf/ptypes/timestamp.go | 112 + .../ptypes/timestamp/timestamp.pb.go | 64 + pkg/golang-protobuf/ptypes/timestamp_test.go | 126 + .../ptypes/wrappers/wrappers.pb.go | 71 + pkg/golang-protobuf/regenerate.bash | 9 + pkg/golang-protobuf/test.bash | 41 + plugins/notifications/dummy/go.mod | 28 + plugins/notifications/dummy/go.sum | 169 + plugins/notifications/email/go.mod | 2 + plugins/notifications/http/go.mod | 2 + plugins/notifications/slack/go.mod | 2 + plugins/notifications/splunk/go.mod | 2 + 77 files changed, 24624 insertions(+) create mode 100644 pkg/golang-protobuf/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 pkg/golang-protobuf/.github/ISSUE_TEMPLATE/feature_request.md create mode 100644 pkg/golang-protobuf/.github/ISSUE_TEMPLATE/question.md create mode 100644 pkg/golang-protobuf/.github/workflows/test.yml create mode 100644 pkg/golang-protobuf/.gitignore create mode 100644 pkg/golang-protobuf/AUTHORS create mode 100644 pkg/golang-protobuf/CONTRIBUTING.md create mode 100644 pkg/golang-protobuf/CONTRIBUTORS create mode 100644 pkg/golang-protobuf/LICENSE create mode 100644 pkg/golang-protobuf/README.md create mode 100644 pkg/golang-protobuf/descriptor/descriptor.go create mode 100644 pkg/golang-protobuf/descriptor/descriptor_test.go create mode 100644 pkg/golang-protobuf/go.mod create mode 100644 pkg/golang-protobuf/go.sum create mode 100644 pkg/golang-protobuf/internal/cmd/generate-alias/main.go create mode 100644 pkg/golang-protobuf/internal/gengogrpc/grpc.go create mode 100644 pkg/golang-protobuf/internal/testprotos/jsonpb_proto/test2.pb.go create mode 100644 pkg/golang-protobuf/internal/testprotos/jsonpb_proto/test2.proto create mode 100644 pkg/golang-protobuf/internal/testprotos/jsonpb_proto/test3.pb.go create mode 100644 pkg/golang-protobuf/internal/testprotos/jsonpb_proto/test3.proto create mode 100644 pkg/golang-protobuf/internal/testprotos/proto2_proto/test.pb.go create mode 100644 pkg/golang-protobuf/internal/testprotos/proto2_proto/test.proto create mode 100644 pkg/golang-protobuf/internal/testprotos/proto3_proto/test.pb.go create mode 100644 pkg/golang-protobuf/internal/testprotos/proto3_proto/test.proto create mode 100755 pkg/golang-protobuf/internal/testprotos/regenerate.bash create mode 100644 pkg/golang-protobuf/jsonpb/decode.go create mode 100644 pkg/golang-protobuf/jsonpb/encode.go create mode 100644 pkg/golang-protobuf/jsonpb/json.go create mode 100644 pkg/golang-protobuf/jsonpb/json_test.go create mode 100644 pkg/golang-protobuf/proto/buffer.go create mode 100644 pkg/golang-protobuf/proto/defaults.go create mode 100644 pkg/golang-protobuf/proto/deprecated.go create mode 100644 pkg/golang-protobuf/proto/discard.go create mode 100644 pkg/golang-protobuf/proto/discard_test.go create mode 100644 pkg/golang-protobuf/proto/extensions.go create mode 100644 pkg/golang-protobuf/proto/extensions_test.go create mode 100644 pkg/golang-protobuf/proto/properties.go create mode 100644 pkg/golang-protobuf/proto/proto.go create mode 100644 pkg/golang-protobuf/proto/proto_clone_test.go create mode 100644 pkg/golang-protobuf/proto/proto_equal_test.go create mode 100644 pkg/golang-protobuf/proto/proto_test.go create mode 100644 pkg/golang-protobuf/proto/registry.go create mode 100644 pkg/golang-protobuf/proto/registry_test.go create mode 100644 pkg/golang-protobuf/proto/text_decode.go create mode 100644 pkg/golang-protobuf/proto/text_encode.go create mode 100644 pkg/golang-protobuf/proto/text_test.go create mode 100644 pkg/golang-protobuf/proto/wire.go create mode 100644 pkg/golang-protobuf/proto/wrappers.go create mode 100644 pkg/golang-protobuf/protoc-gen-go/descriptor/descriptor.pb.go create mode 100644 pkg/golang-protobuf/protoc-gen-go/generator/generator.go create mode 100644 pkg/golang-protobuf/protoc-gen-go/generator/internal/remap/remap.go create mode 100644 pkg/golang-protobuf/protoc-gen-go/generator/internal/remap/remap_test.go create mode 100644 pkg/golang-protobuf/protoc-gen-go/grpc/grpc.go create mode 100644 pkg/golang-protobuf/protoc-gen-go/main.go create mode 100644 pkg/golang-protobuf/protoc-gen-go/plugin/plugin.pb.go create mode 100644 pkg/golang-protobuf/ptypes/any.go create mode 100644 pkg/golang-protobuf/ptypes/any/any.pb.go create mode 100644 pkg/golang-protobuf/ptypes/any_test.go create mode 100644 pkg/golang-protobuf/ptypes/doc.go create mode 100644 pkg/golang-protobuf/ptypes/duration.go create mode 100644 pkg/golang-protobuf/ptypes/duration/duration.pb.go create mode 100644 pkg/golang-protobuf/ptypes/duration_test.go create mode 100644 pkg/golang-protobuf/ptypes/empty/empty.pb.go create mode 100644 pkg/golang-protobuf/ptypes/struct/struct.pb.go create mode 100644 pkg/golang-protobuf/ptypes/timestamp.go create mode 100644 pkg/golang-protobuf/ptypes/timestamp/timestamp.pb.go create mode 100644 pkg/golang-protobuf/ptypes/timestamp_test.go create mode 100644 pkg/golang-protobuf/ptypes/wrappers/wrappers.pb.go create mode 100755 pkg/golang-protobuf/regenerate.bash create mode 100755 pkg/golang-protobuf/test.bash create mode 100644 plugins/notifications/dummy/go.mod create mode 100644 plugins/notifications/dummy/go.sum diff --git a/go.mod b/go.mod index a1c4ed188..22068ca95 100644 --- a/go.mod +++ b/go.mod @@ -175,3 +175,4 @@ require ( ) replace golang.org/x/time/rate => github.com/crowdsecurity/crowdsec/pkg/time/rate v0.0.0 +replace github.com/golang/protobuf => pkg/golang-protobuf \ No newline at end of file diff --git a/pkg/golang-protobuf/.github/ISSUE_TEMPLATE/bug_report.md b/pkg/golang-protobuf/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..cb9fc37c8 --- /dev/null +++ b/pkg/golang-protobuf/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,20 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +**What version of protobuf and what language are you using?** +Version: (e.g., `v1.1.0`, `89a0c16f`, etc) + +**What did you do?** +If possible, provide a recipe for reproducing the error. +A complete runnable program is good with `.proto` and `.go` source code. + +**What did you expect to see?** + +**What did you see instead?** + +Make sure you include information that can help us debug (full error message, exception listing, stack trace, logs). + +**Anything else we should know about your project / environment?** diff --git a/pkg/golang-protobuf/.github/ISSUE_TEMPLATE/feature_request.md b/pkg/golang-protobuf/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..b904f1f84 --- /dev/null +++ b/pkg/golang-protobuf/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,17 @@ +--- +name: Feature request +about: Suggest an idea for this project + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/pkg/golang-protobuf/.github/ISSUE_TEMPLATE/question.md b/pkg/golang-protobuf/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 000000000..bfa6ddea8 --- /dev/null +++ b/pkg/golang-protobuf/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,7 @@ +--- +name: Question +about: Questions and troubleshooting + +--- + + diff --git a/pkg/golang-protobuf/.github/workflows/test.yml b/pkg/golang-protobuf/.github/workflows/test.yml new file mode 100644 index 000000000..bd97bd412 --- /dev/null +++ b/pkg/golang-protobuf/.github/workflows/test.yml @@ -0,0 +1,22 @@ +on: [push, pull_request] +name: Test +jobs: + test: + strategy: + matrix: + go-version: [1.11.x, 1.12.x, 1.13.x, 1.14.x, 1.15.x, 1.16.x] + os: [ubuntu-latest, macos-latest] + runs-on: ${{ matrix.os }} + steps: + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go-version }} + - name: Checkout code + uses: actions/checkout@v2 + - name: TestLatest + if: matrix.go-version == '1.16.x' + run: ./test.bash + - name: TestAll + if: matrix.go-version != '1.16.x' + run: go test ./... diff --git a/pkg/golang-protobuf/.gitignore b/pkg/golang-protobuf/.gitignore new file mode 100644 index 000000000..5c986d1c5 --- /dev/null +++ b/pkg/golang-protobuf/.gitignore @@ -0,0 +1,3 @@ +.cache +vendor +cmd/protoc-gen-go/protoc-gen-go diff --git a/pkg/golang-protobuf/AUTHORS b/pkg/golang-protobuf/AUTHORS new file mode 100644 index 000000000..15167cd74 --- /dev/null +++ b/pkg/golang-protobuf/AUTHORS @@ -0,0 +1,3 @@ +# This source code refers to The Go Authors for copyright purposes. +# The master list of authors is in the main Go distribution, +# visible at http://tip.golang.org/AUTHORS. diff --git a/pkg/golang-protobuf/CONTRIBUTING.md b/pkg/golang-protobuf/CONTRIBUTING.md new file mode 100644 index 000000000..83971cbbf --- /dev/null +++ b/pkg/golang-protobuf/CONTRIBUTING.md @@ -0,0 +1,30 @@ +# Contributing to Go Protocol Buffers + +Go protocol buffers is an open source project and accepts contributions. + +This project is the first major version of Go protobufs, +while the next major revision of this project is located at +[protocolbuffers/protobuf-go](https://github.com/protocolbuffers/protobuf-go). +Most new development effort is focused on the latter project, +and changes to this project is primarily reserved for bug fixes. + + +## Contributor License Agreement + +Contributions to this project must be accompanied by a Contributor License +Agreement. You (or your employer) retain the copyright to your contribution, +this simply gives us permission to use and redistribute your contributions as +part of the project. Head over to to see +your current agreements on file or to sign a new one. + +You generally only need to submit a CLA once, so if you've already submitted one +(even if it was for a different project), you probably don't need to do it +again. + + +## Code reviews + +All submissions, including submissions by project members, require review. We +use GitHub pull requests for this purpose. Consult +[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more +information on using pull requests. diff --git a/pkg/golang-protobuf/CONTRIBUTORS b/pkg/golang-protobuf/CONTRIBUTORS new file mode 100644 index 000000000..1c4577e96 --- /dev/null +++ b/pkg/golang-protobuf/CONTRIBUTORS @@ -0,0 +1,3 @@ +# This source code was written by the Go contributors. +# The master list of contributors is in the main Go distribution, +# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/pkg/golang-protobuf/LICENSE b/pkg/golang-protobuf/LICENSE new file mode 100644 index 000000000..0f646931a --- /dev/null +++ b/pkg/golang-protobuf/LICENSE @@ -0,0 +1,28 @@ +Copyright 2010 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/pkg/golang-protobuf/README.md b/pkg/golang-protobuf/README.md new file mode 100644 index 000000000..2e4233f20 --- /dev/null +++ b/pkg/golang-protobuf/README.md @@ -0,0 +1,122 @@ +# Go support for Protocol Buffers + +[![GoDev](https://img.shields.io/static/v1?label=godev&message=reference&color=00add8)](https://pkg.go.dev/mod/github.com/golang/protobuf) +[![Build Status](https://travis-ci.org/golang/protobuf.svg?branch=master)](https://travis-ci.org/golang/protobuf) + +This module +([`github.com/golang/protobuf`](https://pkg.go.dev/mod/github.com/golang/protobuf)) +contains Go bindings for protocol buffers. + +It has been superseded by the +[`google.golang.org/protobuf`](https://pkg.go.dev/mod/google.golang.org/protobuf) +module, which contains an updated and simplified API, +support for protobuf reflection, and many other improvements. +We recommend that new code use the `google.golang.org/protobuf` module. + +Versions v1.4 and later of `github.com/golang/protobuf` are implemented +in terms of `google.golang.org/protobuf`. +Programs which use both modules must use at least version v1.4 of this one. + +See the +[developer guide for protocol buffers in Go](https://developers.google.com/protocol-buffers/docs/gotutorial) +for a general guide for how to get started using protobufs in Go. + +See +[release note documentation](https://github.com/golang/protobuf/releases) +for more information about individual releases of this project. + +See +[documentation for the next major revision](https://pkg.go.dev/mod/google.golang.org/protobuf) +for more information about the purpose, usage, and history of this project. + +## Package index + +Summary of the packages provided by this module: + +* [`proto`](https://pkg.go.dev/github.com/golang/protobuf/proto): Package + `proto` provides functions operating on protobuf messages such as cloning, + merging, and checking equality, as well as binary serialization and text + serialization. +* [`jsonpb`](https://pkg.go.dev/github.com/golang/protobuf/jsonpb): Package + `jsonpb` serializes protobuf messages as JSON. +* [`ptypes`](https://pkg.go.dev/github.com/golang/protobuf/ptypes): Package + `ptypes` provides helper functionality for protobuf well-known types. +* [`ptypes/any`](https://pkg.go.dev/github.com/golang/protobuf/ptypes/any): + Package `any` is the generated package for `google/protobuf/any.proto`. +* [`ptypes/empty`](https://pkg.go.dev/github.com/golang/protobuf/ptypes/empty): + Package `empty` is the generated package for `google/protobuf/empty.proto`. +* [`ptypes/timestamp`](https://pkg.go.dev/github.com/golang/protobuf/ptypes/timestamp): + Package `timestamp` is the generated package for + `google/protobuf/timestamp.proto`. +* [`ptypes/duration`](https://pkg.go.dev/github.com/golang/protobuf/ptypes/duration): + Package `duration` is the generated package for + `google/protobuf/duration.proto`. +* [`ptypes/wrappers`](https://pkg.go.dev/github.com/golang/protobuf/ptypes/wrappers): + Package `wrappers` is the generated package for + `google/protobuf/wrappers.proto`. +* [`ptypes/struct`](https://pkg.go.dev/github.com/golang/protobuf/ptypes/struct): + Package `structpb` is the generated package for + `google/protobuf/struct.proto`. +* [`protoc-gen-go/descriptor`](https://pkg.go.dev/github.com/golang/protobuf/protoc-gen-go/descriptor): + Package `descriptor` is the generated package for + `google/protobuf/descriptor.proto`. +* [`protoc-gen-go/plugin`](https://pkg.go.dev/github.com/golang/protobuf/protoc-gen-go/plugin): + Package `plugin` is the generated package for + `google/protobuf/compiler/plugin.proto`. +* [`protoc-gen-go`](https://pkg.go.dev/github.com/golang/protobuf/protoc-gen-go): + The `protoc-gen-go` binary is a protoc plugin to generate a Go protocol + buffer package. + +## Reporting issues + +The issue tracker for this project +[is located here](https://github.com/golang/protobuf/issues). + +Please report any issues with a sufficient description of the bug or feature +request. Bug reports should ideally be accompanied by a minimal reproduction of +the issue. Irreproducible bugs are difficult to diagnose and fix (and likely to +be closed after some period of time). Bug reports must specify the version of +the +[Go protocol buffer module](https://github.com/protocolbuffers/protobuf-go/releases) +and also the version of the +[protocol buffer toolchain](https://github.com/protocolbuffers/protobuf/releases) +being used. + +## Contributing + +This project is open-source and accepts contributions. See the +[contribution guide](https://github.com/golang/protobuf/blob/master/CONTRIBUTING.md) +for more information. + +## Compatibility + +This module and the generated code are expected to be stable over time. However, +we reserve the right to make breaking changes without notice for the following +reasons: + +* **Security:** A security issue in the specification or implementation may + come to light whose resolution requires breaking compatibility. We reserve + the right to address such issues. +* **Unspecified behavior:** There are some aspects of the protocol buffer + specification that are undefined. Programs that depend on unspecified + behavior may break in future releases. +* **Specification changes:** It may become necessary to address an + inconsistency, incompleteness, or change in the protocol buffer + specification, which may affect the behavior of existing programs. We + reserve the right to address such changes. +* **Bugs:** If a package has a bug that violates correctness, a program + depending on the buggy behavior may break if the bug is fixed. We reserve + the right to fix such bugs. +* **Generated additions**: We reserve the right to add new declarations to + generated Go packages of `.proto` files. This includes declared constants, + variables, functions, types, fields in structs, and methods on types. This + may break attempts at injecting additional code on top of what is generated + by `protoc-gen-go`. Such practice is not supported by this project. +* **Internal changes**: We reserve the right to add, modify, and remove + internal code, which includes all unexported declarations, the + [`generator`](https://pkg.go.dev/github.com/golang/protobuf/protoc-gen-go/generator) + package, and all packages under + [`internal`](https://pkg.go.dev/github.com/golang/protobuf/internal). + +Any breaking changes outside of these will be announced 6 months in advance to +[protobuf@googlegroups.com](https://groups.google.com/forum/#!forum/protobuf). diff --git a/pkg/golang-protobuf/descriptor/descriptor.go b/pkg/golang-protobuf/descriptor/descriptor.go new file mode 100644 index 000000000..ffde8a650 --- /dev/null +++ b/pkg/golang-protobuf/descriptor/descriptor.go @@ -0,0 +1,180 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package descriptor provides functions for obtaining the protocol buffer +// descriptors of generated Go types. +// +// Deprecated: See the "google.golang.org/protobuf/reflect/protoreflect" package +// for how to obtain an EnumDescriptor or MessageDescriptor in order to +// programatically interact with the protobuf type system. +package descriptor + +import ( + "bytes" + "compress/gzip" + "io/ioutil" + "sync" + + "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/reflect/protodesc" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/runtime/protoimpl" + + descriptorpb "github.com/golang/protobuf/protoc-gen-go/descriptor" +) + +// Message is proto.Message with a method to return its descriptor. +// +// Deprecated: The Descriptor method may not be generated by future +// versions of protoc-gen-go, meaning that this interface may not +// be implemented by many concrete message types. +type Message interface { + proto.Message + Descriptor() ([]byte, []int) +} + +// ForMessage returns the file descriptor proto containing +// the message and the message descriptor proto for the message itself. +// The returned proto messages must not be mutated. +// +// Deprecated: Not all concrete message types satisfy the Message interface. +// Use MessageDescriptorProto instead. If possible, the calling code should +// be rewritten to use protobuf reflection instead. +// See package "google.golang.org/protobuf/reflect/protoreflect" for details. +func ForMessage(m Message) (*descriptorpb.FileDescriptorProto, *descriptorpb.DescriptorProto) { + return MessageDescriptorProto(m) +} + +type rawDesc struct { + fileDesc []byte + indexes []int +} + +var rawDescCache sync.Map // map[protoreflect.Descriptor]*rawDesc + +func deriveRawDescriptor(d protoreflect.Descriptor) ([]byte, []int) { + // Fast-path: check whether raw descriptors are already cached. + origDesc := d + if v, ok := rawDescCache.Load(origDesc); ok { + return v.(*rawDesc).fileDesc, v.(*rawDesc).indexes + } + + // Slow-path: derive the raw descriptor from the v2 descriptor. + + // Start with the leaf (a given enum or message declaration) and + // ascend upwards until we hit the parent file descriptor. + var idxs []int + for { + idxs = append(idxs, d.Index()) + d = d.Parent() + if d == nil { + // TODO: We could construct a FileDescriptor stub for standalone + // descriptors to satisfy the API. + return nil, nil + } + if _, ok := d.(protoreflect.FileDescriptor); ok { + break + } + } + + // Obtain the raw file descriptor. + fd := d.(protoreflect.FileDescriptor) + b, _ := proto.Marshal(protodesc.ToFileDescriptorProto(fd)) + file := protoimpl.X.CompressGZIP(b) + + // Reverse the indexes, since we populated it in reverse. + for i, j := 0, len(idxs)-1; i < j; i, j = i+1, j-1 { + idxs[i], idxs[j] = idxs[j], idxs[i] + } + + if v, ok := rawDescCache.LoadOrStore(origDesc, &rawDesc{file, idxs}); ok { + return v.(*rawDesc).fileDesc, v.(*rawDesc).indexes + } + return file, idxs +} + +// EnumRawDescriptor returns the GZIP'd raw file descriptor representing +// the enum and the index path to reach the enum declaration. +// The returned slices must not be mutated. +func EnumRawDescriptor(e proto.GeneratedEnum) ([]byte, []int) { + if ev, ok := e.(interface{ EnumDescriptor() ([]byte, []int) }); ok { + return ev.EnumDescriptor() + } + ed := protoimpl.X.EnumTypeOf(e) + return deriveRawDescriptor(ed.Descriptor()) +} + +// MessageRawDescriptor returns the GZIP'd raw file descriptor representing +// the message and the index path to reach the message declaration. +// The returned slices must not be mutated. +func MessageRawDescriptor(m proto.GeneratedMessage) ([]byte, []int) { + if mv, ok := m.(interface{ Descriptor() ([]byte, []int) }); ok { + return mv.Descriptor() + } + md := protoimpl.X.MessageTypeOf(m) + return deriveRawDescriptor(md.Descriptor()) +} + +var fileDescCache sync.Map // map[*byte]*descriptorpb.FileDescriptorProto + +func deriveFileDescriptor(rawDesc []byte) *descriptorpb.FileDescriptorProto { + // Fast-path: check whether descriptor protos are already cached. + if v, ok := fileDescCache.Load(&rawDesc[0]); ok { + return v.(*descriptorpb.FileDescriptorProto) + } + + // Slow-path: derive the descriptor proto from the GZIP'd message. + zr, err := gzip.NewReader(bytes.NewReader(rawDesc)) + if err != nil { + panic(err) + } + b, err := ioutil.ReadAll(zr) + if err != nil { + panic(err) + } + fd := new(descriptorpb.FileDescriptorProto) + if err := proto.Unmarshal(b, fd); err != nil { + panic(err) + } + if v, ok := fileDescCache.LoadOrStore(&rawDesc[0], fd); ok { + return v.(*descriptorpb.FileDescriptorProto) + } + return fd +} + +// EnumDescriptorProto returns the file descriptor proto representing +// the enum and the enum descriptor proto for the enum itself. +// The returned proto messages must not be mutated. +func EnumDescriptorProto(e proto.GeneratedEnum) (*descriptorpb.FileDescriptorProto, *descriptorpb.EnumDescriptorProto) { + rawDesc, idxs := EnumRawDescriptor(e) + if rawDesc == nil || idxs == nil { + return nil, nil + } + fd := deriveFileDescriptor(rawDesc) + if len(idxs) == 1 { + return fd, fd.EnumType[idxs[0]] + } + md := fd.MessageType[idxs[0]] + for _, i := range idxs[1 : len(idxs)-1] { + md = md.NestedType[i] + } + ed := md.EnumType[idxs[len(idxs)-1]] + return fd, ed +} + +// MessageDescriptorProto returns the file descriptor proto representing +// the message and the message descriptor proto for the message itself. +// The returned proto messages must not be mutated. +func MessageDescriptorProto(m proto.GeneratedMessage) (*descriptorpb.FileDescriptorProto, *descriptorpb.DescriptorProto) { + rawDesc, idxs := MessageRawDescriptor(m) + if rawDesc == nil || idxs == nil { + return nil, nil + } + fd := deriveFileDescriptor(rawDesc) + md := fd.MessageType[idxs[0]] + for _, i := range idxs[1:] { + md = md.NestedType[i] + } + return fd, md +} diff --git a/pkg/golang-protobuf/descriptor/descriptor_test.go b/pkg/golang-protobuf/descriptor/descriptor_test.go new file mode 100644 index 000000000..28083979c --- /dev/null +++ b/pkg/golang-protobuf/descriptor/descriptor_test.go @@ -0,0 +1,85 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package descriptor + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + "google.golang.org/protobuf/reflect/protoreflect" + + descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" +) + +func TestEnumDescriptor(t *testing.T) { + tests := []struct { + enum protoreflect.Enum + idxs []int + name string + }{{ + enum: descpb.FieldDescriptorProto_Type(0), + idxs: []int{ + new(descpb.FieldDescriptorProto).ProtoReflect().Descriptor().Index(), + new(descpb.FieldDescriptorProto_Type).Descriptor().Index(), + }, + name: "Type", + }, { + enum: descpb.FieldOptions_CType(0), + idxs: []int{ + new(descpb.FieldOptions).ProtoReflect().Descriptor().Index(), + new(descpb.FieldOptions_CType).Descriptor().Index(), + }, + name: "CType", + }} + + for _, tt := range tests { + e := struct{ protoreflect.Enum }{tt.enum} // v2-only enum + + _, idxs := EnumRawDescriptor(e) + if diff := cmp.Diff(tt.idxs, idxs); diff != "" { + t.Errorf("path index mismatch (-want +got):\n%v", diff) + } + + _, ed := EnumDescriptorProto(e) + if ed.GetName() != tt.name { + t.Errorf("mismatching enum name: got %v, want %v", ed.GetName(), tt.name) + } + } +} + +func TestMessageDescriptor(t *testing.T) { + tests := []struct { + message protoreflect.ProtoMessage + idxs []int + name string + }{{ + message: (*descpb.SourceCodeInfo_Location)(nil), + idxs: []int{ + new(descpb.SourceCodeInfo).ProtoReflect().Descriptor().Index(), + new(descpb.SourceCodeInfo_Location).ProtoReflect().Descriptor().Index(), + }, + name: "Location", + }, { + message: (*descpb.FileDescriptorProto)(nil), + idxs: []int{ + new(descpb.FileDescriptorProto).ProtoReflect().Descriptor().Index(), + }, + name: "FileDescriptorProto", + }} + + for _, tt := range tests { + m := struct{ protoreflect.ProtoMessage }{tt.message} // v2-only message + + _, idxs := MessageRawDescriptor(m) + if diff := cmp.Diff(tt.idxs, idxs); diff != "" { + t.Errorf("path index mismatch (-want +got):\n%v", diff) + } + + _, md := MessageDescriptorProto(m) + if md.GetName() != tt.name { + t.Errorf("mismatching message name: got %v, want %v", md.GetName(), tt.name) + } + } +} diff --git a/pkg/golang-protobuf/go.mod b/pkg/golang-protobuf/go.mod new file mode 100644 index 000000000..6cac17b11 --- /dev/null +++ b/pkg/golang-protobuf/go.mod @@ -0,0 +1,9 @@ +// Deprecated: Use the "google.golang.org/protobuf" module instead. +module github.com/golang/protobuf + +go 1.9 + +require ( + github.com/google/go-cmp v0.5.5 + google.golang.org/protobuf v1.26.0 +) diff --git a/pkg/golang-protobuf/go.sum b/pkg/golang-protobuf/go.sum new file mode 100644 index 000000000..20a6257f1 --- /dev/null +++ b/pkg/golang-protobuf/go.sum @@ -0,0 +1,8 @@ +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= diff --git a/pkg/golang-protobuf/internal/cmd/generate-alias/main.go b/pkg/golang-protobuf/internal/cmd/generate-alias/main.go new file mode 100644 index 000000000..6c16e6dc6 --- /dev/null +++ b/pkg/golang-protobuf/internal/cmd/generate-alias/main.go @@ -0,0 +1,132 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:generate go run . -execute + +package main + +import ( + "flag" + "fmt" + "io/ioutil" + "os" + "os/exec" + "path" + "path/filepath" + "strings" + + "github.com/golang/protobuf/proto" + gengo "google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo" + "google.golang.org/protobuf/compiler/protogen" + "google.golang.org/protobuf/reflect/protodesc" + "google.golang.org/protobuf/reflect/protoreflect" + + "google.golang.org/protobuf/types/descriptorpb" + "google.golang.org/protobuf/types/known/anypb" + "google.golang.org/protobuf/types/known/durationpb" + "google.golang.org/protobuf/types/known/emptypb" + "google.golang.org/protobuf/types/known/structpb" + "google.golang.org/protobuf/types/known/timestamppb" + "google.golang.org/protobuf/types/known/wrapperspb" + "google.golang.org/protobuf/types/pluginpb" +) + +func main() { + run := flag.Bool("execute", false, "Write generated files to destination.") + flag.Parse() + + // Set of generated proto packages to forward to v2. + files := []struct { + oldGoPkg string + newGoPkg string + pbDesc protoreflect.FileDescriptor + }{{ + oldGoPkg: "github.com/golang/protobuf/protoc-gen-go/descriptor;descriptor", + newGoPkg: "google.golang.org/protobuf/types/descriptorpb", + pbDesc: descriptorpb.File_google_protobuf_descriptor_proto, + }, { + oldGoPkg: "github.com/golang/protobuf/protoc-gen-go/plugin;plugin_go", + newGoPkg: "google.golang.org/protobuf/types/pluginpb", + pbDesc: pluginpb.File_google_protobuf_compiler_plugin_proto, + }, { + oldGoPkg: "github.com/golang/protobuf/ptypes/any;any", + newGoPkg: "google.golang.org/protobuf/types/known/anypb", + pbDesc: anypb.File_google_protobuf_any_proto, + }, { + oldGoPkg: "github.com/golang/protobuf/ptypes/duration;duration", + newGoPkg: "google.golang.org/protobuf/types/known/durationpb", + pbDesc: durationpb.File_google_protobuf_duration_proto, + }, { + oldGoPkg: "github.com/golang/protobuf/ptypes/timestamp;timestamp", + newGoPkg: "google.golang.org/protobuf/types/known/timestamppb", + pbDesc: timestamppb.File_google_protobuf_timestamp_proto, + }, { + oldGoPkg: "github.com/golang/protobuf/ptypes/wrappers;wrappers", + newGoPkg: "google.golang.org/protobuf/types/known/wrapperspb", + pbDesc: wrapperspb.File_google_protobuf_wrappers_proto, + }, { + oldGoPkg: "github.com/golang/protobuf/ptypes/struct;structpb", + newGoPkg: "google.golang.org/protobuf/types/known/structpb", + pbDesc: structpb.File_google_protobuf_struct_proto, + }, { + oldGoPkg: "github.com/golang/protobuf/ptypes/empty;empty", + newGoPkg: "google.golang.org/protobuf/types/known/emptypb", + pbDesc: emptypb.File_google_protobuf_empty_proto, + }} + + // For each package, construct a proto file that public imports the package. + var req pluginpb.CodeGeneratorRequest + var flags []string + for _, file := range files { + pkgPath := file.oldGoPkg[:strings.IndexByte(file.oldGoPkg, ';')] + fd := &descriptorpb.FileDescriptorProto{ + Name: proto.String(pkgPath + "/" + path.Base(pkgPath) + ".proto"), + Syntax: proto.String(file.pbDesc.Syntax().String()), + Dependency: []string{file.pbDesc.Path()}, + PublicDependency: []int32{0}, + Options: &descriptorpb.FileOptions{GoPackage: proto.String(file.oldGoPkg)}, + } + req.ProtoFile = append(req.ProtoFile, protodesc.ToFileDescriptorProto(file.pbDesc), fd) + req.FileToGenerate = append(req.FileToGenerate, fd.GetName()) + flags = append(flags, "M"+file.pbDesc.Path()+"="+file.newGoPkg) + } + req.Parameter = proto.String(strings.Join(flags, ",")) + + // Use the internal logic of protoc-gen-go to generate the files. + gen, err := protogen.Options{}.New(&req) + check(err) + for _, file := range gen.Files { + if file.Generate { + gengo.GenerateVersionMarkers = false + gengo.GenerateFile(gen, file) + } + } + + // Write the generated files. + resp := gen.Response() + if resp.Error != nil { + panic("gengo error: " + resp.GetError()) + } + for _, file := range resp.File { + relPath, err := filepath.Rel(filepath.FromSlash("github.com/golang/protobuf"), file.GetName()) + check(err) + + check(ioutil.WriteFile(relPath+".bak", []byte(file.GetContent()), 0664)) + if *run { + fmt.Println("#", relPath) + check(os.Rename(relPath+".bak", relPath)) + } else { + cmd := exec.Command("diff", relPath, relPath+".bak", "-N", "-u") + cmd.Stdout = os.Stdout + cmd.Run() + os.Remove(relPath + ".bak") // best-effort delete + } + } +} + +func check(err error) { + if err != nil { + panic(err) + } +} diff --git a/pkg/golang-protobuf/internal/gengogrpc/grpc.go b/pkg/golang-protobuf/internal/gengogrpc/grpc.go new file mode 100644 index 000000000..fd2f51d89 --- /dev/null +++ b/pkg/golang-protobuf/internal/gengogrpc/grpc.go @@ -0,0 +1,398 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package gengogrpc contains the gRPC code generator. +package gengogrpc + +import ( + "fmt" + "strconv" + "strings" + + "google.golang.org/protobuf/compiler/protogen" + + "google.golang.org/protobuf/types/descriptorpb" +) + +const ( + contextPackage = protogen.GoImportPath("context") + grpcPackage = protogen.GoImportPath("google.golang.org/grpc") + codesPackage = protogen.GoImportPath("google.golang.org/grpc/codes") + statusPackage = protogen.GoImportPath("google.golang.org/grpc/status") +) + +// GenerateFile generates a _grpc.pb.go file containing gRPC service definitions. +func GenerateFile(gen *protogen.Plugin, file *protogen.File) *protogen.GeneratedFile { + if len(file.Services) == 0 { + return nil + } + filename := file.GeneratedFilenamePrefix + "_grpc.pb.go" + g := gen.NewGeneratedFile(filename, file.GoImportPath) + g.P("// Code generated by protoc-gen-go-grpc. DO NOT EDIT.") + g.P() + g.P("package ", file.GoPackageName) + g.P() + GenerateFileContent(gen, file, g) + return g +} + +// GenerateFileContent generates the gRPC service definitions, excluding the package statement. +func GenerateFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile) { + if len(file.Services) == 0 { + return + } + + // TODO: Remove this. We don't need to include these references any more. + g.P("// Reference imports to suppress errors if they are not otherwise used.") + g.P("var _ ", contextPackage.Ident("Context")) + g.P("var _ ", grpcPackage.Ident("ClientConnInterface")) + g.P() + + g.P("// This is a compile-time assertion to ensure that this generated file") + g.P("// is compatible with the grpc package it is being compiled against.") + g.P("const _ = ", grpcPackage.Ident("SupportPackageIsVersion6")) + g.P() + for _, service := range file.Services { + genService(gen, file, g, service) + } +} + +func genService(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, service *protogen.Service) { + clientName := service.GoName + "Client" + + g.P("// ", clientName, " is the client API for ", service.GoName, " service.") + g.P("//") + g.P("// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.") + + // Client interface. + if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() { + g.P("//") + g.P(deprecationComment) + } + g.Annotate(clientName, service.Location) + g.P("type ", clientName, " interface {") + for _, method := range service.Methods { + g.Annotate(clientName+"."+method.GoName, method.Location) + if method.Desc.Options().(*descriptorpb.MethodOptions).GetDeprecated() { + g.P(deprecationComment) + } + g.P(method.Comments.Leading, + clientSignature(g, method)) + } + g.P("}") + g.P() + + // Client structure. + g.P("type ", unexport(clientName), " struct {") + g.P("cc ", grpcPackage.Ident("ClientConnInterface")) + g.P("}") + g.P() + + // NewClient factory. + if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() { + g.P(deprecationComment) + } + g.P("func New", clientName, " (cc ", grpcPackage.Ident("ClientConnInterface"), ") ", clientName, " {") + g.P("return &", unexport(clientName), "{cc}") + g.P("}") + g.P() + + var methodIndex, streamIndex int + // Client method implementations. + for _, method := range service.Methods { + if !method.Desc.IsStreamingServer() && !method.Desc.IsStreamingClient() { + // Unary RPC method + genClientMethod(gen, file, g, method, methodIndex) + methodIndex++ + } else { + // Streaming RPC method + genClientMethod(gen, file, g, method, streamIndex) + streamIndex++ + } + } + + // Server interface. + serverType := service.GoName + "Server" + g.P("// ", serverType, " is the server API for ", service.GoName, " service.") + if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() { + g.P("//") + g.P(deprecationComment) + } + g.Annotate(serverType, service.Location) + g.P("type ", serverType, " interface {") + for _, method := range service.Methods { + g.Annotate(serverType+"."+method.GoName, method.Location) + if method.Desc.Options().(*descriptorpb.MethodOptions).GetDeprecated() { + g.P(deprecationComment) + } + g.P(method.Comments.Leading, + serverSignature(g, method)) + } + g.P("}") + g.P() + + // Server Unimplemented struct for forward compatibility. + g.P("// Unimplemented", serverType, " can be embedded to have forward compatible implementations.") + g.P("type Unimplemented", serverType, " struct {") + g.P("}") + g.P() + for _, method := range service.Methods { + nilArg := "" + if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { + nilArg = "nil," + } + g.P("func (*Unimplemented", serverType, ") ", serverSignature(g, method), "{") + g.P("return ", nilArg, statusPackage.Ident("Errorf"), "(", codesPackage.Ident("Unimplemented"), `, "method `, method.GoName, ` not implemented")`) + g.P("}") + } + g.P() + + // Server registration. + if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() { + g.P(deprecationComment) + } + serviceDescVar := "_" + service.GoName + "_serviceDesc" + g.P("func Register", service.GoName, "Server(s *", grpcPackage.Ident("Server"), ", srv ", serverType, ") {") + g.P("s.RegisterService(&", serviceDescVar, `, srv)`) + g.P("}") + g.P() + + // Server handler implementations. + var handlerNames []string + for _, method := range service.Methods { + hname := genServerMethod(gen, file, g, method) + handlerNames = append(handlerNames, hname) + } + + // Service descriptor. + g.P("var ", serviceDescVar, " = ", grpcPackage.Ident("ServiceDesc"), " {") + g.P("ServiceName: ", strconv.Quote(string(service.Desc.FullName())), ",") + g.P("HandlerType: (*", serverType, ")(nil),") + g.P("Methods: []", grpcPackage.Ident("MethodDesc"), "{") + for i, method := range service.Methods { + if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() { + continue + } + g.P("{") + g.P("MethodName: ", strconv.Quote(string(method.Desc.Name())), ",") + g.P("Handler: ", handlerNames[i], ",") + g.P("},") + } + g.P("},") + g.P("Streams: []", grpcPackage.Ident("StreamDesc"), "{") + for i, method := range service.Methods { + if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { + continue + } + g.P("{") + g.P("StreamName: ", strconv.Quote(string(method.Desc.Name())), ",") + g.P("Handler: ", handlerNames[i], ",") + if method.Desc.IsStreamingServer() { + g.P("ServerStreams: true,") + } + if method.Desc.IsStreamingClient() { + g.P("ClientStreams: true,") + } + g.P("},") + } + g.P("},") + g.P("Metadata: \"", file.Desc.Path(), "\",") + g.P("}") + g.P() +} + +func clientSignature(g *protogen.GeneratedFile, method *protogen.Method) string { + s := method.GoName + "(ctx " + g.QualifiedGoIdent(contextPackage.Ident("Context")) + if !method.Desc.IsStreamingClient() { + s += ", in *" + g.QualifiedGoIdent(method.Input.GoIdent) + } + s += ", opts ..." + g.QualifiedGoIdent(grpcPackage.Ident("CallOption")) + ") (" + if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { + s += "*" + g.QualifiedGoIdent(method.Output.GoIdent) + } else { + s += method.Parent.GoName + "_" + method.GoName + "Client" + } + s += ", error)" + return s +} + +func genClientMethod(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, method *protogen.Method, index int) { + service := method.Parent + sname := fmt.Sprintf("/%s/%s", service.Desc.FullName(), method.Desc.Name()) + + if method.Desc.Options().(*descriptorpb.MethodOptions).GetDeprecated() { + g.P(deprecationComment) + } + g.P("func (c *", unexport(service.GoName), "Client) ", clientSignature(g, method), "{") + if !method.Desc.IsStreamingServer() && !method.Desc.IsStreamingClient() { + g.P("out := new(", method.Output.GoIdent, ")") + g.P(`err := c.cc.Invoke(ctx, "`, sname, `", in, out, opts...)`) + g.P("if err != nil { return nil, err }") + g.P("return out, nil") + g.P("}") + g.P() + return + } + streamType := unexport(service.GoName) + method.GoName + "Client" + serviceDescVar := "_" + service.GoName + "_serviceDesc" + g.P("stream, err := c.cc.NewStream(ctx, &", serviceDescVar, ".Streams[", index, `], "`, sname, `", opts...)`) + g.P("if err != nil { return nil, err }") + g.P("x := &", streamType, "{stream}") + if !method.Desc.IsStreamingClient() { + g.P("if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }") + g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }") + } + g.P("return x, nil") + g.P("}") + g.P() + + genSend := method.Desc.IsStreamingClient() + genRecv := method.Desc.IsStreamingServer() + genCloseAndRecv := !method.Desc.IsStreamingServer() + + // Stream auxiliary types and methods. + g.P("type ", service.GoName, "_", method.GoName, "Client interface {") + if genSend { + g.P("Send(*", method.Input.GoIdent, ") error") + } + if genRecv { + g.P("Recv() (*", method.Output.GoIdent, ", error)") + } + if genCloseAndRecv { + g.P("CloseAndRecv() (*", method.Output.GoIdent, ", error)") + } + g.P(grpcPackage.Ident("ClientStream")) + g.P("}") + g.P() + + g.P("type ", streamType, " struct {") + g.P(grpcPackage.Ident("ClientStream")) + g.P("}") + g.P() + + if genSend { + g.P("func (x *", streamType, ") Send(m *", method.Input.GoIdent, ") error {") + g.P("return x.ClientStream.SendMsg(m)") + g.P("}") + g.P() + } + if genRecv { + g.P("func (x *", streamType, ") Recv() (*", method.Output.GoIdent, ", error) {") + g.P("m := new(", method.Output.GoIdent, ")") + g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }") + g.P("return m, nil") + g.P("}") + g.P() + } + if genCloseAndRecv { + g.P("func (x *", streamType, ") CloseAndRecv() (*", method.Output.GoIdent, ", error) {") + g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }") + g.P("m := new(", method.Output.GoIdent, ")") + g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }") + g.P("return m, nil") + g.P("}") + g.P() + } +} + +func serverSignature(g *protogen.GeneratedFile, method *protogen.Method) string { + var reqArgs []string + ret := "error" + if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { + reqArgs = append(reqArgs, g.QualifiedGoIdent(contextPackage.Ident("Context"))) + ret = "(*" + g.QualifiedGoIdent(method.Output.GoIdent) + ", error)" + } + if !method.Desc.IsStreamingClient() { + reqArgs = append(reqArgs, "*"+g.QualifiedGoIdent(method.Input.GoIdent)) + } + if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() { + reqArgs = append(reqArgs, method.Parent.GoName+"_"+method.GoName+"Server") + } + return method.GoName + "(" + strings.Join(reqArgs, ", ") + ") " + ret +} + +func genServerMethod(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, method *protogen.Method) string { + service := method.Parent + hname := fmt.Sprintf("_%s_%s_Handler", service.GoName, method.GoName) + + if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { + g.P("func ", hname, "(srv interface{}, ctx ", contextPackage.Ident("Context"), ", dec func(interface{}) error, interceptor ", grpcPackage.Ident("UnaryServerInterceptor"), ") (interface{}, error) {") + g.P("in := new(", method.Input.GoIdent, ")") + g.P("if err := dec(in); err != nil { return nil, err }") + g.P("if interceptor == nil { return srv.(", service.GoName, "Server).", method.GoName, "(ctx, in) }") + g.P("info := &", grpcPackage.Ident("UnaryServerInfo"), "{") + g.P("Server: srv,") + g.P("FullMethod: ", strconv.Quote(fmt.Sprintf("/%s/%s", service.Desc.FullName(), method.GoName)), ",") + g.P("}") + g.P("handler := func(ctx ", contextPackage.Ident("Context"), ", req interface{}) (interface{}, error) {") + g.P("return srv.(", service.GoName, "Server).", method.GoName, "(ctx, req.(*", method.Input.GoIdent, "))") + g.P("}") + g.P("return interceptor(ctx, in, info, handler)") + g.P("}") + g.P() + return hname + } + streamType := unexport(service.GoName) + method.GoName + "Server" + g.P("func ", hname, "(srv interface{}, stream ", grpcPackage.Ident("ServerStream"), ") error {") + if !method.Desc.IsStreamingClient() { + g.P("m := new(", method.Input.GoIdent, ")") + g.P("if err := stream.RecvMsg(m); err != nil { return err }") + g.P("return srv.(", service.GoName, "Server).", method.GoName, "(m, &", streamType, "{stream})") + } else { + g.P("return srv.(", service.GoName, "Server).", method.GoName, "(&", streamType, "{stream})") + } + g.P("}") + g.P() + + genSend := method.Desc.IsStreamingServer() + genSendAndClose := !method.Desc.IsStreamingServer() + genRecv := method.Desc.IsStreamingClient() + + // Stream auxiliary types and methods. + g.P("type ", service.GoName, "_", method.GoName, "Server interface {") + if genSend { + g.P("Send(*", method.Output.GoIdent, ") error") + } + if genSendAndClose { + g.P("SendAndClose(*", method.Output.GoIdent, ") error") + } + if genRecv { + g.P("Recv() (*", method.Input.GoIdent, ", error)") + } + g.P(grpcPackage.Ident("ServerStream")) + g.P("}") + g.P() + + g.P("type ", streamType, " struct {") + g.P(grpcPackage.Ident("ServerStream")) + g.P("}") + g.P() + + if genSend { + g.P("func (x *", streamType, ") Send(m *", method.Output.GoIdent, ") error {") + g.P("return x.ServerStream.SendMsg(m)") + g.P("}") + g.P() + } + if genSendAndClose { + g.P("func (x *", streamType, ") SendAndClose(m *", method.Output.GoIdent, ") error {") + g.P("return x.ServerStream.SendMsg(m)") + g.P("}") + g.P() + } + if genRecv { + g.P("func (x *", streamType, ") Recv() (*", method.Input.GoIdent, ", error) {") + g.P("m := new(", method.Input.GoIdent, ")") + g.P("if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }") + g.P("return m, nil") + g.P("}") + g.P() + } + + return hname +} + +const deprecationComment = "// Deprecated: Do not use." + +func unexport(s string) string { return strings.ToLower(s[:1]) + s[1:] } diff --git a/pkg/golang-protobuf/internal/testprotos/jsonpb_proto/test2.pb.go b/pkg/golang-protobuf/internal/testprotos/jsonpb_proto/test2.pb.go new file mode 100644 index 000000000..1dc0f8a03 --- /dev/null +++ b/pkg/golang-protobuf/internal/testprotos/jsonpb_proto/test2.pb.go @@ -0,0 +1,1293 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: jsonpb_proto/test2.proto + +package jsonpb_proto + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + anypb "google.golang.org/protobuf/types/known/anypb" + durationpb "google.golang.org/protobuf/types/known/durationpb" + structpb "google.golang.org/protobuf/types/known/structpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type Widget_Color int32 + +const ( + Widget_RED Widget_Color = 0 + Widget_GREEN Widget_Color = 1 + Widget_BLUE Widget_Color = 2 +) + +var Widget_Color_name = map[int32]string{ + 0: "RED", + 1: "GREEN", + 2: "BLUE", +} + +var Widget_Color_value = map[string]int32{ + "RED": 0, + "GREEN": 1, + "BLUE": 2, +} + +func (x Widget_Color) Enum() *Widget_Color { + p := new(Widget_Color) + *p = x + return p +} + +func (x Widget_Color) String() string { + return proto.EnumName(Widget_Color_name, int32(x)) +} + +func (x *Widget_Color) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Widget_Color_value, data, "Widget_Color") + if err != nil { + return err + } + *x = Widget_Color(value) + return nil +} + +func (Widget_Color) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_50cab1d8463dea41, []int{3, 0} +} + +// Test message for holding primitive types. +type Simple struct { + OBool *bool `protobuf:"varint,1,opt,name=o_bool,json=oBool" json:"o_bool,omitempty"` + OInt32 *int32 `protobuf:"varint,2,opt,name=o_int32,json=oInt32" json:"o_int32,omitempty"` + OInt32Str *int32 `protobuf:"varint,3,opt,name=o_int32_str,json=oInt32Str" json:"o_int32_str,omitempty"` + OInt64 *int64 `protobuf:"varint,4,opt,name=o_int64,json=oInt64" json:"o_int64,omitempty"` + OInt64Str *int64 `protobuf:"varint,5,opt,name=o_int64_str,json=oInt64Str" json:"o_int64_str,omitempty"` + OUint32 *uint32 `protobuf:"varint,6,opt,name=o_uint32,json=oUint32" json:"o_uint32,omitempty"` + OUint32Str *uint32 `protobuf:"varint,7,opt,name=o_uint32_str,json=oUint32Str" json:"o_uint32_str,omitempty"` + OUint64 *uint64 `protobuf:"varint,8,opt,name=o_uint64,json=oUint64" json:"o_uint64,omitempty"` + OUint64Str *uint64 `protobuf:"varint,9,opt,name=o_uint64_str,json=oUint64Str" json:"o_uint64_str,omitempty"` + OSint32 *int32 `protobuf:"zigzag32,10,opt,name=o_sint32,json=oSint32" json:"o_sint32,omitempty"` + OSint32Str *int32 `protobuf:"zigzag32,11,opt,name=o_sint32_str,json=oSint32Str" json:"o_sint32_str,omitempty"` + OSint64 *int64 `protobuf:"zigzag64,12,opt,name=o_sint64,json=oSint64" json:"o_sint64,omitempty"` + OSint64Str *int64 `protobuf:"zigzag64,13,opt,name=o_sint64_str,json=oSint64Str" json:"o_sint64_str,omitempty"` + OFloat *float32 `protobuf:"fixed32,14,opt,name=o_float,json=oFloat" json:"o_float,omitempty"` + OFloatStr *float32 `protobuf:"fixed32,15,opt,name=o_float_str,json=oFloatStr" json:"o_float_str,omitempty"` + ODouble *float64 `protobuf:"fixed64,16,opt,name=o_double,json=oDouble" json:"o_double,omitempty"` + ODoubleStr *float64 `protobuf:"fixed64,17,opt,name=o_double_str,json=oDoubleStr" json:"o_double_str,omitempty"` + OString *string `protobuf:"bytes,18,opt,name=o_string,json=oString" json:"o_string,omitempty"` + OBytes []byte `protobuf:"bytes,19,opt,name=o_bytes,json=oBytes" json:"o_bytes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Simple) Reset() { *m = Simple{} } +func (m *Simple) String() string { return proto.CompactTextString(m) } +func (*Simple) ProtoMessage() {} +func (*Simple) Descriptor() ([]byte, []int) { + return fileDescriptor_50cab1d8463dea41, []int{0} +} + +func (m *Simple) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Simple.Unmarshal(m, b) +} +func (m *Simple) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Simple.Marshal(b, m, deterministic) +} +func (m *Simple) XXX_Merge(src proto.Message) { + xxx_messageInfo_Simple.Merge(m, src) +} +func (m *Simple) XXX_Size() int { + return xxx_messageInfo_Simple.Size(m) +} +func (m *Simple) XXX_DiscardUnknown() { + xxx_messageInfo_Simple.DiscardUnknown(m) +} + +var xxx_messageInfo_Simple proto.InternalMessageInfo + +func (m *Simple) GetOBool() bool { + if m != nil && m.OBool != nil { + return *m.OBool + } + return false +} + +func (m *Simple) GetOInt32() int32 { + if m != nil && m.OInt32 != nil { + return *m.OInt32 + } + return 0 +} + +func (m *Simple) GetOInt32Str() int32 { + if m != nil && m.OInt32Str != nil { + return *m.OInt32Str + } + return 0 +} + +func (m *Simple) GetOInt64() int64 { + if m != nil && m.OInt64 != nil { + return *m.OInt64 + } + return 0 +} + +func (m *Simple) GetOInt64Str() int64 { + if m != nil && m.OInt64Str != nil { + return *m.OInt64Str + } + return 0 +} + +func (m *Simple) GetOUint32() uint32 { + if m != nil && m.OUint32 != nil { + return *m.OUint32 + } + return 0 +} + +func (m *Simple) GetOUint32Str() uint32 { + if m != nil && m.OUint32Str != nil { + return *m.OUint32Str + } + return 0 +} + +func (m *Simple) GetOUint64() uint64 { + if m != nil && m.OUint64 != nil { + return *m.OUint64 + } + return 0 +} + +func (m *Simple) GetOUint64Str() uint64 { + if m != nil && m.OUint64Str != nil { + return *m.OUint64Str + } + return 0 +} + +func (m *Simple) GetOSint32() int32 { + if m != nil && m.OSint32 != nil { + return *m.OSint32 + } + return 0 +} + +func (m *Simple) GetOSint32Str() int32 { + if m != nil && m.OSint32Str != nil { + return *m.OSint32Str + } + return 0 +} + +func (m *Simple) GetOSint64() int64 { + if m != nil && m.OSint64 != nil { + return *m.OSint64 + } + return 0 +} + +func (m *Simple) GetOSint64Str() int64 { + if m != nil && m.OSint64Str != nil { + return *m.OSint64Str + } + return 0 +} + +func (m *Simple) GetOFloat() float32 { + if m != nil && m.OFloat != nil { + return *m.OFloat + } + return 0 +} + +func (m *Simple) GetOFloatStr() float32 { + if m != nil && m.OFloatStr != nil { + return *m.OFloatStr + } + return 0 +} + +func (m *Simple) GetODouble() float64 { + if m != nil && m.ODouble != nil { + return *m.ODouble + } + return 0 +} + +func (m *Simple) GetODoubleStr() float64 { + if m != nil && m.ODoubleStr != nil { + return *m.ODoubleStr + } + return 0 +} + +func (m *Simple) GetOString() string { + if m != nil && m.OString != nil { + return *m.OString + } + return "" +} + +func (m *Simple) GetOBytes() []byte { + if m != nil { + return m.OBytes + } + return nil +} + +// Test message for holding special non-finites primitives. +type NonFinites struct { + FNan *float32 `protobuf:"fixed32,1,opt,name=f_nan,json=fNan" json:"f_nan,omitempty"` + FPinf *float32 `protobuf:"fixed32,2,opt,name=f_pinf,json=fPinf" json:"f_pinf,omitempty"` + FNinf *float32 `protobuf:"fixed32,3,opt,name=f_ninf,json=fNinf" json:"f_ninf,omitempty"` + DNan *float64 `protobuf:"fixed64,4,opt,name=d_nan,json=dNan" json:"d_nan,omitempty"` + DPinf *float64 `protobuf:"fixed64,5,opt,name=d_pinf,json=dPinf" json:"d_pinf,omitempty"` + DNinf *float64 `protobuf:"fixed64,6,opt,name=d_ninf,json=dNinf" json:"d_ninf,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *NonFinites) Reset() { *m = NonFinites{} } +func (m *NonFinites) String() string { return proto.CompactTextString(m) } +func (*NonFinites) ProtoMessage() {} +func (*NonFinites) Descriptor() ([]byte, []int) { + return fileDescriptor_50cab1d8463dea41, []int{1} +} + +func (m *NonFinites) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_NonFinites.Unmarshal(m, b) +} +func (m *NonFinites) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_NonFinites.Marshal(b, m, deterministic) +} +func (m *NonFinites) XXX_Merge(src proto.Message) { + xxx_messageInfo_NonFinites.Merge(m, src) +} +func (m *NonFinites) XXX_Size() int { + return xxx_messageInfo_NonFinites.Size(m) +} +func (m *NonFinites) XXX_DiscardUnknown() { + xxx_messageInfo_NonFinites.DiscardUnknown(m) +} + +var xxx_messageInfo_NonFinites proto.InternalMessageInfo + +func (m *NonFinites) GetFNan() float32 { + if m != nil && m.FNan != nil { + return *m.FNan + } + return 0 +} + +func (m *NonFinites) GetFPinf() float32 { + if m != nil && m.FPinf != nil { + return *m.FPinf + } + return 0 +} + +func (m *NonFinites) GetFNinf() float32 { + if m != nil && m.FNinf != nil { + return *m.FNinf + } + return 0 +} + +func (m *NonFinites) GetDNan() float64 { + if m != nil && m.DNan != nil { + return *m.DNan + } + return 0 +} + +func (m *NonFinites) GetDPinf() float64 { + if m != nil && m.DPinf != nil { + return *m.DPinf + } + return 0 +} + +func (m *NonFinites) GetDNinf() float64 { + if m != nil && m.DNinf != nil { + return *m.DNinf + } + return 0 +} + +// Test message for holding repeated primitives. +type Repeats struct { + RBool []bool `protobuf:"varint,1,rep,name=r_bool,json=rBool" json:"r_bool,omitempty"` + RInt32 []int32 `protobuf:"varint,2,rep,name=r_int32,json=rInt32" json:"r_int32,omitempty"` + RInt64 []int64 `protobuf:"varint,3,rep,name=r_int64,json=rInt64" json:"r_int64,omitempty"` + RUint32 []uint32 `protobuf:"varint,4,rep,name=r_uint32,json=rUint32" json:"r_uint32,omitempty"` + RUint64 []uint64 `protobuf:"varint,5,rep,name=r_uint64,json=rUint64" json:"r_uint64,omitempty"` + RSint32 []int32 `protobuf:"zigzag32,6,rep,name=r_sint32,json=rSint32" json:"r_sint32,omitempty"` + RSint64 []int64 `protobuf:"zigzag64,7,rep,name=r_sint64,json=rSint64" json:"r_sint64,omitempty"` + RFloat []float32 `protobuf:"fixed32,8,rep,name=r_float,json=rFloat" json:"r_float,omitempty"` + RDouble []float64 `protobuf:"fixed64,9,rep,name=r_double,json=rDouble" json:"r_double,omitempty"` + RString []string `protobuf:"bytes,10,rep,name=r_string,json=rString" json:"r_string,omitempty"` + RBytes [][]byte `protobuf:"bytes,11,rep,name=r_bytes,json=rBytes" json:"r_bytes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Repeats) Reset() { *m = Repeats{} } +func (m *Repeats) String() string { return proto.CompactTextString(m) } +func (*Repeats) ProtoMessage() {} +func (*Repeats) Descriptor() ([]byte, []int) { + return fileDescriptor_50cab1d8463dea41, []int{2} +} + +func (m *Repeats) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Repeats.Unmarshal(m, b) +} +func (m *Repeats) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Repeats.Marshal(b, m, deterministic) +} +func (m *Repeats) XXX_Merge(src proto.Message) { + xxx_messageInfo_Repeats.Merge(m, src) +} +func (m *Repeats) XXX_Size() int { + return xxx_messageInfo_Repeats.Size(m) +} +func (m *Repeats) XXX_DiscardUnknown() { + xxx_messageInfo_Repeats.DiscardUnknown(m) +} + +var xxx_messageInfo_Repeats proto.InternalMessageInfo + +func (m *Repeats) GetRBool() []bool { + if m != nil { + return m.RBool + } + return nil +} + +func (m *Repeats) GetRInt32() []int32 { + if m != nil { + return m.RInt32 + } + return nil +} + +func (m *Repeats) GetRInt64() []int64 { + if m != nil { + return m.RInt64 + } + return nil +} + +func (m *Repeats) GetRUint32() []uint32 { + if m != nil { + return m.RUint32 + } + return nil +} + +func (m *Repeats) GetRUint64() []uint64 { + if m != nil { + return m.RUint64 + } + return nil +} + +func (m *Repeats) GetRSint32() []int32 { + if m != nil { + return m.RSint32 + } + return nil +} + +func (m *Repeats) GetRSint64() []int64 { + if m != nil { + return m.RSint64 + } + return nil +} + +func (m *Repeats) GetRFloat() []float32 { + if m != nil { + return m.RFloat + } + return nil +} + +func (m *Repeats) GetRDouble() []float64 { + if m != nil { + return m.RDouble + } + return nil +} + +func (m *Repeats) GetRString() []string { + if m != nil { + return m.RString + } + return nil +} + +func (m *Repeats) GetRBytes() [][]byte { + if m != nil { + return m.RBytes + } + return nil +} + +// Test message for holding enums and nested messages. +type Widget struct { + Color *Widget_Color `protobuf:"varint,1,opt,name=color,enum=jsonpb_test.Widget_Color" json:"color,omitempty"` + RColor []Widget_Color `protobuf:"varint,2,rep,name=r_color,json=rColor,enum=jsonpb_test.Widget_Color" json:"r_color,omitempty"` + Simple *Simple `protobuf:"bytes,10,opt,name=simple" json:"simple,omitempty"` + RSimple []*Simple `protobuf:"bytes,11,rep,name=r_simple,json=rSimple" json:"r_simple,omitempty"` + Repeats *Repeats `protobuf:"bytes,20,opt,name=repeats" json:"repeats,omitempty"` + RRepeats []*Repeats `protobuf:"bytes,21,rep,name=r_repeats,json=rRepeats" json:"r_repeats,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Widget) Reset() { *m = Widget{} } +func (m *Widget) String() string { return proto.CompactTextString(m) } +func (*Widget) ProtoMessage() {} +func (*Widget) Descriptor() ([]byte, []int) { + return fileDescriptor_50cab1d8463dea41, []int{3} +} + +func (m *Widget) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Widget.Unmarshal(m, b) +} +func (m *Widget) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Widget.Marshal(b, m, deterministic) +} +func (m *Widget) XXX_Merge(src proto.Message) { + xxx_messageInfo_Widget.Merge(m, src) +} +func (m *Widget) XXX_Size() int { + return xxx_messageInfo_Widget.Size(m) +} +func (m *Widget) XXX_DiscardUnknown() { + xxx_messageInfo_Widget.DiscardUnknown(m) +} + +var xxx_messageInfo_Widget proto.InternalMessageInfo + +func (m *Widget) GetColor() Widget_Color { + if m != nil && m.Color != nil { + return *m.Color + } + return Widget_RED +} + +func (m *Widget) GetRColor() []Widget_Color { + if m != nil { + return m.RColor + } + return nil +} + +func (m *Widget) GetSimple() *Simple { + if m != nil { + return m.Simple + } + return nil +} + +func (m *Widget) GetRSimple() []*Simple { + if m != nil { + return m.RSimple + } + return nil +} + +func (m *Widget) GetRepeats() *Repeats { + if m != nil { + return m.Repeats + } + return nil +} + +func (m *Widget) GetRRepeats() []*Repeats { + if m != nil { + return m.RRepeats + } + return nil +} + +type Maps struct { + MInt64Str map[int64]string `protobuf:"bytes,1,rep,name=m_int64_str,json=mInt64Str" json:"m_int64_str,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + MBoolSimple map[bool]*Simple `protobuf:"bytes,2,rep,name=m_bool_simple,json=mBoolSimple" json:"m_bool_simple,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Maps) Reset() { *m = Maps{} } +func (m *Maps) String() string { return proto.CompactTextString(m) } +func (*Maps) ProtoMessage() {} +func (*Maps) Descriptor() ([]byte, []int) { + return fileDescriptor_50cab1d8463dea41, []int{4} +} + +func (m *Maps) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Maps.Unmarshal(m, b) +} +func (m *Maps) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Maps.Marshal(b, m, deterministic) +} +func (m *Maps) XXX_Merge(src proto.Message) { + xxx_messageInfo_Maps.Merge(m, src) +} +func (m *Maps) XXX_Size() int { + return xxx_messageInfo_Maps.Size(m) +} +func (m *Maps) XXX_DiscardUnknown() { + xxx_messageInfo_Maps.DiscardUnknown(m) +} + +var xxx_messageInfo_Maps proto.InternalMessageInfo + +func (m *Maps) GetMInt64Str() map[int64]string { + if m != nil { + return m.MInt64Str + } + return nil +} + +func (m *Maps) GetMBoolSimple() map[bool]*Simple { + if m != nil { + return m.MBoolSimple + } + return nil +} + +type MsgWithOneof struct { + // Types that are valid to be assigned to Union: + // *MsgWithOneof_Title + // *MsgWithOneof_Salary + // *MsgWithOneof_Country + // *MsgWithOneof_HomeAddress + // *MsgWithOneof_MsgWithRequired + // *MsgWithOneof_NullValue + Union isMsgWithOneof_Union `protobuf_oneof:"union"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MsgWithOneof) Reset() { *m = MsgWithOneof{} } +func (m *MsgWithOneof) String() string { return proto.CompactTextString(m) } +func (*MsgWithOneof) ProtoMessage() {} +func (*MsgWithOneof) Descriptor() ([]byte, []int) { + return fileDescriptor_50cab1d8463dea41, []int{5} +} + +func (m *MsgWithOneof) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MsgWithOneof.Unmarshal(m, b) +} +func (m *MsgWithOneof) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MsgWithOneof.Marshal(b, m, deterministic) +} +func (m *MsgWithOneof) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgWithOneof.Merge(m, src) +} +func (m *MsgWithOneof) XXX_Size() int { + return xxx_messageInfo_MsgWithOneof.Size(m) +} +func (m *MsgWithOneof) XXX_DiscardUnknown() { + xxx_messageInfo_MsgWithOneof.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgWithOneof proto.InternalMessageInfo + +type isMsgWithOneof_Union interface { + isMsgWithOneof_Union() +} + +type MsgWithOneof_Title struct { + Title string `protobuf:"bytes,1,opt,name=title,oneof"` +} + +type MsgWithOneof_Salary struct { + Salary int64 `protobuf:"varint,2,opt,name=salary,oneof"` +} + +type MsgWithOneof_Country struct { + Country string `protobuf:"bytes,3,opt,name=Country,oneof"` +} + +type MsgWithOneof_HomeAddress struct { + HomeAddress string `protobuf:"bytes,4,opt,name=home_address,json=homeAddress,oneof"` +} + +type MsgWithOneof_MsgWithRequired struct { + MsgWithRequired *MsgWithRequired `protobuf:"bytes,5,opt,name=msg_with_required,json=msgWithRequired,oneof"` +} + +type MsgWithOneof_NullValue struct { + NullValue structpb.NullValue `protobuf:"varint,6,opt,name=null_value,json=nullValue,enum=google.protobuf.NullValue,oneof"` +} + +func (*MsgWithOneof_Title) isMsgWithOneof_Union() {} + +func (*MsgWithOneof_Salary) isMsgWithOneof_Union() {} + +func (*MsgWithOneof_Country) isMsgWithOneof_Union() {} + +func (*MsgWithOneof_HomeAddress) isMsgWithOneof_Union() {} + +func (*MsgWithOneof_MsgWithRequired) isMsgWithOneof_Union() {} + +func (*MsgWithOneof_NullValue) isMsgWithOneof_Union() {} + +func (m *MsgWithOneof) GetUnion() isMsgWithOneof_Union { + if m != nil { + return m.Union + } + return nil +} + +func (m *MsgWithOneof) GetTitle() string { + if x, ok := m.GetUnion().(*MsgWithOneof_Title); ok { + return x.Title + } + return "" +} + +func (m *MsgWithOneof) GetSalary() int64 { + if x, ok := m.GetUnion().(*MsgWithOneof_Salary); ok { + return x.Salary + } + return 0 +} + +func (m *MsgWithOneof) GetCountry() string { + if x, ok := m.GetUnion().(*MsgWithOneof_Country); ok { + return x.Country + } + return "" +} + +func (m *MsgWithOneof) GetHomeAddress() string { + if x, ok := m.GetUnion().(*MsgWithOneof_HomeAddress); ok { + return x.HomeAddress + } + return "" +} + +func (m *MsgWithOneof) GetMsgWithRequired() *MsgWithRequired { + if x, ok := m.GetUnion().(*MsgWithOneof_MsgWithRequired); ok { + return x.MsgWithRequired + } + return nil +} + +func (m *MsgWithOneof) GetNullValue() structpb.NullValue { + if x, ok := m.GetUnion().(*MsgWithOneof_NullValue); ok { + return x.NullValue + } + return structpb.NullValue_NULL_VALUE +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*MsgWithOneof) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*MsgWithOneof_Title)(nil), + (*MsgWithOneof_Salary)(nil), + (*MsgWithOneof_Country)(nil), + (*MsgWithOneof_HomeAddress)(nil), + (*MsgWithOneof_MsgWithRequired)(nil), + (*MsgWithOneof_NullValue)(nil), + } +} + +type Real struct { + Value *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Real) Reset() { *m = Real{} } +func (m *Real) String() string { return proto.CompactTextString(m) } +func (*Real) ProtoMessage() {} +func (*Real) Descriptor() ([]byte, []int) { + return fileDescriptor_50cab1d8463dea41, []int{6} +} + +var extRange_Real = []proto.ExtensionRange{ + {Start: 100, End: 536870911}, +} + +func (*Real) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_Real +} + +func (m *Real) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Real.Unmarshal(m, b) +} +func (m *Real) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Real.Marshal(b, m, deterministic) +} +func (m *Real) XXX_Merge(src proto.Message) { + xxx_messageInfo_Real.Merge(m, src) +} +func (m *Real) XXX_Size() int { + return xxx_messageInfo_Real.Size(m) +} +func (m *Real) XXX_DiscardUnknown() { + xxx_messageInfo_Real.DiscardUnknown(m) +} + +var xxx_messageInfo_Real proto.InternalMessageInfo + +func (m *Real) GetValue() float64 { + if m != nil && m.Value != nil { + return *m.Value + } + return 0 +} + +type Complex struct { + Imaginary *float64 `protobuf:"fixed64,1,opt,name=imaginary" json:"imaginary,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Complex) Reset() { *m = Complex{} } +func (m *Complex) String() string { return proto.CompactTextString(m) } +func (*Complex) ProtoMessage() {} +func (*Complex) Descriptor() ([]byte, []int) { + return fileDescriptor_50cab1d8463dea41, []int{7} +} + +var extRange_Complex = []proto.ExtensionRange{ + {Start: 100, End: 536870911}, +} + +func (*Complex) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_Complex +} + +func (m *Complex) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Complex.Unmarshal(m, b) +} +func (m *Complex) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Complex.Marshal(b, m, deterministic) +} +func (m *Complex) XXX_Merge(src proto.Message) { + xxx_messageInfo_Complex.Merge(m, src) +} +func (m *Complex) XXX_Size() int { + return xxx_messageInfo_Complex.Size(m) +} +func (m *Complex) XXX_DiscardUnknown() { + xxx_messageInfo_Complex.DiscardUnknown(m) +} + +var xxx_messageInfo_Complex proto.InternalMessageInfo + +func (m *Complex) GetImaginary() float64 { + if m != nil && m.Imaginary != nil { + return *m.Imaginary + } + return 0 +} + +var E_Complex_RealExtension = &proto.ExtensionDesc{ + ExtendedType: (*Real)(nil), + ExtensionType: (*Complex)(nil), + Field: 123, + Name: "jsonpb_test.Complex.real_extension", + Tag: "bytes,123,opt,name=real_extension", + Filename: "jsonpb_proto/test2.proto", +} + +type KnownTypes struct { + An *anypb.Any `protobuf:"bytes,14,opt,name=an" json:"an,omitempty"` + Dur *durationpb.Duration `protobuf:"bytes,1,opt,name=dur" json:"dur,omitempty"` + St *structpb.Struct `protobuf:"bytes,12,opt,name=st" json:"st,omitempty"` + Ts *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=ts" json:"ts,omitempty"` + Lv *structpb.ListValue `protobuf:"bytes,15,opt,name=lv" json:"lv,omitempty"` + Val *structpb.Value `protobuf:"bytes,16,opt,name=val" json:"val,omitempty"` + Dbl *wrapperspb.DoubleValue `protobuf:"bytes,3,opt,name=dbl" json:"dbl,omitempty"` + Flt *wrapperspb.FloatValue `protobuf:"bytes,4,opt,name=flt" json:"flt,omitempty"` + I64 *wrapperspb.Int64Value `protobuf:"bytes,5,opt,name=i64" json:"i64,omitempty"` + U64 *wrapperspb.UInt64Value `protobuf:"bytes,6,opt,name=u64" json:"u64,omitempty"` + I32 *wrapperspb.Int32Value `protobuf:"bytes,7,opt,name=i32" json:"i32,omitempty"` + U32 *wrapperspb.UInt32Value `protobuf:"bytes,8,opt,name=u32" json:"u32,omitempty"` + Bool *wrapperspb.BoolValue `protobuf:"bytes,9,opt,name=bool" json:"bool,omitempty"` + Str *wrapperspb.StringValue `protobuf:"bytes,10,opt,name=str" json:"str,omitempty"` + Bytes *wrapperspb.BytesValue `protobuf:"bytes,11,opt,name=bytes" json:"bytes,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *KnownTypes) Reset() { *m = KnownTypes{} } +func (m *KnownTypes) String() string { return proto.CompactTextString(m) } +func (*KnownTypes) ProtoMessage() {} +func (*KnownTypes) Descriptor() ([]byte, []int) { + return fileDescriptor_50cab1d8463dea41, []int{8} +} + +func (m *KnownTypes) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_KnownTypes.Unmarshal(m, b) +} +func (m *KnownTypes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_KnownTypes.Marshal(b, m, deterministic) +} +func (m *KnownTypes) XXX_Merge(src proto.Message) { + xxx_messageInfo_KnownTypes.Merge(m, src) +} +func (m *KnownTypes) XXX_Size() int { + return xxx_messageInfo_KnownTypes.Size(m) +} +func (m *KnownTypes) XXX_DiscardUnknown() { + xxx_messageInfo_KnownTypes.DiscardUnknown(m) +} + +var xxx_messageInfo_KnownTypes proto.InternalMessageInfo + +func (m *KnownTypes) GetAn() *anypb.Any { + if m != nil { + return m.An + } + return nil +} + +func (m *KnownTypes) GetDur() *durationpb.Duration { + if m != nil { + return m.Dur + } + return nil +} + +func (m *KnownTypes) GetSt() *structpb.Struct { + if m != nil { + return m.St + } + return nil +} + +func (m *KnownTypes) GetTs() *timestamppb.Timestamp { + if m != nil { + return m.Ts + } + return nil +} + +func (m *KnownTypes) GetLv() *structpb.ListValue { + if m != nil { + return m.Lv + } + return nil +} + +func (m *KnownTypes) GetVal() *structpb.Value { + if m != nil { + return m.Val + } + return nil +} + +func (m *KnownTypes) GetDbl() *wrapperspb.DoubleValue { + if m != nil { + return m.Dbl + } + return nil +} + +func (m *KnownTypes) GetFlt() *wrapperspb.FloatValue { + if m != nil { + return m.Flt + } + return nil +} + +func (m *KnownTypes) GetI64() *wrapperspb.Int64Value { + if m != nil { + return m.I64 + } + return nil +} + +func (m *KnownTypes) GetU64() *wrapperspb.UInt64Value { + if m != nil { + return m.U64 + } + return nil +} + +func (m *KnownTypes) GetI32() *wrapperspb.Int32Value { + if m != nil { + return m.I32 + } + return nil +} + +func (m *KnownTypes) GetU32() *wrapperspb.UInt32Value { + if m != nil { + return m.U32 + } + return nil +} + +func (m *KnownTypes) GetBool() *wrapperspb.BoolValue { + if m != nil { + return m.Bool + } + return nil +} + +func (m *KnownTypes) GetStr() *wrapperspb.StringValue { + if m != nil { + return m.Str + } + return nil +} + +func (m *KnownTypes) GetBytes() *wrapperspb.BytesValue { + if m != nil { + return m.Bytes + } + return nil +} + +// Test messages for marshaling/unmarshaling required fields. +type MsgWithRequired struct { + Str *string `protobuf:"bytes,1,req,name=str" json:"str,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MsgWithRequired) Reset() { *m = MsgWithRequired{} } +func (m *MsgWithRequired) String() string { return proto.CompactTextString(m) } +func (*MsgWithRequired) ProtoMessage() {} +func (*MsgWithRequired) Descriptor() ([]byte, []int) { + return fileDescriptor_50cab1d8463dea41, []int{9} +} + +func (m *MsgWithRequired) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MsgWithRequired.Unmarshal(m, b) +} +func (m *MsgWithRequired) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MsgWithRequired.Marshal(b, m, deterministic) +} +func (m *MsgWithRequired) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgWithRequired.Merge(m, src) +} +func (m *MsgWithRequired) XXX_Size() int { + return xxx_messageInfo_MsgWithRequired.Size(m) +} +func (m *MsgWithRequired) XXX_DiscardUnknown() { + xxx_messageInfo_MsgWithRequired.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgWithRequired proto.InternalMessageInfo + +func (m *MsgWithRequired) GetStr() string { + if m != nil && m.Str != nil { + return *m.Str + } + return "" +} + +type MsgWithIndirectRequired struct { + Subm *MsgWithRequired `protobuf:"bytes,1,opt,name=subm" json:"subm,omitempty"` + MapField map[string]*MsgWithRequired `protobuf:"bytes,2,rep,name=map_field,json=mapField" json:"map_field,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + SliceField []*MsgWithRequired `protobuf:"bytes,3,rep,name=slice_field,json=sliceField" json:"slice_field,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MsgWithIndirectRequired) Reset() { *m = MsgWithIndirectRequired{} } +func (m *MsgWithIndirectRequired) String() string { return proto.CompactTextString(m) } +func (*MsgWithIndirectRequired) ProtoMessage() {} +func (*MsgWithIndirectRequired) Descriptor() ([]byte, []int) { + return fileDescriptor_50cab1d8463dea41, []int{10} +} + +func (m *MsgWithIndirectRequired) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MsgWithIndirectRequired.Unmarshal(m, b) +} +func (m *MsgWithIndirectRequired) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MsgWithIndirectRequired.Marshal(b, m, deterministic) +} +func (m *MsgWithIndirectRequired) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgWithIndirectRequired.Merge(m, src) +} +func (m *MsgWithIndirectRequired) XXX_Size() int { + return xxx_messageInfo_MsgWithIndirectRequired.Size(m) +} +func (m *MsgWithIndirectRequired) XXX_DiscardUnknown() { + xxx_messageInfo_MsgWithIndirectRequired.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgWithIndirectRequired proto.InternalMessageInfo + +func (m *MsgWithIndirectRequired) GetSubm() *MsgWithRequired { + if m != nil { + return m.Subm + } + return nil +} + +func (m *MsgWithIndirectRequired) GetMapField() map[string]*MsgWithRequired { + if m != nil { + return m.MapField + } + return nil +} + +func (m *MsgWithIndirectRequired) GetSliceField() []*MsgWithRequired { + if m != nil { + return m.SliceField + } + return nil +} + +type MsgWithRequiredBytes struct { + Byts []byte `protobuf:"bytes,1,req,name=byts" json:"byts,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MsgWithRequiredBytes) Reset() { *m = MsgWithRequiredBytes{} } +func (m *MsgWithRequiredBytes) String() string { return proto.CompactTextString(m) } +func (*MsgWithRequiredBytes) ProtoMessage() {} +func (*MsgWithRequiredBytes) Descriptor() ([]byte, []int) { + return fileDescriptor_50cab1d8463dea41, []int{11} +} + +func (m *MsgWithRequiredBytes) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MsgWithRequiredBytes.Unmarshal(m, b) +} +func (m *MsgWithRequiredBytes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MsgWithRequiredBytes.Marshal(b, m, deterministic) +} +func (m *MsgWithRequiredBytes) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgWithRequiredBytes.Merge(m, src) +} +func (m *MsgWithRequiredBytes) XXX_Size() int { + return xxx_messageInfo_MsgWithRequiredBytes.Size(m) +} +func (m *MsgWithRequiredBytes) XXX_DiscardUnknown() { + xxx_messageInfo_MsgWithRequiredBytes.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgWithRequiredBytes proto.InternalMessageInfo + +func (m *MsgWithRequiredBytes) GetByts() []byte { + if m != nil { + return m.Byts + } + return nil +} + +type MsgWithRequiredWKT struct { + Str *wrapperspb.StringValue `protobuf:"bytes,1,req,name=str" json:"str,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MsgWithRequiredWKT) Reset() { *m = MsgWithRequiredWKT{} } +func (m *MsgWithRequiredWKT) String() string { return proto.CompactTextString(m) } +func (*MsgWithRequiredWKT) ProtoMessage() {} +func (*MsgWithRequiredWKT) Descriptor() ([]byte, []int) { + return fileDescriptor_50cab1d8463dea41, []int{12} +} + +func (m *MsgWithRequiredWKT) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MsgWithRequiredWKT.Unmarshal(m, b) +} +func (m *MsgWithRequiredWKT) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MsgWithRequiredWKT.Marshal(b, m, deterministic) +} +func (m *MsgWithRequiredWKT) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgWithRequiredWKT.Merge(m, src) +} +func (m *MsgWithRequiredWKT) XXX_Size() int { + return xxx_messageInfo_MsgWithRequiredWKT.Size(m) +} +func (m *MsgWithRequiredWKT) XXX_DiscardUnknown() { + xxx_messageInfo_MsgWithRequiredWKT.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgWithRequiredWKT proto.InternalMessageInfo + +func (m *MsgWithRequiredWKT) GetStr() *wrapperspb.StringValue { + if m != nil { + return m.Str + } + return nil +} + +var E_Name = &proto.ExtensionDesc{ + ExtendedType: (*Real)(nil), + ExtensionType: (*string)(nil), + Field: 124, + Name: "jsonpb_test.name", + Tag: "bytes,124,opt,name=name", + Filename: "jsonpb_proto/test2.proto", +} + +var E_Extm = &proto.ExtensionDesc{ + ExtendedType: (*Real)(nil), + ExtensionType: (*MsgWithRequired)(nil), + Field: 125, + Name: "jsonpb_test.extm", + Tag: "bytes,125,opt,name=extm", + Filename: "jsonpb_proto/test2.proto", +} + +func init() { + proto.RegisterEnum("jsonpb_test.Widget_Color", Widget_Color_name, Widget_Color_value) + proto.RegisterType((*Simple)(nil), "jsonpb_test.Simple") + proto.RegisterType((*NonFinites)(nil), "jsonpb_test.NonFinites") + proto.RegisterType((*Repeats)(nil), "jsonpb_test.Repeats") + proto.RegisterType((*Widget)(nil), "jsonpb_test.Widget") + proto.RegisterType((*Maps)(nil), "jsonpb_test.Maps") + proto.RegisterMapType((map[bool]*Simple)(nil), "jsonpb_test.Maps.MBoolSimpleEntry") + proto.RegisterMapType((map[int64]string)(nil), "jsonpb_test.Maps.MInt64StrEntry") + proto.RegisterType((*MsgWithOneof)(nil), "jsonpb_test.MsgWithOneof") + proto.RegisterType((*Real)(nil), "jsonpb_test.Real") + proto.RegisterExtension(E_Complex_RealExtension) + proto.RegisterType((*Complex)(nil), "jsonpb_test.Complex") + proto.RegisterType((*KnownTypes)(nil), "jsonpb_test.KnownTypes") + proto.RegisterType((*MsgWithRequired)(nil), "jsonpb_test.MsgWithRequired") + proto.RegisterType((*MsgWithIndirectRequired)(nil), "jsonpb_test.MsgWithIndirectRequired") + proto.RegisterMapType((map[string]*MsgWithRequired)(nil), "jsonpb_test.MsgWithIndirectRequired.MapFieldEntry") + proto.RegisterType((*MsgWithRequiredBytes)(nil), "jsonpb_test.MsgWithRequiredBytes") + proto.RegisterType((*MsgWithRequiredWKT)(nil), "jsonpb_test.MsgWithRequiredWKT") + proto.RegisterExtension(E_Name) + proto.RegisterExtension(E_Extm) +} + +func init() { proto.RegisterFile("jsonpb_proto/test2.proto", fileDescriptor_50cab1d8463dea41) } + +var fileDescriptor_50cab1d8463dea41 = []byte{ + // 1537 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x57, 0xdd, 0x6e, 0xdb, 0xc8, + 0x15, 0x36, 0x49, 0x51, 0x12, 0x8f, 0xec, 0xc4, 0x99, 0x64, 0x37, 0xb4, 0x1b, 0x6c, 0x09, 0x6d, + 0xb7, 0x55, 0xb3, 0xa8, 0xdc, 0xa5, 0x05, 0xa1, 0xc8, 0x76, 0x81, 0xae, 0x13, 0xa7, 0xd9, 0xee, + 0xc6, 0x5b, 0x8c, 0x93, 0x06, 0xed, 0x8d, 0x40, 0x99, 0x94, 0xc2, 0x96, 0x9c, 0x51, 0x67, 0x86, + 0x4e, 0x84, 0xb6, 0x80, 0xfb, 0x0a, 0xed, 0x23, 0x14, 0xe8, 0x6d, 0xef, 0x7a, 0xd1, 0xe7, 0xe8, + 0x03, 0x2d, 0xe6, 0xcc, 0x50, 0x7f, 0x96, 0x8d, 0xbd, 0xb2, 0x66, 0xbe, 0x9f, 0x19, 0xce, 0xf9, + 0x78, 0x86, 0x86, 0xf0, 0x8f, 0x92, 0xb3, 0xd9, 0x78, 0x34, 0x13, 0x5c, 0xf1, 0x23, 0x95, 0x49, + 0x15, 0xf7, 0xf1, 0x37, 0xe9, 0x58, 0x44, 0xcf, 0x1d, 0x1e, 0x4c, 0x39, 0x9f, 0x16, 0xd9, 0x11, + 0x42, 0xe3, 0x6a, 0x72, 0x94, 0xb0, 0xb9, 0xe1, 0x1d, 0x7e, 0xb4, 0x09, 0xa5, 0x95, 0x48, 0x54, + 0xce, 0x99, 0xc5, 0x1f, 0x6d, 0xe2, 0x52, 0x89, 0xea, 0x42, 0x59, 0xf4, 0x87, 0x9b, 0xa8, 0xca, + 0xcb, 0x4c, 0xaa, 0xa4, 0x9c, 0xdd, 0x64, 0xff, 0x4e, 0x24, 0xb3, 0x59, 0x26, 0xa4, 0xc1, 0xbb, + 0xff, 0x69, 0x40, 0xf3, 0x3c, 0x2f, 0x67, 0x45, 0x46, 0x3e, 0x80, 0x26, 0x1f, 0x8d, 0x39, 0x2f, + 0x42, 0x27, 0x72, 0x7a, 0x6d, 0xea, 0xf3, 0x13, 0xce, 0x0b, 0xf2, 0x10, 0x5a, 0x7c, 0x94, 0x33, + 0x75, 0x1c, 0x87, 0x6e, 0xe4, 0xf4, 0x7c, 0xda, 0xe4, 0x5f, 0xe9, 0x11, 0xf9, 0x08, 0x3a, 0x16, + 0x18, 0x49, 0x25, 0x42, 0x0f, 0xc1, 0xc0, 0x80, 0xe7, 0x4a, 0x2c, 0x84, 0xc3, 0x41, 0xd8, 0x88, + 0x9c, 0x9e, 0x67, 0x84, 0xc3, 0xc1, 0x42, 0x38, 0x1c, 0xa0, 0xd0, 0x47, 0x30, 0x30, 0xa0, 0x16, + 0x1e, 0x40, 0x9b, 0x8f, 0x2a, 0xb3, 0x64, 0x33, 0x72, 0x7a, 0x7b, 0xb4, 0xc5, 0x5f, 0xe3, 0x90, + 0x44, 0xb0, 0x5b, 0x43, 0xa8, 0x6d, 0x21, 0x0c, 0x16, 0x5e, 0x13, 0x0f, 0x07, 0x61, 0x3b, 0x72, + 0x7a, 0x0d, 0x2b, 0x1e, 0x0e, 0x96, 0x62, 0xbb, 0x70, 0x80, 0x30, 0x58, 0x78, 0x21, 0x96, 0x66, + 0x65, 0x88, 0x9c, 0xde, 0x3d, 0xda, 0xe2, 0xe7, 0x2b, 0x2b, 0xcb, 0xe5, 0xca, 0x1d, 0x84, 0xc1, + 0xc2, 0x6b, 0xe2, 0xe1, 0x20, 0xdc, 0x8d, 0x9c, 0x1e, 0xb1, 0xe2, 0x7a, 0x65, 0xb9, 0x5c, 0x79, + 0x0f, 0x61, 0xb0, 0xf0, 0xe2, 0xb0, 0x26, 0x05, 0x4f, 0x54, 0x78, 0x27, 0x72, 0x7a, 0x2e, 0x6d, + 0xf2, 0xe7, 0x7a, 0x64, 0x0e, 0x0b, 0x01, 0x54, 0xde, 0x45, 0x30, 0x30, 0xe0, 0x62, 0xd5, 0x94, + 0x57, 0xe3, 0x22, 0x0b, 0xf7, 0x23, 0xa7, 0xe7, 0xd0, 0x16, 0x7f, 0x86, 0x43, 0xb3, 0xaa, 0x81, + 0x50, 0x7b, 0x0f, 0x61, 0xb0, 0xf0, 0x72, 0xcb, 0x4a, 0xe4, 0x6c, 0x1a, 0x92, 0xc8, 0xe9, 0x05, + 0x7a, 0xcb, 0x38, 0x34, 0x1b, 0x1a, 0xcf, 0x55, 0x26, 0xc3, 0xfb, 0x91, 0xd3, 0xdb, 0xa5, 0x4d, + 0x7e, 0xa2, 0x47, 0xdd, 0x7f, 0x38, 0x00, 0x67, 0x9c, 0x3d, 0xcf, 0x59, 0xae, 0x32, 0x49, 0xee, + 0x83, 0x3f, 0x19, 0xb1, 0x84, 0x61, 0x68, 0x5c, 0xda, 0x98, 0x9c, 0x25, 0x4c, 0x47, 0x69, 0x32, + 0x9a, 0xe5, 0x6c, 0x82, 0x91, 0x71, 0xa9, 0x3f, 0xf9, 0x6d, 0xce, 0x26, 0x66, 0x9a, 0xe9, 0x69, + 0xcf, 0x4e, 0x9f, 0xe9, 0xe9, 0xfb, 0xe0, 0xa7, 0x68, 0xd1, 0xc0, 0x0d, 0x36, 0x52, 0x6b, 0x91, + 0x1a, 0x0b, 0x1f, 0x67, 0xfd, 0xb4, 0xb6, 0x48, 0x8d, 0x45, 0xd3, 0x4e, 0x6b, 0x8b, 0xee, 0xbf, + 0x5d, 0x68, 0xd1, 0x6c, 0x96, 0x25, 0x4a, 0x6a, 0x8a, 0xa8, 0x73, 0xec, 0xe9, 0x1c, 0x8b, 0x3a, + 0xc7, 0x62, 0x91, 0x63, 0x4f, 0xe7, 0x58, 0x98, 0x1c, 0xd7, 0xc0, 0x70, 0x10, 0x7a, 0x91, 0xa7, + 0x73, 0x2a, 0x4c, 0x4e, 0x0f, 0xa0, 0x2d, 0xea, 0x1c, 0x36, 0x22, 0x4f, 0xe7, 0x50, 0xd8, 0x1c, + 0x2e, 0xa0, 0xe1, 0x20, 0xf4, 0x23, 0x4f, 0xa7, 0x4c, 0xd8, 0x94, 0x21, 0x24, 0xeb, 0xf4, 0x7a, + 0x3a, 0x43, 0xe2, 0x7c, 0x45, 0x65, 0x13, 0xd2, 0x8a, 0x3c, 0x9d, 0x10, 0x61, 0x13, 0x82, 0x9b, + 0x30, 0xf5, 0x6f, 0x47, 0x9e, 0xae, 0xbf, 0x30, 0xf5, 0x47, 0x8d, 0xad, 0x6f, 0x10, 0x79, 0xba, + 0xbe, 0xc2, 0xd6, 0xd7, 0xd8, 0x99, 0xea, 0x41, 0xe4, 0xe9, 0xea, 0x89, 0x65, 0xf5, 0x84, 0xad, + 0x5e, 0x27, 0xf2, 0x74, 0xf5, 0x84, 0xa9, 0xde, 0xff, 0x5d, 0x68, 0xbe, 0xc9, 0xd3, 0x69, 0xa6, + 0xc8, 0x11, 0xf8, 0x17, 0xbc, 0xe0, 0x02, 0x2b, 0x77, 0x27, 0x3e, 0xe8, 0xaf, 0x74, 0xac, 0xbe, + 0xe1, 0xf4, 0x9f, 0x6a, 0x02, 0x35, 0x3c, 0x12, 0x6b, 0x53, 0x23, 0xd1, 0x27, 0x78, 0xab, 0xa4, + 0x29, 0xf0, 0x2f, 0xf9, 0x14, 0x9a, 0x12, 0xdb, 0x0b, 0xbe, 0x4f, 0x9d, 0xf8, 0xfe, 0x9a, 0xc4, + 0x74, 0x1e, 0x6a, 0x29, 0xa4, 0x6f, 0xce, 0x07, 0xe9, 0x7a, 0xdb, 0x37, 0xd0, 0xf5, 0xa1, 0x59, + 0x7e, 0x4b, 0x98, 0xa2, 0x87, 0x0f, 0xd0, 0xfd, 0xc1, 0x1a, 0xdd, 0x06, 0x82, 0xd6, 0x24, 0xf2, + 0x19, 0x04, 0x62, 0x54, 0x2b, 0x3e, 0xc0, 0x05, 0xb6, 0x2b, 0xda, 0xc2, 0xfe, 0xea, 0x7e, 0x02, + 0xbe, 0x79, 0x90, 0x16, 0x78, 0xf4, 0xf4, 0xd9, 0xfe, 0x0e, 0x09, 0xc0, 0xff, 0x35, 0x3d, 0x3d, + 0x3d, 0xdb, 0x77, 0x48, 0x1b, 0x1a, 0x27, 0xdf, 0xbc, 0x3e, 0xdd, 0x77, 0xbb, 0xff, 0x72, 0xa1, + 0xf1, 0x32, 0x99, 0x49, 0xf2, 0x2b, 0xe8, 0x94, 0x2b, 0xbd, 0xcd, 0xc1, 0x45, 0xa2, 0xb5, 0x45, + 0x34, 0xaf, 0xff, 0xb2, 0xee, 0x76, 0xa7, 0x4c, 0x89, 0x39, 0x0d, 0xca, 0x45, 0xf7, 0x7b, 0x0e, + 0x7b, 0x25, 0xc6, 0xb7, 0x3e, 0x09, 0x17, 0x3d, 0xba, 0x5b, 0x3c, 0x74, 0xae, 0xcd, 0x51, 0x18, + 0x97, 0x4e, 0xb9, 0x9c, 0x39, 0xfc, 0x25, 0xdc, 0x59, 0x5f, 0x84, 0xec, 0x83, 0xf7, 0xa7, 0x6c, + 0x8e, 0xe5, 0xf6, 0xa8, 0xfe, 0x49, 0x1e, 0x80, 0x7f, 0x99, 0x14, 0x55, 0x86, 0xaf, 0x69, 0x40, + 0xcd, 0xe0, 0x89, 0xfb, 0x0b, 0xe7, 0xf0, 0x1c, 0xf6, 0x37, 0xed, 0x57, 0xf5, 0x6d, 0xa3, 0xff, + 0xe9, 0xaa, 0xfe, 0x86, 0x6a, 0x2d, 0x4d, 0xbb, 0xff, 0x74, 0x61, 0xf7, 0xa5, 0x9c, 0xbe, 0xc9, + 0xd5, 0xdb, 0x6f, 0x59, 0xc6, 0x27, 0xe4, 0x43, 0xf0, 0x55, 0xae, 0x8a, 0x0c, 0x3d, 0x83, 0x17, + 0x3b, 0xd4, 0x0c, 0x49, 0x08, 0x4d, 0x99, 0x14, 0x89, 0x98, 0xa3, 0xb1, 0xf7, 0x62, 0x87, 0xda, + 0x31, 0x39, 0x84, 0xd6, 0x53, 0x5e, 0xe9, 0xed, 0x60, 0x0f, 0xd1, 0x9a, 0x7a, 0x82, 0x7c, 0x0c, + 0xbb, 0x6f, 0x79, 0x99, 0x8d, 0x92, 0x34, 0x15, 0x99, 0x94, 0xd8, 0x4e, 0x34, 0xa1, 0xa3, 0x67, + 0xbf, 0x34, 0x93, 0xe4, 0x37, 0x70, 0xaf, 0x94, 0xd3, 0xd1, 0xbb, 0x5c, 0xbd, 0x1d, 0x89, 0xec, + 0xcf, 0x55, 0x2e, 0xb2, 0x14, 0x5b, 0x4c, 0x27, 0x7e, 0xb4, 0x7e, 0xc4, 0x66, 0xa3, 0xd4, 0x72, + 0x5e, 0xec, 0xd0, 0xbb, 0xe5, 0xfa, 0x14, 0xf9, 0x1c, 0x80, 0x55, 0x45, 0x31, 0x32, 0x67, 0xd0, + 0xc4, 0xd7, 0xe8, 0xb0, 0x6f, 0x6e, 0xdc, 0x7e, 0x7d, 0xe3, 0xf6, 0xcf, 0xaa, 0xa2, 0xf8, 0x9d, + 0x66, 0xbc, 0xd8, 0xa1, 0x01, 0xab, 0x07, 0x27, 0x2d, 0xf0, 0x2b, 0x96, 0x73, 0xd6, 0xfd, 0x31, + 0x34, 0x68, 0x96, 0x14, 0xcb, 0x62, 0x38, 0xa6, 0xb3, 0xe1, 0xe0, 0x71, 0xbb, 0x9d, 0xee, 0x5f, + 0x5d, 0x5d, 0x5d, 0xb9, 0xdd, 0xbf, 0x3b, 0xfa, 0xd9, 0xf5, 0x99, 0xbe, 0x27, 0x8f, 0x20, 0xc8, + 0xcb, 0x64, 0x9a, 0x33, 0x7d, 0x46, 0x86, 0xbf, 0x9c, 0x58, 0x6a, 0xe2, 0x33, 0xb8, 0x23, 0xb2, + 0xa4, 0x18, 0x65, 0xef, 0x55, 0xc6, 0x64, 0xce, 0x19, 0xb9, 0xb7, 0x11, 0xf8, 0xa4, 0x08, 0xff, + 0xb2, 0xe5, 0xdd, 0xb1, 0x0b, 0xd1, 0x3d, 0x2d, 0x3f, 0xad, 0xd5, 0xdd, 0xff, 0xf9, 0x00, 0x5f, + 0x33, 0xfe, 0x8e, 0xbd, 0x9a, 0xcf, 0x32, 0x49, 0x7e, 0x04, 0x6e, 0xc2, 0xf0, 0xc2, 0xd2, 0xfa, + 0xcd, 0x07, 0xff, 0x92, 0xcd, 0xa9, 0x9b, 0x30, 0xf2, 0x29, 0x78, 0x69, 0x65, 0xda, 0x4c, 0x27, + 0x3e, 0xb8, 0x46, 0x7b, 0x66, 0x3f, 0x78, 0xa8, 0x66, 0x91, 0x9f, 0x80, 0x2b, 0x15, 0xde, 0x9f, + 0x9d, 0xf8, 0xe1, 0x35, 0xee, 0x39, 0x7e, 0xfc, 0x50, 0x57, 0x2a, 0xf2, 0x18, 0x5c, 0x25, 0x6d, + 0xf0, 0xae, 0x1f, 0xfa, 0xab, 0xfa, 0x3b, 0x88, 0xba, 0x4a, 0x6a, 0x6e, 0x71, 0x89, 0x77, 0xe7, + 0x36, 0xee, 0x37, 0xb9, 0x54, 0x58, 0x13, 0xea, 0x16, 0x97, 0xa4, 0x07, 0xde, 0x65, 0x52, 0xe0, + 0x5d, 0xda, 0x89, 0x3f, 0xbc, 0x46, 0x36, 0x44, 0x4d, 0x21, 0x7d, 0xf0, 0xd2, 0x71, 0x81, 0x39, + 0xd4, 0xe1, 0xb9, 0xf6, 0x5c, 0xd8, 0xa5, 0x2d, 0x3f, 0x1d, 0x17, 0xe4, 0x67, 0xe0, 0x4d, 0x0a, + 0x85, 0xb1, 0xec, 0xc4, 0x3f, 0xb8, 0xc6, 0xc7, 0x7e, 0x6f, 0xe9, 0x93, 0x42, 0x69, 0x7a, 0x8e, + 0xd7, 0xcb, 0x76, 0x3a, 0xbe, 0xdb, 0x96, 0x9e, 0x0f, 0x07, 0x7a, 0x37, 0xd5, 0x70, 0x80, 0x29, + 0xdc, 0xb6, 0x9b, 0xd7, 0xab, 0xfc, 0x6a, 0x38, 0x40, 0xfb, 0xe3, 0x18, 0xbf, 0xa0, 0x6e, 0xb0, + 0x3f, 0x8e, 0x6b, 0xfb, 0xe3, 0x18, 0xed, 0x8f, 0x63, 0xfc, 0xa4, 0xba, 0xc9, 0x7e, 0xc1, 0xaf, + 0x90, 0xdf, 0xc0, 0x3b, 0x38, 0xb8, 0xe1, 0xd0, 0x75, 0x73, 0x31, 0x74, 0xe4, 0x69, 0x7f, 0xdd, + 0x30, 0xe1, 0x06, 0x7f, 0x73, 0xaf, 0x59, 0x7f, 0xa9, 0x04, 0xf9, 0x0c, 0xfc, 0xfa, 0x7e, 0xdb, + 0xfe, 0x00, 0x78, 0xdf, 0x19, 0x81, 0x61, 0x76, 0x3f, 0x86, 0xbb, 0x1b, 0x2f, 0xb5, 0x6e, 0x69, + 0xa6, 0x4d, 0xbb, 0xbd, 0x00, 0x7d, 0xbb, 0xff, 0x75, 0xe1, 0xa1, 0x65, 0x7d, 0xc5, 0xd2, 0x5c, + 0x64, 0x17, 0x6a, 0xc1, 0xfe, 0x39, 0x34, 0x64, 0x35, 0x2e, 0x6d, 0x92, 0x6f, 0x6d, 0x17, 0x14, + 0x99, 0xe4, 0x5b, 0x08, 0xca, 0x64, 0x36, 0x9a, 0xe4, 0x59, 0x91, 0xda, 0x46, 0x1e, 0x6f, 0x93, + 0x6d, 0x2e, 0xa5, 0x1b, 0xfc, 0x73, 0x2d, 0x32, 0x8d, 0xbd, 0x5d, 0xda, 0x21, 0xf9, 0x02, 0x3a, + 0xb2, 0xc8, 0x2f, 0x32, 0x6b, 0xe9, 0xa1, 0xe5, 0xed, 0x3b, 0x01, 0x14, 0xa0, 0xfc, 0xf0, 0xf7, + 0xb0, 0xb7, 0xe6, 0xbc, 0xda, 0xd3, 0x03, 0xd3, 0xd3, 0xe3, 0xf5, 0x9e, 0x7e, 0xbb, 0xf7, 0x4a, + 0x73, 0x7f, 0x0c, 0x0f, 0x36, 0x50, 0xac, 0x00, 0x21, 0xd0, 0x18, 0xcf, 0x95, 0xc4, 0x33, 0xde, + 0xa5, 0xf8, 0xbb, 0xfb, 0x0c, 0xc8, 0x06, 0xf7, 0xcd, 0xd7, 0xaf, 0xea, 0x08, 0x68, 0xe2, 0xf7, + 0x89, 0xc0, 0x93, 0x4f, 0xa0, 0xc1, 0x92, 0x32, 0xdb, 0xd6, 0xd2, 0xfe, 0x8a, 0xcf, 0x83, 0xf0, + 0x93, 0xa7, 0xd0, 0xc8, 0xde, 0xab, 0x72, 0x1b, 0xed, 0x6f, 0xdf, 0xa7, 0x90, 0x5a, 0x7c, 0xf2, + 0xc5, 0x1f, 0x3e, 0x9f, 0xe6, 0xea, 0x6d, 0x35, 0xee, 0x5f, 0xf0, 0xf2, 0x68, 0xca, 0x8b, 0x84, + 0x4d, 0x97, 0xff, 0x54, 0xe5, 0x4c, 0x65, 0x82, 0x25, 0x05, 0xfe, 0x07, 0x88, 0xb3, 0xf2, 0x68, + 0xf5, 0x3f, 0xc3, 0xef, 0x02, 0x00, 0x00, 0xff, 0xff, 0x5b, 0xac, 0xa6, 0xa5, 0x28, 0x0e, 0x00, + 0x00, +} diff --git a/pkg/golang-protobuf/internal/testprotos/jsonpb_proto/test2.proto b/pkg/golang-protobuf/internal/testprotos/jsonpb_proto/test2.proto new file mode 100644 index 000000000..f41c0ec48 --- /dev/null +++ b/pkg/golang-protobuf/internal/testprotos/jsonpb_proto/test2.proto @@ -0,0 +1,155 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +syntax = "proto2"; + +option go_package = "github.com/golang/protobuf/internal/testprotos/jsonpb_proto"; + +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/wrappers.proto"; + +package jsonpb_test; + +// Test message for holding primitive types. +message Simple { + optional bool o_bool = 1; + optional int32 o_int32 = 2; + optional int32 o_int32_str = 3; + optional int64 o_int64 = 4; + optional int64 o_int64_str = 5; + optional uint32 o_uint32 = 6; + optional uint32 o_uint32_str = 7; + optional uint64 o_uint64 = 8; + optional uint64 o_uint64_str = 9; + optional sint32 o_sint32 = 10; + optional sint32 o_sint32_str = 11; + optional sint64 o_sint64 = 12; + optional sint64 o_sint64_str = 13; + optional float o_float = 14; + optional float o_float_str = 15; + optional double o_double = 16; + optional double o_double_str = 17; + optional string o_string = 18; + optional bytes o_bytes = 19; +} + +// Test message for holding special non-finites primitives. +message NonFinites { + optional float f_nan = 1; + optional float f_pinf = 2; + optional float f_ninf = 3; + optional double d_nan = 4; + optional double d_pinf = 5; + optional double d_ninf = 6; +} + +// Test message for holding repeated primitives. +message Repeats { + repeated bool r_bool = 1; + repeated int32 r_int32 = 2; + repeated int64 r_int64 = 3; + repeated uint32 r_uint32 = 4; + repeated uint64 r_uint64 = 5; + repeated sint32 r_sint32 = 6; + repeated sint64 r_sint64 = 7; + repeated float r_float = 8; + repeated double r_double = 9; + repeated string r_string = 10; + repeated bytes r_bytes = 11; +} + +// Test message for holding enums and nested messages. +message Widget { + enum Color { + RED = 0; + GREEN = 1; + BLUE = 2; + }; + optional Color color = 1; + repeated Color r_color = 2; + + optional Simple simple = 10; + repeated Simple r_simple = 11; + + optional Repeats repeats = 20; + repeated Repeats r_repeats = 21; +} + +message Maps { + map m_int64_str = 1; + map m_bool_simple = 2; +} + +message MsgWithOneof { + oneof union { + string title = 1; + int64 salary = 2; + string Country = 3; + string home_address = 4; + MsgWithRequired msg_with_required = 5; + google.protobuf.NullValue null_value = 6; + } +} + +message Real { + optional double value = 1; + extensions 100 to max; +} + +extend Real { + optional string name = 124; +} + +message Complex { + extend Real { + optional Complex real_extension = 123; + } + optional double imaginary = 1; + extensions 100 to max; +} + +message KnownTypes { + optional google.protobuf.Any an = 14; + optional google.protobuf.Duration dur = 1; + optional google.protobuf.Struct st = 12; + optional google.protobuf.Timestamp ts = 2; + optional google.protobuf.ListValue lv = 15; + optional google.protobuf.Value val = 16; + + optional google.protobuf.DoubleValue dbl = 3; + optional google.protobuf.FloatValue flt = 4; + optional google.protobuf.Int64Value i64 = 5; + optional google.protobuf.UInt64Value u64 = 6; + optional google.protobuf.Int32Value i32 = 7; + optional google.protobuf.UInt32Value u32 = 8; + optional google.protobuf.BoolValue bool = 9; + optional google.protobuf.StringValue str = 10; + optional google.protobuf.BytesValue bytes = 11; +} + +// Test messages for marshaling/unmarshaling required fields. +message MsgWithRequired { + required string str = 1; +} + +message MsgWithIndirectRequired { + optional MsgWithRequired subm = 1; + map map_field = 2; + repeated MsgWithRequired slice_field = 3; +} + +message MsgWithRequiredBytes { + required bytes byts = 1; +} + +message MsgWithRequiredWKT { + required google.protobuf.StringValue str = 1; +} + +extend Real { + optional MsgWithRequired extm = 125; +} diff --git a/pkg/golang-protobuf/internal/testprotos/jsonpb_proto/test3.pb.go b/pkg/golang-protobuf/internal/testprotos/jsonpb_proto/test3.pb.go new file mode 100644 index 000000000..cb9a81411 --- /dev/null +++ b/pkg/golang-protobuf/internal/testprotos/jsonpb_proto/test3.pb.go @@ -0,0 +1,378 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: jsonpb_proto/test3.proto + +package jsonpb_proto + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type Numeral int32 + +const ( + Numeral_UNKNOWN Numeral = 0 + Numeral_ARABIC Numeral = 1 + Numeral_ROMAN Numeral = 2 +) + +var Numeral_name = map[int32]string{ + 0: "UNKNOWN", + 1: "ARABIC", + 2: "ROMAN", +} + +var Numeral_value = map[string]int32{ + "UNKNOWN": 0, + "ARABIC": 1, + "ROMAN": 2, +} + +func (x Numeral) String() string { + return proto.EnumName(Numeral_name, int32(x)) +} + +func (Numeral) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_813baf511b225405, []int{0} +} + +type Simple3 struct { + Dub float64 `protobuf:"fixed64,1,opt,name=dub,proto3" json:"dub,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Simple3) Reset() { *m = Simple3{} } +func (m *Simple3) String() string { return proto.CompactTextString(m) } +func (*Simple3) ProtoMessage() {} +func (*Simple3) Descriptor() ([]byte, []int) { + return fileDescriptor_813baf511b225405, []int{0} +} + +func (m *Simple3) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Simple3.Unmarshal(m, b) +} +func (m *Simple3) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Simple3.Marshal(b, m, deterministic) +} +func (m *Simple3) XXX_Merge(src proto.Message) { + xxx_messageInfo_Simple3.Merge(m, src) +} +func (m *Simple3) XXX_Size() int { + return xxx_messageInfo_Simple3.Size(m) +} +func (m *Simple3) XXX_DiscardUnknown() { + xxx_messageInfo_Simple3.DiscardUnknown(m) +} + +var xxx_messageInfo_Simple3 proto.InternalMessageInfo + +func (m *Simple3) GetDub() float64 { + if m != nil { + return m.Dub + } + return 0 +} + +type SimpleSlice3 struct { + Slices []string `protobuf:"bytes,1,rep,name=slices,proto3" json:"slices,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SimpleSlice3) Reset() { *m = SimpleSlice3{} } +func (m *SimpleSlice3) String() string { return proto.CompactTextString(m) } +func (*SimpleSlice3) ProtoMessage() {} +func (*SimpleSlice3) Descriptor() ([]byte, []int) { + return fileDescriptor_813baf511b225405, []int{1} +} + +func (m *SimpleSlice3) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SimpleSlice3.Unmarshal(m, b) +} +func (m *SimpleSlice3) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SimpleSlice3.Marshal(b, m, deterministic) +} +func (m *SimpleSlice3) XXX_Merge(src proto.Message) { + xxx_messageInfo_SimpleSlice3.Merge(m, src) +} +func (m *SimpleSlice3) XXX_Size() int { + return xxx_messageInfo_SimpleSlice3.Size(m) +} +func (m *SimpleSlice3) XXX_DiscardUnknown() { + xxx_messageInfo_SimpleSlice3.DiscardUnknown(m) +} + +var xxx_messageInfo_SimpleSlice3 proto.InternalMessageInfo + +func (m *SimpleSlice3) GetSlices() []string { + if m != nil { + return m.Slices + } + return nil +} + +type SimpleMap3 struct { + Stringy map[string]string `protobuf:"bytes,1,rep,name=stringy,proto3" json:"stringy,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SimpleMap3) Reset() { *m = SimpleMap3{} } +func (m *SimpleMap3) String() string { return proto.CompactTextString(m) } +func (*SimpleMap3) ProtoMessage() {} +func (*SimpleMap3) Descriptor() ([]byte, []int) { + return fileDescriptor_813baf511b225405, []int{2} +} + +func (m *SimpleMap3) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SimpleMap3.Unmarshal(m, b) +} +func (m *SimpleMap3) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SimpleMap3.Marshal(b, m, deterministic) +} +func (m *SimpleMap3) XXX_Merge(src proto.Message) { + xxx_messageInfo_SimpleMap3.Merge(m, src) +} +func (m *SimpleMap3) XXX_Size() int { + return xxx_messageInfo_SimpleMap3.Size(m) +} +func (m *SimpleMap3) XXX_DiscardUnknown() { + xxx_messageInfo_SimpleMap3.DiscardUnknown(m) +} + +var xxx_messageInfo_SimpleMap3 proto.InternalMessageInfo + +func (m *SimpleMap3) GetStringy() map[string]string { + if m != nil { + return m.Stringy + } + return nil +} + +type SimpleNull3 struct { + Simple *Simple3 `protobuf:"bytes,1,opt,name=simple,proto3" json:"simple,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SimpleNull3) Reset() { *m = SimpleNull3{} } +func (m *SimpleNull3) String() string { return proto.CompactTextString(m) } +func (*SimpleNull3) ProtoMessage() {} +func (*SimpleNull3) Descriptor() ([]byte, []int) { + return fileDescriptor_813baf511b225405, []int{3} +} + +func (m *SimpleNull3) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SimpleNull3.Unmarshal(m, b) +} +func (m *SimpleNull3) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SimpleNull3.Marshal(b, m, deterministic) +} +func (m *SimpleNull3) XXX_Merge(src proto.Message) { + xxx_messageInfo_SimpleNull3.Merge(m, src) +} +func (m *SimpleNull3) XXX_Size() int { + return xxx_messageInfo_SimpleNull3.Size(m) +} +func (m *SimpleNull3) XXX_DiscardUnknown() { + xxx_messageInfo_SimpleNull3.DiscardUnknown(m) +} + +var xxx_messageInfo_SimpleNull3 proto.InternalMessageInfo + +func (m *SimpleNull3) GetSimple() *Simple3 { + if m != nil { + return m.Simple + } + return nil +} + +type Mappy struct { + Nummy map[int64]int32 `protobuf:"bytes,1,rep,name=nummy,proto3" json:"nummy,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Strry map[string]string `protobuf:"bytes,2,rep,name=strry,proto3" json:"strry,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Objjy map[int32]*Simple3 `protobuf:"bytes,3,rep,name=objjy,proto3" json:"objjy,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Buggy map[int64]string `protobuf:"bytes,4,rep,name=buggy,proto3" json:"buggy,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Booly map[bool]bool `protobuf:"bytes,5,rep,name=booly,proto3" json:"booly,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + Enumy map[string]Numeral `protobuf:"bytes,6,rep,name=enumy,proto3" json:"enumy,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3,enum=jsonpb_test.Numeral"` + S32Booly map[int32]bool `protobuf:"bytes,7,rep,name=s32booly,proto3" json:"s32booly,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + S64Booly map[int64]bool `protobuf:"bytes,8,rep,name=s64booly,proto3" json:"s64booly,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + U32Booly map[uint32]bool `protobuf:"bytes,9,rep,name=u32booly,proto3" json:"u32booly,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + U64Booly map[uint64]bool `protobuf:"bytes,10,rep,name=u64booly,proto3" json:"u64booly,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Mappy) Reset() { *m = Mappy{} } +func (m *Mappy) String() string { return proto.CompactTextString(m) } +func (*Mappy) ProtoMessage() {} +func (*Mappy) Descriptor() ([]byte, []int) { + return fileDescriptor_813baf511b225405, []int{4} +} + +func (m *Mappy) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Mappy.Unmarshal(m, b) +} +func (m *Mappy) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Mappy.Marshal(b, m, deterministic) +} +func (m *Mappy) XXX_Merge(src proto.Message) { + xxx_messageInfo_Mappy.Merge(m, src) +} +func (m *Mappy) XXX_Size() int { + return xxx_messageInfo_Mappy.Size(m) +} +func (m *Mappy) XXX_DiscardUnknown() { + xxx_messageInfo_Mappy.DiscardUnknown(m) +} + +var xxx_messageInfo_Mappy proto.InternalMessageInfo + +func (m *Mappy) GetNummy() map[int64]int32 { + if m != nil { + return m.Nummy + } + return nil +} + +func (m *Mappy) GetStrry() map[string]string { + if m != nil { + return m.Strry + } + return nil +} + +func (m *Mappy) GetObjjy() map[int32]*Simple3 { + if m != nil { + return m.Objjy + } + return nil +} + +func (m *Mappy) GetBuggy() map[int64]string { + if m != nil { + return m.Buggy + } + return nil +} + +func (m *Mappy) GetBooly() map[bool]bool { + if m != nil { + return m.Booly + } + return nil +} + +func (m *Mappy) GetEnumy() map[string]Numeral { + if m != nil { + return m.Enumy + } + return nil +} + +func (m *Mappy) GetS32Booly() map[int32]bool { + if m != nil { + return m.S32Booly + } + return nil +} + +func (m *Mappy) GetS64Booly() map[int64]bool { + if m != nil { + return m.S64Booly + } + return nil +} + +func (m *Mappy) GetU32Booly() map[uint32]bool { + if m != nil { + return m.U32Booly + } + return nil +} + +func (m *Mappy) GetU64Booly() map[uint64]bool { + if m != nil { + return m.U64Booly + } + return nil +} + +func init() { + proto.RegisterEnum("jsonpb_test.Numeral", Numeral_name, Numeral_value) + proto.RegisterType((*Simple3)(nil), "jsonpb_test.Simple3") + proto.RegisterType((*SimpleSlice3)(nil), "jsonpb_test.SimpleSlice3") + proto.RegisterType((*SimpleMap3)(nil), "jsonpb_test.SimpleMap3") + proto.RegisterMapType((map[string]string)(nil), "jsonpb_test.SimpleMap3.StringyEntry") + proto.RegisterType((*SimpleNull3)(nil), "jsonpb_test.SimpleNull3") + proto.RegisterType((*Mappy)(nil), "jsonpb_test.Mappy") + proto.RegisterMapType((map[bool]bool)(nil), "jsonpb_test.Mappy.BoolyEntry") + proto.RegisterMapType((map[int64]string)(nil), "jsonpb_test.Mappy.BuggyEntry") + proto.RegisterMapType((map[string]Numeral)(nil), "jsonpb_test.Mappy.EnumyEntry") + proto.RegisterMapType((map[int64]int32)(nil), "jsonpb_test.Mappy.NummyEntry") + proto.RegisterMapType((map[int32]*Simple3)(nil), "jsonpb_test.Mappy.ObjjyEntry") + proto.RegisterMapType((map[int32]bool)(nil), "jsonpb_test.Mappy.S32boolyEntry") + proto.RegisterMapType((map[int64]bool)(nil), "jsonpb_test.Mappy.S64boolyEntry") + proto.RegisterMapType((map[string]string)(nil), "jsonpb_test.Mappy.StrryEntry") + proto.RegisterMapType((map[uint32]bool)(nil), "jsonpb_test.Mappy.U32boolyEntry") + proto.RegisterMapType((map[uint64]bool)(nil), "jsonpb_test.Mappy.U64boolyEntry") +} + +func init() { proto.RegisterFile("jsonpb_proto/test3.proto", fileDescriptor_813baf511b225405) } + +var fileDescriptor_813baf511b225405 = []byte{ + // 563 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x95, 0xdd, 0x8a, 0xd3, 0x40, + 0x14, 0xc7, 0x4d, 0xbb, 0x69, 0x9b, 0xd3, 0x5d, 0x29, 0xc3, 0x22, 0xa1, 0x22, 0x94, 0x22, 0xb2, + 0x2c, 0x9a, 0x40, 0x23, 0xb2, 0x6c, 0x55, 0x68, 0x65, 0x2f, 0x44, 0x9a, 0x42, 0x4a, 0x11, 0xbc, + 0x91, 0x64, 0x8d, 0x31, 0x35, 0x5f, 0x24, 0x19, 0x21, 0x6f, 0xe0, 0x2b, 0xf9, 0x76, 0x32, 0x1f, + 0xd9, 0x4c, 0x4a, 0x86, 0xea, 0xd5, 0x9e, 0x99, 0xf3, 0xff, 0xe5, 0x7c, 0xec, 0xbf, 0x0c, 0xe8, + 0x87, 0x22, 0x4d, 0x32, 0xef, 0x6b, 0x96, 0xa7, 0x65, 0x6a, 0x96, 0x7e, 0x51, 0x5a, 0x06, 0x8d, + 0xd1, 0x98, 0x67, 0xc8, 0xdd, 0xfc, 0x29, 0x0c, 0x77, 0x61, 0x9c, 0x45, 0xbe, 0x85, 0x26, 0xd0, + 0xff, 0x86, 0x3d, 0x5d, 0x99, 0x29, 0x57, 0x8a, 0x43, 0xc2, 0xf9, 0x0b, 0x38, 0x67, 0xc9, 0x5d, + 0x14, 0xde, 0xfb, 0x16, 0x7a, 0x02, 0x83, 0x82, 0x44, 0x85, 0xae, 0xcc, 0xfa, 0x57, 0x9a, 0xc3, + 0x4f, 0xf3, 0xdf, 0x0a, 0x00, 0x13, 0x6e, 0xdc, 0xcc, 0x42, 0xef, 0x61, 0x58, 0x94, 0x79, 0x98, + 0x04, 0x15, 0xd5, 0x8d, 0x17, 0xcf, 0x0d, 0xa1, 0xa4, 0xd1, 0x28, 0x8d, 0x1d, 0x93, 0xdd, 0x25, + 0x65, 0x5e, 0x39, 0x35, 0x34, 0xbd, 0x85, 0x73, 0x31, 0x41, 0x1a, 0xfb, 0xe9, 0x57, 0xb4, 0x31, + 0xcd, 0x21, 0x21, 0xba, 0x04, 0xf5, 0x97, 0x1b, 0x61, 0x5f, 0xef, 0xd1, 0x3b, 0x76, 0xb8, 0xed, + 0xdd, 0x28, 0xf3, 0x25, 0x8c, 0xd9, 0xf7, 0x6d, 0x1c, 0x45, 0x16, 0x7a, 0x09, 0x83, 0x82, 0x1e, + 0x29, 0x3d, 0x5e, 0x5c, 0x76, 0x74, 0x62, 0x39, 0x5c, 0x33, 0xff, 0xa3, 0x81, 0xba, 0x71, 0xb3, + 0xac, 0x42, 0x16, 0xa8, 0x09, 0x8e, 0xe3, 0x7a, 0x80, 0x67, 0x2d, 0x8c, 0x4a, 0x0c, 0x9b, 0xe4, + 0x59, 0xe7, 0x4c, 0x4b, 0xa0, 0xa2, 0xcc, 0xf3, 0x4a, 0xef, 0x49, 0xa1, 0x1d, 0xc9, 0x73, 0x88, + 0x6a, 0x09, 0x94, 0x7a, 0x87, 0x43, 0xa5, 0xf7, 0xa5, 0xd0, 0x96, 0xe4, 0x39, 0x44, 0xb5, 0x04, + 0xf2, 0x70, 0x10, 0x54, 0xfa, 0x99, 0x14, 0x5a, 0x93, 0x3c, 0x87, 0xa8, 0x96, 0x42, 0x69, 0x1a, + 0x55, 0xba, 0x2a, 0x87, 0x48, 0xbe, 0x86, 0x48, 0x4c, 0x20, 0x3f, 0xc1, 0x71, 0xa5, 0x0f, 0xa4, + 0xd0, 0x1d, 0xc9, 0x73, 0x88, 0x6a, 0xd1, 0x5b, 0x18, 0x15, 0xd6, 0x82, 0x15, 0x1b, 0x52, 0x6e, + 0xd6, 0xb5, 0x0b, 0x2e, 0x61, 0xe8, 0x03, 0x41, 0xe9, 0x37, 0xaf, 0x19, 0x3d, 0x92, 0xd3, 0x5c, + 0x52, 0xd3, 0xfc, 0x48, 0x68, 0x5c, 0xd7, 0xd6, 0xa4, 0xf4, 0xbe, 0x5d, 0x1b, 0x0b, 0xb5, 0x71, + 0x5d, 0x1b, 0xe4, 0x74, 0xbb, 0x76, 0x4d, 0x4c, 0x6f, 0x00, 0x1a, 0x57, 0x88, 0xb6, 0xed, 0x77, + 0xd8, 0x56, 0x15, 0x6c, 0x4b, 0xc8, 0xc6, 0x1a, 0xff, 0x63, 0xf8, 0xa9, 0x0d, 0xd0, 0xf8, 0x43, + 0x24, 0x55, 0x46, 0x5e, 0x8b, 0xa4, 0xec, 0x07, 0xd0, 0xee, 0xa4, 0xb1, 0xce, 0xa9, 0x19, 0xb4, + 0x63, 0xf2, 0x61, 0x2b, 0x22, 0x39, 0xea, 0x20, 0x47, 0x47, 0x33, 0x34, 0x26, 0xea, 0x98, 0xbe, + 0x35, 0xc3, 0xe3, 0xa3, 0x19, 0x6c, 0x1c, 0xfb, 0xb9, 0x1b, 0x89, 0xdf, 0x5b, 0xc2, 0x45, 0xcb, + 0x5c, 0x1d, 0x6b, 0x91, 0x37, 0x43, 0x60, 0xf1, 0xff, 0x7b, 0x6a, 0x07, 0xc7, 0xf0, 0x5e, 0x56, + 0xf9, 0xe2, 0x5f, 0x60, 0x59, 0xe5, 0xb3, 0x13, 0xf0, 0xf5, 0x2b, 0x18, 0xf2, 0x4d, 0xa0, 0x31, + 0x0c, 0xf7, 0xf6, 0x27, 0x7b, 0xfb, 0xd9, 0x9e, 0x3c, 0x42, 0x00, 0x83, 0x95, 0xb3, 0x5a, 0x7f, + 0xfc, 0x30, 0x51, 0x90, 0x06, 0xaa, 0xb3, 0xdd, 0xac, 0xec, 0x49, 0x6f, 0xfd, 0xee, 0xcb, 0x32, + 0x08, 0xcb, 0x1f, 0xd8, 0x33, 0xee, 0xd3, 0xd8, 0x0c, 0xd2, 0xc8, 0x4d, 0x02, 0x93, 0xbe, 0x0f, + 0x1e, 0xfe, 0x6e, 0x86, 0x49, 0xe9, 0xe7, 0x89, 0x1b, 0xd1, 0x77, 0x83, 0xde, 0x16, 0xa6, 0xf8, + 0x9e, 0x78, 0x03, 0xfa, 0xc7, 0xfa, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x7c, 0xda, 0x44, 0x24, 0x66, + 0x06, 0x00, 0x00, +} diff --git a/pkg/golang-protobuf/internal/testprotos/jsonpb_proto/test3.proto b/pkg/golang-protobuf/internal/testprotos/jsonpb_proto/test3.proto new file mode 100644 index 000000000..dbeb2b589 --- /dev/null +++ b/pkg/golang-protobuf/internal/testprotos/jsonpb_proto/test3.proto @@ -0,0 +1,44 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +syntax = "proto3"; + +option go_package = "github.com/golang/protobuf/internal/testprotos/jsonpb_proto"; + +package jsonpb_test; + +message Simple3 { + double dub = 1; +} + +message SimpleSlice3 { + repeated string slices = 1; +} + +message SimpleMap3 { + map stringy = 1; +} + +message SimpleNull3 { + Simple3 simple = 1; +} + +enum Numeral { + UNKNOWN = 0; + ARABIC = 1; + ROMAN = 2; +} + +message Mappy { + map nummy = 1; + map strry = 2; + map objjy = 3; + map buggy = 4; + map booly = 5; + map enumy = 6; + map s32booly = 7; + map s64booly = 8; + map u32booly = 9; + map u64booly = 10; +} diff --git a/pkg/golang-protobuf/internal/testprotos/proto2_proto/test.pb.go b/pkg/golang-protobuf/internal/testprotos/proto2_proto/test.pb.go new file mode 100644 index 000000000..cd202f971 --- /dev/null +++ b/pkg/golang-protobuf/internal/testprotos/proto2_proto/test.pb.go @@ -0,0 +1,4356 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: proto2_proto/test.proto + +package proto2_proto + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type FOO int32 + +const ( + FOO_FOO1 FOO = 1 +) + +var FOO_name = map[int32]string{ + 1: "FOO1", +} + +var FOO_value = map[string]int32{ + "FOO1": 1, +} + +func (x FOO) Enum() *FOO { + p := new(FOO) + *p = x + return p +} + +func (x FOO) String() string { + return proto.EnumName(FOO_name, int32(x)) +} + +func (x *FOO) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FOO_value, data, "FOO") + if err != nil { + return err + } + *x = FOO(value) + return nil +} + +func (FOO) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{0} +} + +// An enum, for completeness. +type GoTest_KIND int32 + +const ( + GoTest_VOID GoTest_KIND = 0 + // Basic types + GoTest_BOOL GoTest_KIND = 1 + GoTest_BYTES GoTest_KIND = 2 + GoTest_FINGERPRINT GoTest_KIND = 3 + GoTest_FLOAT GoTest_KIND = 4 + GoTest_INT GoTest_KIND = 5 + GoTest_STRING GoTest_KIND = 6 + GoTest_TIME GoTest_KIND = 7 + // Groupings + GoTest_TUPLE GoTest_KIND = 8 + GoTest_ARRAY GoTest_KIND = 9 + GoTest_MAP GoTest_KIND = 10 + // Table types + GoTest_TABLE GoTest_KIND = 11 + // Functions + GoTest_FUNCTION GoTest_KIND = 12 +) + +var GoTest_KIND_name = map[int32]string{ + 0: "VOID", + 1: "BOOL", + 2: "BYTES", + 3: "FINGERPRINT", + 4: "FLOAT", + 5: "INT", + 6: "STRING", + 7: "TIME", + 8: "TUPLE", + 9: "ARRAY", + 10: "MAP", + 11: "TABLE", + 12: "FUNCTION", +} + +var GoTest_KIND_value = map[string]int32{ + "VOID": 0, + "BOOL": 1, + "BYTES": 2, + "FINGERPRINT": 3, + "FLOAT": 4, + "INT": 5, + "STRING": 6, + "TIME": 7, + "TUPLE": 8, + "ARRAY": 9, + "MAP": 10, + "TABLE": 11, + "FUNCTION": 12, +} + +func (x GoTest_KIND) Enum() *GoTest_KIND { + p := new(GoTest_KIND) + *p = x + return p +} + +func (x GoTest_KIND) String() string { + return proto.EnumName(GoTest_KIND_name, int32(x)) +} + +func (x *GoTest_KIND) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(GoTest_KIND_value, data, "GoTest_KIND") + if err != nil { + return err + } + *x = GoTest_KIND(value) + return nil +} + +func (GoTest_KIND) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{2, 0} +} + +type MyMessage_Color int32 + +const ( + MyMessage_RED MyMessage_Color = 0 + MyMessage_GREEN MyMessage_Color = 1 + MyMessage_BLUE MyMessage_Color = 2 +) + +var MyMessage_Color_name = map[int32]string{ + 0: "RED", + 1: "GREEN", + 2: "BLUE", +} + +var MyMessage_Color_value = map[string]int32{ + "RED": 0, + "GREEN": 1, + "BLUE": 2, +} + +func (x MyMessage_Color) Enum() *MyMessage_Color { + p := new(MyMessage_Color) + *p = x + return p +} + +func (x MyMessage_Color) String() string { + return proto.EnumName(MyMessage_Color_name, int32(x)) +} + +func (x *MyMessage_Color) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(MyMessage_Color_value, data, "MyMessage_Color") + if err != nil { + return err + } + *x = MyMessage_Color(value) + return nil +} + +func (MyMessage_Color) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{13, 0} +} + +type DefaultsMessage_DefaultsEnum int32 + +const ( + DefaultsMessage_ZERO DefaultsMessage_DefaultsEnum = 0 + DefaultsMessage_ONE DefaultsMessage_DefaultsEnum = 1 + DefaultsMessage_TWO DefaultsMessage_DefaultsEnum = 2 +) + +var DefaultsMessage_DefaultsEnum_name = map[int32]string{ + 0: "ZERO", + 1: "ONE", + 2: "TWO", +} + +var DefaultsMessage_DefaultsEnum_value = map[string]int32{ + "ZERO": 0, + "ONE": 1, + "TWO": 2, +} + +func (x DefaultsMessage_DefaultsEnum) Enum() *DefaultsMessage_DefaultsEnum { + p := new(DefaultsMessage_DefaultsEnum) + *p = x + return p +} + +func (x DefaultsMessage_DefaultsEnum) String() string { + return proto.EnumName(DefaultsMessage_DefaultsEnum_name, int32(x)) +} + +func (x *DefaultsMessage_DefaultsEnum) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(DefaultsMessage_DefaultsEnum_value, data, "DefaultsMessage_DefaultsEnum") + if err != nil { + return err + } + *x = DefaultsMessage_DefaultsEnum(value) + return nil +} + +func (DefaultsMessage_DefaultsEnum) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{16, 0} +} + +type Defaults_Color int32 + +const ( + Defaults_RED Defaults_Color = 0 + Defaults_GREEN Defaults_Color = 1 + Defaults_BLUE Defaults_Color = 2 +) + +var Defaults_Color_name = map[int32]string{ + 0: "RED", + 1: "GREEN", + 2: "BLUE", +} + +var Defaults_Color_value = map[string]int32{ + "RED": 0, + "GREEN": 1, + "BLUE": 2, +} + +func (x Defaults_Color) Enum() *Defaults_Color { + p := new(Defaults_Color) + *p = x + return p +} + +func (x Defaults_Color) String() string { + return proto.EnumName(Defaults_Color_name, int32(x)) +} + +func (x *Defaults_Color) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Defaults_Color_value, data, "Defaults_Color") + if err != nil { + return err + } + *x = Defaults_Color(value) + return nil +} + +func (Defaults_Color) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{20, 0} +} + +type RepeatedEnum_Color int32 + +const ( + RepeatedEnum_RED RepeatedEnum_Color = 1 +) + +var RepeatedEnum_Color_name = map[int32]string{ + 1: "RED", +} + +var RepeatedEnum_Color_value = map[string]int32{ + "RED": 1, +} + +func (x RepeatedEnum_Color) Enum() *RepeatedEnum_Color { + p := new(RepeatedEnum_Color) + *p = x + return p +} + +func (x RepeatedEnum_Color) String() string { + return proto.EnumName(RepeatedEnum_Color_name, int32(x)) +} + +func (x *RepeatedEnum_Color) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(RepeatedEnum_Color_value, data, "RepeatedEnum_Color") + if err != nil { + return err + } + *x = RepeatedEnum_Color(value) + return nil +} + +func (RepeatedEnum_Color) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{22, 0} +} + +type GoEnum struct { + Foo *FOO `protobuf:"varint,1,req,name=foo,enum=proto2_test.FOO" json:"foo,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GoEnum) Reset() { *m = GoEnum{} } +func (m *GoEnum) String() string { return proto.CompactTextString(m) } +func (*GoEnum) ProtoMessage() {} +func (*GoEnum) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{0} +} + +func (m *GoEnum) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GoEnum.Unmarshal(m, b) +} +func (m *GoEnum) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GoEnum.Marshal(b, m, deterministic) +} +func (m *GoEnum) XXX_Merge(src proto.Message) { + xxx_messageInfo_GoEnum.Merge(m, src) +} +func (m *GoEnum) XXX_Size() int { + return xxx_messageInfo_GoEnum.Size(m) +} +func (m *GoEnum) XXX_DiscardUnknown() { + xxx_messageInfo_GoEnum.DiscardUnknown(m) +} + +var xxx_messageInfo_GoEnum proto.InternalMessageInfo + +func (m *GoEnum) GetFoo() FOO { + if m != nil && m.Foo != nil { + return *m.Foo + } + return FOO_FOO1 +} + +type GoTestField struct { + Label *string `protobuf:"bytes,1,req,name=Label" json:"Label,omitempty"` + Type *string `protobuf:"bytes,2,req,name=Type" json:"Type,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GoTestField) Reset() { *m = GoTestField{} } +func (m *GoTestField) String() string { return proto.CompactTextString(m) } +func (*GoTestField) ProtoMessage() {} +func (*GoTestField) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{1} +} + +func (m *GoTestField) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GoTestField.Unmarshal(m, b) +} +func (m *GoTestField) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GoTestField.Marshal(b, m, deterministic) +} +func (m *GoTestField) XXX_Merge(src proto.Message) { + xxx_messageInfo_GoTestField.Merge(m, src) +} +func (m *GoTestField) XXX_Size() int { + return xxx_messageInfo_GoTestField.Size(m) +} +func (m *GoTestField) XXX_DiscardUnknown() { + xxx_messageInfo_GoTestField.DiscardUnknown(m) +} + +var xxx_messageInfo_GoTestField proto.InternalMessageInfo + +func (m *GoTestField) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" +} + +func (m *GoTestField) GetType() string { + if m != nil && m.Type != nil { + return *m.Type + } + return "" +} + +type GoTest struct { + // Some typical parameters + Kind *GoTest_KIND `protobuf:"varint,1,req,name=Kind,enum=proto2_test.GoTest_KIND" json:"Kind,omitempty"` + Table *string `protobuf:"bytes,2,opt,name=Table" json:"Table,omitempty"` + Param *int32 `protobuf:"varint,3,opt,name=Param" json:"Param,omitempty"` + // Required, repeated and optional foreign fields. + RequiredField *GoTestField `protobuf:"bytes,4,req,name=RequiredField" json:"RequiredField,omitempty"` + RepeatedField []*GoTestField `protobuf:"bytes,5,rep,name=RepeatedField" json:"RepeatedField,omitempty"` + OptionalField *GoTestField `protobuf:"bytes,6,opt,name=OptionalField" json:"OptionalField,omitempty"` + // Required fields of all basic types + F_BoolRequired *bool `protobuf:"varint,10,req,name=F_Bool_required,json=FBoolRequired" json:"F_Bool_required,omitempty"` + F_Int32Required *int32 `protobuf:"varint,11,req,name=F_Int32_required,json=FInt32Required" json:"F_Int32_required,omitempty"` + F_Int64Required *int64 `protobuf:"varint,12,req,name=F_Int64_required,json=FInt64Required" json:"F_Int64_required,omitempty"` + F_Fixed32Required *uint32 `protobuf:"fixed32,13,req,name=F_Fixed32_required,json=FFixed32Required" json:"F_Fixed32_required,omitempty"` + F_Fixed64Required *uint64 `protobuf:"fixed64,14,req,name=F_Fixed64_required,json=FFixed64Required" json:"F_Fixed64_required,omitempty"` + F_Uint32Required *uint32 `protobuf:"varint,15,req,name=F_Uint32_required,json=FUint32Required" json:"F_Uint32_required,omitempty"` + F_Uint64Required *uint64 `protobuf:"varint,16,req,name=F_Uint64_required,json=FUint64Required" json:"F_Uint64_required,omitempty"` + F_FloatRequired *float32 `protobuf:"fixed32,17,req,name=F_Float_required,json=FFloatRequired" json:"F_Float_required,omitempty"` + F_DoubleRequired *float64 `protobuf:"fixed64,18,req,name=F_Double_required,json=FDoubleRequired" json:"F_Double_required,omitempty"` + F_StringRequired *string `protobuf:"bytes,19,req,name=F_String_required,json=FStringRequired" json:"F_String_required,omitempty"` + F_BytesRequired []byte `protobuf:"bytes,101,req,name=F_Bytes_required,json=FBytesRequired" json:"F_Bytes_required,omitempty"` + F_Sint32Required *int32 `protobuf:"zigzag32,102,req,name=F_Sint32_required,json=FSint32Required" json:"F_Sint32_required,omitempty"` + F_Sint64Required *int64 `protobuf:"zigzag64,103,req,name=F_Sint64_required,json=FSint64Required" json:"F_Sint64_required,omitempty"` + F_Sfixed32Required *int32 `protobuf:"fixed32,104,req,name=F_Sfixed32_required,json=FSfixed32Required" json:"F_Sfixed32_required,omitempty"` + F_Sfixed64Required *int64 `protobuf:"fixed64,105,req,name=F_Sfixed64_required,json=FSfixed64Required" json:"F_Sfixed64_required,omitempty"` + // Repeated fields of all basic types + F_BoolRepeated []bool `protobuf:"varint,20,rep,name=F_Bool_repeated,json=FBoolRepeated" json:"F_Bool_repeated,omitempty"` + F_Int32Repeated []int32 `protobuf:"varint,21,rep,name=F_Int32_repeated,json=FInt32Repeated" json:"F_Int32_repeated,omitempty"` + F_Int64Repeated []int64 `protobuf:"varint,22,rep,name=F_Int64_repeated,json=FInt64Repeated" json:"F_Int64_repeated,omitempty"` + F_Fixed32Repeated []uint32 `protobuf:"fixed32,23,rep,name=F_Fixed32_repeated,json=FFixed32Repeated" json:"F_Fixed32_repeated,omitempty"` + F_Fixed64Repeated []uint64 `protobuf:"fixed64,24,rep,name=F_Fixed64_repeated,json=FFixed64Repeated" json:"F_Fixed64_repeated,omitempty"` + F_Uint32Repeated []uint32 `protobuf:"varint,25,rep,name=F_Uint32_repeated,json=FUint32Repeated" json:"F_Uint32_repeated,omitempty"` + F_Uint64Repeated []uint64 `protobuf:"varint,26,rep,name=F_Uint64_repeated,json=FUint64Repeated" json:"F_Uint64_repeated,omitempty"` + F_FloatRepeated []float32 `protobuf:"fixed32,27,rep,name=F_Float_repeated,json=FFloatRepeated" json:"F_Float_repeated,omitempty"` + F_DoubleRepeated []float64 `protobuf:"fixed64,28,rep,name=F_Double_repeated,json=FDoubleRepeated" json:"F_Double_repeated,omitempty"` + F_StringRepeated []string `protobuf:"bytes,29,rep,name=F_String_repeated,json=FStringRepeated" json:"F_String_repeated,omitempty"` + F_BytesRepeated [][]byte `protobuf:"bytes,201,rep,name=F_Bytes_repeated,json=FBytesRepeated" json:"F_Bytes_repeated,omitempty"` + F_Sint32Repeated []int32 `protobuf:"zigzag32,202,rep,name=F_Sint32_repeated,json=FSint32Repeated" json:"F_Sint32_repeated,omitempty"` + F_Sint64Repeated []int64 `protobuf:"zigzag64,203,rep,name=F_Sint64_repeated,json=FSint64Repeated" json:"F_Sint64_repeated,omitempty"` + F_Sfixed32Repeated []int32 `protobuf:"fixed32,204,rep,name=F_Sfixed32_repeated,json=FSfixed32Repeated" json:"F_Sfixed32_repeated,omitempty"` + F_Sfixed64Repeated []int64 `protobuf:"fixed64,205,rep,name=F_Sfixed64_repeated,json=FSfixed64Repeated" json:"F_Sfixed64_repeated,omitempty"` + // Optional fields of all basic types + F_BoolOptional *bool `protobuf:"varint,30,opt,name=F_Bool_optional,json=FBoolOptional" json:"F_Bool_optional,omitempty"` + F_Int32Optional *int32 `protobuf:"varint,31,opt,name=F_Int32_optional,json=FInt32Optional" json:"F_Int32_optional,omitempty"` + F_Int64Optional *int64 `protobuf:"varint,32,opt,name=F_Int64_optional,json=FInt64Optional" json:"F_Int64_optional,omitempty"` + F_Fixed32Optional *uint32 `protobuf:"fixed32,33,opt,name=F_Fixed32_optional,json=FFixed32Optional" json:"F_Fixed32_optional,omitempty"` + F_Fixed64Optional *uint64 `protobuf:"fixed64,34,opt,name=F_Fixed64_optional,json=FFixed64Optional" json:"F_Fixed64_optional,omitempty"` + F_Uint32Optional *uint32 `protobuf:"varint,35,opt,name=F_Uint32_optional,json=FUint32Optional" json:"F_Uint32_optional,omitempty"` + F_Uint64Optional *uint64 `protobuf:"varint,36,opt,name=F_Uint64_optional,json=FUint64Optional" json:"F_Uint64_optional,omitempty"` + F_FloatOptional *float32 `protobuf:"fixed32,37,opt,name=F_Float_optional,json=FFloatOptional" json:"F_Float_optional,omitempty"` + F_DoubleOptional *float64 `protobuf:"fixed64,38,opt,name=F_Double_optional,json=FDoubleOptional" json:"F_Double_optional,omitempty"` + F_StringOptional *string `protobuf:"bytes,39,opt,name=F_String_optional,json=FStringOptional" json:"F_String_optional,omitempty"` + F_BytesOptional []byte `protobuf:"bytes,301,opt,name=F_Bytes_optional,json=FBytesOptional" json:"F_Bytes_optional,omitempty"` + F_Sint32Optional *int32 `protobuf:"zigzag32,302,opt,name=F_Sint32_optional,json=FSint32Optional" json:"F_Sint32_optional,omitempty"` + F_Sint64Optional *int64 `protobuf:"zigzag64,303,opt,name=F_Sint64_optional,json=FSint64Optional" json:"F_Sint64_optional,omitempty"` + F_Sfixed32Optional *int32 `protobuf:"fixed32,304,opt,name=F_Sfixed32_optional,json=FSfixed32Optional" json:"F_Sfixed32_optional,omitempty"` + F_Sfixed64Optional *int64 `protobuf:"fixed64,305,opt,name=F_Sfixed64_optional,json=FSfixed64Optional" json:"F_Sfixed64_optional,omitempty"` + // Default-valued fields of all basic types + F_BoolDefaulted *bool `protobuf:"varint,40,opt,name=F_Bool_defaulted,json=FBoolDefaulted,def=1" json:"F_Bool_defaulted,omitempty"` + F_Int32Defaulted *int32 `protobuf:"varint,41,opt,name=F_Int32_defaulted,json=FInt32Defaulted,def=32" json:"F_Int32_defaulted,omitempty"` + F_Int64Defaulted *int64 `protobuf:"varint,42,opt,name=F_Int64_defaulted,json=FInt64Defaulted,def=64" json:"F_Int64_defaulted,omitempty"` + F_Fixed32Defaulted *uint32 `protobuf:"fixed32,43,opt,name=F_Fixed32_defaulted,json=FFixed32Defaulted,def=320" json:"F_Fixed32_defaulted,omitempty"` + F_Fixed64Defaulted *uint64 `protobuf:"fixed64,44,opt,name=F_Fixed64_defaulted,json=FFixed64Defaulted,def=640" json:"F_Fixed64_defaulted,omitempty"` + F_Uint32Defaulted *uint32 `protobuf:"varint,45,opt,name=F_Uint32_defaulted,json=FUint32Defaulted,def=3200" json:"F_Uint32_defaulted,omitempty"` + F_Uint64Defaulted *uint64 `protobuf:"varint,46,opt,name=F_Uint64_defaulted,json=FUint64Defaulted,def=6400" json:"F_Uint64_defaulted,omitempty"` + F_FloatDefaulted *float32 `protobuf:"fixed32,47,opt,name=F_Float_defaulted,json=FFloatDefaulted,def=314159" json:"F_Float_defaulted,omitempty"` + F_DoubleDefaulted *float64 `protobuf:"fixed64,48,opt,name=F_Double_defaulted,json=FDoubleDefaulted,def=271828" json:"F_Double_defaulted,omitempty"` + F_StringDefaulted *string `protobuf:"bytes,49,opt,name=F_String_defaulted,json=FStringDefaulted,def=hello, \"world!\"\n" json:"F_String_defaulted,omitempty"` + F_BytesDefaulted []byte `protobuf:"bytes,401,opt,name=F_Bytes_defaulted,json=FBytesDefaulted,def=Bignose" json:"F_Bytes_defaulted,omitempty"` + F_Sint32Defaulted *int32 `protobuf:"zigzag32,402,opt,name=F_Sint32_defaulted,json=FSint32Defaulted,def=-32" json:"F_Sint32_defaulted,omitempty"` + F_Sint64Defaulted *int64 `protobuf:"zigzag64,403,opt,name=F_Sint64_defaulted,json=FSint64Defaulted,def=-64" json:"F_Sint64_defaulted,omitempty"` + F_Sfixed32Defaulted *int32 `protobuf:"fixed32,404,opt,name=F_Sfixed32_defaulted,json=FSfixed32Defaulted,def=-32" json:"F_Sfixed32_defaulted,omitempty"` + F_Sfixed64Defaulted *int64 `protobuf:"fixed64,405,opt,name=F_Sfixed64_defaulted,json=FSfixed64Defaulted,def=-64" json:"F_Sfixed64_defaulted,omitempty"` + // Packed repeated fields (no string or bytes). + F_BoolRepeatedPacked []bool `protobuf:"varint,50,rep,packed,name=F_Bool_repeated_packed,json=FBoolRepeatedPacked" json:"F_Bool_repeated_packed,omitempty"` + F_Int32RepeatedPacked []int32 `protobuf:"varint,51,rep,packed,name=F_Int32_repeated_packed,json=FInt32RepeatedPacked" json:"F_Int32_repeated_packed,omitempty"` + F_Int64RepeatedPacked []int64 `protobuf:"varint,52,rep,packed,name=F_Int64_repeated_packed,json=FInt64RepeatedPacked" json:"F_Int64_repeated_packed,omitempty"` + F_Fixed32RepeatedPacked []uint32 `protobuf:"fixed32,53,rep,packed,name=F_Fixed32_repeated_packed,json=FFixed32RepeatedPacked" json:"F_Fixed32_repeated_packed,omitempty"` + F_Fixed64RepeatedPacked []uint64 `protobuf:"fixed64,54,rep,packed,name=F_Fixed64_repeated_packed,json=FFixed64RepeatedPacked" json:"F_Fixed64_repeated_packed,omitempty"` + F_Uint32RepeatedPacked []uint32 `protobuf:"varint,55,rep,packed,name=F_Uint32_repeated_packed,json=FUint32RepeatedPacked" json:"F_Uint32_repeated_packed,omitempty"` + F_Uint64RepeatedPacked []uint64 `protobuf:"varint,56,rep,packed,name=F_Uint64_repeated_packed,json=FUint64RepeatedPacked" json:"F_Uint64_repeated_packed,omitempty"` + F_FloatRepeatedPacked []float32 `protobuf:"fixed32,57,rep,packed,name=F_Float_repeated_packed,json=FFloatRepeatedPacked" json:"F_Float_repeated_packed,omitempty"` + F_DoubleRepeatedPacked []float64 `protobuf:"fixed64,58,rep,packed,name=F_Double_repeated_packed,json=FDoubleRepeatedPacked" json:"F_Double_repeated_packed,omitempty"` + F_Sint32RepeatedPacked []int32 `protobuf:"zigzag32,502,rep,packed,name=F_Sint32_repeated_packed,json=FSint32RepeatedPacked" json:"F_Sint32_repeated_packed,omitempty"` + F_Sint64RepeatedPacked []int64 `protobuf:"zigzag64,503,rep,packed,name=F_Sint64_repeated_packed,json=FSint64RepeatedPacked" json:"F_Sint64_repeated_packed,omitempty"` + F_Sfixed32RepeatedPacked []int32 `protobuf:"fixed32,504,rep,packed,name=F_Sfixed32_repeated_packed,json=FSfixed32RepeatedPacked" json:"F_Sfixed32_repeated_packed,omitempty"` + F_Sfixed64RepeatedPacked []int64 `protobuf:"fixed64,505,rep,packed,name=F_Sfixed64_repeated_packed,json=FSfixed64RepeatedPacked" json:"F_Sfixed64_repeated_packed,omitempty"` + Requiredgroup *GoTest_RequiredGroup `protobuf:"group,70,req,name=RequiredGroup,json=requiredgroup" json:"requiredgroup,omitempty"` + Repeatedgroup []*GoTest_RepeatedGroup `protobuf:"group,80,rep,name=RepeatedGroup,json=repeatedgroup" json:"repeatedgroup,omitempty"` + Optionalgroup *GoTest_OptionalGroup `protobuf:"group,90,opt,name=OptionalGroup,json=optionalgroup" json:"optionalgroup,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GoTest) Reset() { *m = GoTest{} } +func (m *GoTest) String() string { return proto.CompactTextString(m) } +func (*GoTest) ProtoMessage() {} +func (*GoTest) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{2} +} + +func (m *GoTest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GoTest.Unmarshal(m, b) +} +func (m *GoTest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GoTest.Marshal(b, m, deterministic) +} +func (m *GoTest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GoTest.Merge(m, src) +} +func (m *GoTest) XXX_Size() int { + return xxx_messageInfo_GoTest.Size(m) +} +func (m *GoTest) XXX_DiscardUnknown() { + xxx_messageInfo_GoTest.DiscardUnknown(m) +} + +var xxx_messageInfo_GoTest proto.InternalMessageInfo + +const Default_GoTest_F_BoolDefaulted bool = true +const Default_GoTest_F_Int32Defaulted int32 = 32 +const Default_GoTest_F_Int64Defaulted int64 = 64 +const Default_GoTest_F_Fixed32Defaulted uint32 = 320 +const Default_GoTest_F_Fixed64Defaulted uint64 = 640 +const Default_GoTest_F_Uint32Defaulted uint32 = 3200 +const Default_GoTest_F_Uint64Defaulted uint64 = 6400 +const Default_GoTest_F_FloatDefaulted float32 = 314159 +const Default_GoTest_F_DoubleDefaulted float64 = 271828 +const Default_GoTest_F_StringDefaulted string = "hello, \"world!\"\n" + +var Default_GoTest_F_BytesDefaulted []byte = []byte("Bignose") + +const Default_GoTest_F_Sint32Defaulted int32 = -32 +const Default_GoTest_F_Sint64Defaulted int64 = -64 +const Default_GoTest_F_Sfixed32Defaulted int32 = -32 +const Default_GoTest_F_Sfixed64Defaulted int64 = -64 + +func (m *GoTest) GetKind() GoTest_KIND { + if m != nil && m.Kind != nil { + return *m.Kind + } + return GoTest_VOID +} + +func (m *GoTest) GetTable() string { + if m != nil && m.Table != nil { + return *m.Table + } + return "" +} + +func (m *GoTest) GetParam() int32 { + if m != nil && m.Param != nil { + return *m.Param + } + return 0 +} + +func (m *GoTest) GetRequiredField() *GoTestField { + if m != nil { + return m.RequiredField + } + return nil +} + +func (m *GoTest) GetRepeatedField() []*GoTestField { + if m != nil { + return m.RepeatedField + } + return nil +} + +func (m *GoTest) GetOptionalField() *GoTestField { + if m != nil { + return m.OptionalField + } + return nil +} + +func (m *GoTest) GetF_BoolRequired() bool { + if m != nil && m.F_BoolRequired != nil { + return *m.F_BoolRequired + } + return false +} + +func (m *GoTest) GetF_Int32Required() int32 { + if m != nil && m.F_Int32Required != nil { + return *m.F_Int32Required + } + return 0 +} + +func (m *GoTest) GetF_Int64Required() int64 { + if m != nil && m.F_Int64Required != nil { + return *m.F_Int64Required + } + return 0 +} + +func (m *GoTest) GetF_Fixed32Required() uint32 { + if m != nil && m.F_Fixed32Required != nil { + return *m.F_Fixed32Required + } + return 0 +} + +func (m *GoTest) GetF_Fixed64Required() uint64 { + if m != nil && m.F_Fixed64Required != nil { + return *m.F_Fixed64Required + } + return 0 +} + +func (m *GoTest) GetF_Uint32Required() uint32 { + if m != nil && m.F_Uint32Required != nil { + return *m.F_Uint32Required + } + return 0 +} + +func (m *GoTest) GetF_Uint64Required() uint64 { + if m != nil && m.F_Uint64Required != nil { + return *m.F_Uint64Required + } + return 0 +} + +func (m *GoTest) GetF_FloatRequired() float32 { + if m != nil && m.F_FloatRequired != nil { + return *m.F_FloatRequired + } + return 0 +} + +func (m *GoTest) GetF_DoubleRequired() float64 { + if m != nil && m.F_DoubleRequired != nil { + return *m.F_DoubleRequired + } + return 0 +} + +func (m *GoTest) GetF_StringRequired() string { + if m != nil && m.F_StringRequired != nil { + return *m.F_StringRequired + } + return "" +} + +func (m *GoTest) GetF_BytesRequired() []byte { + if m != nil { + return m.F_BytesRequired + } + return nil +} + +func (m *GoTest) GetF_Sint32Required() int32 { + if m != nil && m.F_Sint32Required != nil { + return *m.F_Sint32Required + } + return 0 +} + +func (m *GoTest) GetF_Sint64Required() int64 { + if m != nil && m.F_Sint64Required != nil { + return *m.F_Sint64Required + } + return 0 +} + +func (m *GoTest) GetF_Sfixed32Required() int32 { + if m != nil && m.F_Sfixed32Required != nil { + return *m.F_Sfixed32Required + } + return 0 +} + +func (m *GoTest) GetF_Sfixed64Required() int64 { + if m != nil && m.F_Sfixed64Required != nil { + return *m.F_Sfixed64Required + } + return 0 +} + +func (m *GoTest) GetF_BoolRepeated() []bool { + if m != nil { + return m.F_BoolRepeated + } + return nil +} + +func (m *GoTest) GetF_Int32Repeated() []int32 { + if m != nil { + return m.F_Int32Repeated + } + return nil +} + +func (m *GoTest) GetF_Int64Repeated() []int64 { + if m != nil { + return m.F_Int64Repeated + } + return nil +} + +func (m *GoTest) GetF_Fixed32Repeated() []uint32 { + if m != nil { + return m.F_Fixed32Repeated + } + return nil +} + +func (m *GoTest) GetF_Fixed64Repeated() []uint64 { + if m != nil { + return m.F_Fixed64Repeated + } + return nil +} + +func (m *GoTest) GetF_Uint32Repeated() []uint32 { + if m != nil { + return m.F_Uint32Repeated + } + return nil +} + +func (m *GoTest) GetF_Uint64Repeated() []uint64 { + if m != nil { + return m.F_Uint64Repeated + } + return nil +} + +func (m *GoTest) GetF_FloatRepeated() []float32 { + if m != nil { + return m.F_FloatRepeated + } + return nil +} + +func (m *GoTest) GetF_DoubleRepeated() []float64 { + if m != nil { + return m.F_DoubleRepeated + } + return nil +} + +func (m *GoTest) GetF_StringRepeated() []string { + if m != nil { + return m.F_StringRepeated + } + return nil +} + +func (m *GoTest) GetF_BytesRepeated() [][]byte { + if m != nil { + return m.F_BytesRepeated + } + return nil +} + +func (m *GoTest) GetF_Sint32Repeated() []int32 { + if m != nil { + return m.F_Sint32Repeated + } + return nil +} + +func (m *GoTest) GetF_Sint64Repeated() []int64 { + if m != nil { + return m.F_Sint64Repeated + } + return nil +} + +func (m *GoTest) GetF_Sfixed32Repeated() []int32 { + if m != nil { + return m.F_Sfixed32Repeated + } + return nil +} + +func (m *GoTest) GetF_Sfixed64Repeated() []int64 { + if m != nil { + return m.F_Sfixed64Repeated + } + return nil +} + +func (m *GoTest) GetF_BoolOptional() bool { + if m != nil && m.F_BoolOptional != nil { + return *m.F_BoolOptional + } + return false +} + +func (m *GoTest) GetF_Int32Optional() int32 { + if m != nil && m.F_Int32Optional != nil { + return *m.F_Int32Optional + } + return 0 +} + +func (m *GoTest) GetF_Int64Optional() int64 { + if m != nil && m.F_Int64Optional != nil { + return *m.F_Int64Optional + } + return 0 +} + +func (m *GoTest) GetF_Fixed32Optional() uint32 { + if m != nil && m.F_Fixed32Optional != nil { + return *m.F_Fixed32Optional + } + return 0 +} + +func (m *GoTest) GetF_Fixed64Optional() uint64 { + if m != nil && m.F_Fixed64Optional != nil { + return *m.F_Fixed64Optional + } + return 0 +} + +func (m *GoTest) GetF_Uint32Optional() uint32 { + if m != nil && m.F_Uint32Optional != nil { + return *m.F_Uint32Optional + } + return 0 +} + +func (m *GoTest) GetF_Uint64Optional() uint64 { + if m != nil && m.F_Uint64Optional != nil { + return *m.F_Uint64Optional + } + return 0 +} + +func (m *GoTest) GetF_FloatOptional() float32 { + if m != nil && m.F_FloatOptional != nil { + return *m.F_FloatOptional + } + return 0 +} + +func (m *GoTest) GetF_DoubleOptional() float64 { + if m != nil && m.F_DoubleOptional != nil { + return *m.F_DoubleOptional + } + return 0 +} + +func (m *GoTest) GetF_StringOptional() string { + if m != nil && m.F_StringOptional != nil { + return *m.F_StringOptional + } + return "" +} + +func (m *GoTest) GetF_BytesOptional() []byte { + if m != nil { + return m.F_BytesOptional + } + return nil +} + +func (m *GoTest) GetF_Sint32Optional() int32 { + if m != nil && m.F_Sint32Optional != nil { + return *m.F_Sint32Optional + } + return 0 +} + +func (m *GoTest) GetF_Sint64Optional() int64 { + if m != nil && m.F_Sint64Optional != nil { + return *m.F_Sint64Optional + } + return 0 +} + +func (m *GoTest) GetF_Sfixed32Optional() int32 { + if m != nil && m.F_Sfixed32Optional != nil { + return *m.F_Sfixed32Optional + } + return 0 +} + +func (m *GoTest) GetF_Sfixed64Optional() int64 { + if m != nil && m.F_Sfixed64Optional != nil { + return *m.F_Sfixed64Optional + } + return 0 +} + +func (m *GoTest) GetF_BoolDefaulted() bool { + if m != nil && m.F_BoolDefaulted != nil { + return *m.F_BoolDefaulted + } + return Default_GoTest_F_BoolDefaulted +} + +func (m *GoTest) GetF_Int32Defaulted() int32 { + if m != nil && m.F_Int32Defaulted != nil { + return *m.F_Int32Defaulted + } + return Default_GoTest_F_Int32Defaulted +} + +func (m *GoTest) GetF_Int64Defaulted() int64 { + if m != nil && m.F_Int64Defaulted != nil { + return *m.F_Int64Defaulted + } + return Default_GoTest_F_Int64Defaulted +} + +func (m *GoTest) GetF_Fixed32Defaulted() uint32 { + if m != nil && m.F_Fixed32Defaulted != nil { + return *m.F_Fixed32Defaulted + } + return Default_GoTest_F_Fixed32Defaulted +} + +func (m *GoTest) GetF_Fixed64Defaulted() uint64 { + if m != nil && m.F_Fixed64Defaulted != nil { + return *m.F_Fixed64Defaulted + } + return Default_GoTest_F_Fixed64Defaulted +} + +func (m *GoTest) GetF_Uint32Defaulted() uint32 { + if m != nil && m.F_Uint32Defaulted != nil { + return *m.F_Uint32Defaulted + } + return Default_GoTest_F_Uint32Defaulted +} + +func (m *GoTest) GetF_Uint64Defaulted() uint64 { + if m != nil && m.F_Uint64Defaulted != nil { + return *m.F_Uint64Defaulted + } + return Default_GoTest_F_Uint64Defaulted +} + +func (m *GoTest) GetF_FloatDefaulted() float32 { + if m != nil && m.F_FloatDefaulted != nil { + return *m.F_FloatDefaulted + } + return Default_GoTest_F_FloatDefaulted +} + +func (m *GoTest) GetF_DoubleDefaulted() float64 { + if m != nil && m.F_DoubleDefaulted != nil { + return *m.F_DoubleDefaulted + } + return Default_GoTest_F_DoubleDefaulted +} + +func (m *GoTest) GetF_StringDefaulted() string { + if m != nil && m.F_StringDefaulted != nil { + return *m.F_StringDefaulted + } + return Default_GoTest_F_StringDefaulted +} + +func (m *GoTest) GetF_BytesDefaulted() []byte { + if m != nil && m.F_BytesDefaulted != nil { + return m.F_BytesDefaulted + } + return append([]byte(nil), Default_GoTest_F_BytesDefaulted...) +} + +func (m *GoTest) GetF_Sint32Defaulted() int32 { + if m != nil && m.F_Sint32Defaulted != nil { + return *m.F_Sint32Defaulted + } + return Default_GoTest_F_Sint32Defaulted +} + +func (m *GoTest) GetF_Sint64Defaulted() int64 { + if m != nil && m.F_Sint64Defaulted != nil { + return *m.F_Sint64Defaulted + } + return Default_GoTest_F_Sint64Defaulted +} + +func (m *GoTest) GetF_Sfixed32Defaulted() int32 { + if m != nil && m.F_Sfixed32Defaulted != nil { + return *m.F_Sfixed32Defaulted + } + return Default_GoTest_F_Sfixed32Defaulted +} + +func (m *GoTest) GetF_Sfixed64Defaulted() int64 { + if m != nil && m.F_Sfixed64Defaulted != nil { + return *m.F_Sfixed64Defaulted + } + return Default_GoTest_F_Sfixed64Defaulted +} + +func (m *GoTest) GetF_BoolRepeatedPacked() []bool { + if m != nil { + return m.F_BoolRepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Int32RepeatedPacked() []int32 { + if m != nil { + return m.F_Int32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Int64RepeatedPacked() []int64 { + if m != nil { + return m.F_Int64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Fixed32RepeatedPacked() []uint32 { + if m != nil { + return m.F_Fixed32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Fixed64RepeatedPacked() []uint64 { + if m != nil { + return m.F_Fixed64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Uint32RepeatedPacked() []uint32 { + if m != nil { + return m.F_Uint32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Uint64RepeatedPacked() []uint64 { + if m != nil { + return m.F_Uint64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_FloatRepeatedPacked() []float32 { + if m != nil { + return m.F_FloatRepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_DoubleRepeatedPacked() []float64 { + if m != nil { + return m.F_DoubleRepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Sint32RepeatedPacked() []int32 { + if m != nil { + return m.F_Sint32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Sint64RepeatedPacked() []int64 { + if m != nil { + return m.F_Sint64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Sfixed32RepeatedPacked() []int32 { + if m != nil { + return m.F_Sfixed32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Sfixed64RepeatedPacked() []int64 { + if m != nil { + return m.F_Sfixed64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetRequiredgroup() *GoTest_RequiredGroup { + if m != nil { + return m.Requiredgroup + } + return nil +} + +func (m *GoTest) GetRepeatedgroup() []*GoTest_RepeatedGroup { + if m != nil { + return m.Repeatedgroup + } + return nil +} + +func (m *GoTest) GetOptionalgroup() *GoTest_OptionalGroup { + if m != nil { + return m.Optionalgroup + } + return nil +} + +// Required, repeated, and optional groups. +type GoTest_RequiredGroup struct { + RequiredField *string `protobuf:"bytes,71,req,name=RequiredField" json:"RequiredField,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GoTest_RequiredGroup) Reset() { *m = GoTest_RequiredGroup{} } +func (m *GoTest_RequiredGroup) String() string { return proto.CompactTextString(m) } +func (*GoTest_RequiredGroup) ProtoMessage() {} +func (*GoTest_RequiredGroup) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{2, 0} +} + +func (m *GoTest_RequiredGroup) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GoTest_RequiredGroup.Unmarshal(m, b) +} +func (m *GoTest_RequiredGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GoTest_RequiredGroup.Marshal(b, m, deterministic) +} +func (m *GoTest_RequiredGroup) XXX_Merge(src proto.Message) { + xxx_messageInfo_GoTest_RequiredGroup.Merge(m, src) +} +func (m *GoTest_RequiredGroup) XXX_Size() int { + return xxx_messageInfo_GoTest_RequiredGroup.Size(m) +} +func (m *GoTest_RequiredGroup) XXX_DiscardUnknown() { + xxx_messageInfo_GoTest_RequiredGroup.DiscardUnknown(m) +} + +var xxx_messageInfo_GoTest_RequiredGroup proto.InternalMessageInfo + +func (m *GoTest_RequiredGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" +} + +type GoTest_RepeatedGroup struct { + RequiredField *string `protobuf:"bytes,81,req,name=RequiredField" json:"RequiredField,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GoTest_RepeatedGroup) Reset() { *m = GoTest_RepeatedGroup{} } +func (m *GoTest_RepeatedGroup) String() string { return proto.CompactTextString(m) } +func (*GoTest_RepeatedGroup) ProtoMessage() {} +func (*GoTest_RepeatedGroup) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{2, 1} +} + +func (m *GoTest_RepeatedGroup) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GoTest_RepeatedGroup.Unmarshal(m, b) +} +func (m *GoTest_RepeatedGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GoTest_RepeatedGroup.Marshal(b, m, deterministic) +} +func (m *GoTest_RepeatedGroup) XXX_Merge(src proto.Message) { + xxx_messageInfo_GoTest_RepeatedGroup.Merge(m, src) +} +func (m *GoTest_RepeatedGroup) XXX_Size() int { + return xxx_messageInfo_GoTest_RepeatedGroup.Size(m) +} +func (m *GoTest_RepeatedGroup) XXX_DiscardUnknown() { + xxx_messageInfo_GoTest_RepeatedGroup.DiscardUnknown(m) +} + +var xxx_messageInfo_GoTest_RepeatedGroup proto.InternalMessageInfo + +func (m *GoTest_RepeatedGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" +} + +type GoTest_OptionalGroup struct { + RequiredField *string `protobuf:"bytes,91,req,name=RequiredField" json:"RequiredField,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GoTest_OptionalGroup) Reset() { *m = GoTest_OptionalGroup{} } +func (m *GoTest_OptionalGroup) String() string { return proto.CompactTextString(m) } +func (*GoTest_OptionalGroup) ProtoMessage() {} +func (*GoTest_OptionalGroup) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{2, 2} +} + +func (m *GoTest_OptionalGroup) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GoTest_OptionalGroup.Unmarshal(m, b) +} +func (m *GoTest_OptionalGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GoTest_OptionalGroup.Marshal(b, m, deterministic) +} +func (m *GoTest_OptionalGroup) XXX_Merge(src proto.Message) { + xxx_messageInfo_GoTest_OptionalGroup.Merge(m, src) +} +func (m *GoTest_OptionalGroup) XXX_Size() int { + return xxx_messageInfo_GoTest_OptionalGroup.Size(m) +} +func (m *GoTest_OptionalGroup) XXX_DiscardUnknown() { + xxx_messageInfo_GoTest_OptionalGroup.DiscardUnknown(m) +} + +var xxx_messageInfo_GoTest_OptionalGroup proto.InternalMessageInfo + +func (m *GoTest_OptionalGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" +} + +// For testing a group containing a required field. +type GoTestRequiredGroupField struct { + Group *GoTestRequiredGroupField_Group `protobuf:"group,1,req,name=Group,json=group" json:"group,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GoTestRequiredGroupField) Reset() { *m = GoTestRequiredGroupField{} } +func (m *GoTestRequiredGroupField) String() string { return proto.CompactTextString(m) } +func (*GoTestRequiredGroupField) ProtoMessage() {} +func (*GoTestRequiredGroupField) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{3} +} + +func (m *GoTestRequiredGroupField) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GoTestRequiredGroupField.Unmarshal(m, b) +} +func (m *GoTestRequiredGroupField) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GoTestRequiredGroupField.Marshal(b, m, deterministic) +} +func (m *GoTestRequiredGroupField) XXX_Merge(src proto.Message) { + xxx_messageInfo_GoTestRequiredGroupField.Merge(m, src) +} +func (m *GoTestRequiredGroupField) XXX_Size() int { + return xxx_messageInfo_GoTestRequiredGroupField.Size(m) +} +func (m *GoTestRequiredGroupField) XXX_DiscardUnknown() { + xxx_messageInfo_GoTestRequiredGroupField.DiscardUnknown(m) +} + +var xxx_messageInfo_GoTestRequiredGroupField proto.InternalMessageInfo + +func (m *GoTestRequiredGroupField) GetGroup() *GoTestRequiredGroupField_Group { + if m != nil { + return m.Group + } + return nil +} + +type GoTestRequiredGroupField_Group struct { + Field *int32 `protobuf:"varint,2,req,name=Field" json:"Field,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GoTestRequiredGroupField_Group) Reset() { *m = GoTestRequiredGroupField_Group{} } +func (m *GoTestRequiredGroupField_Group) String() string { return proto.CompactTextString(m) } +func (*GoTestRequiredGroupField_Group) ProtoMessage() {} +func (*GoTestRequiredGroupField_Group) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{3, 0} +} + +func (m *GoTestRequiredGroupField_Group) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GoTestRequiredGroupField_Group.Unmarshal(m, b) +} +func (m *GoTestRequiredGroupField_Group) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GoTestRequiredGroupField_Group.Marshal(b, m, deterministic) +} +func (m *GoTestRequiredGroupField_Group) XXX_Merge(src proto.Message) { + xxx_messageInfo_GoTestRequiredGroupField_Group.Merge(m, src) +} +func (m *GoTestRequiredGroupField_Group) XXX_Size() int { + return xxx_messageInfo_GoTestRequiredGroupField_Group.Size(m) +} +func (m *GoTestRequiredGroupField_Group) XXX_DiscardUnknown() { + xxx_messageInfo_GoTestRequiredGroupField_Group.DiscardUnknown(m) +} + +var xxx_messageInfo_GoTestRequiredGroupField_Group proto.InternalMessageInfo + +func (m *GoTestRequiredGroupField_Group) GetField() int32 { + if m != nil && m.Field != nil { + return *m.Field + } + return 0 +} + +// For testing skipping of unrecognized fields. +// Numbers are all big, larger than tag numbers in GoTestField, +// the message used in the corresponding test. +type GoSkipTest struct { + SkipInt32 *int32 `protobuf:"varint,11,req,name=skip_int32,json=skipInt32" json:"skip_int32,omitempty"` + SkipFixed32 *uint32 `protobuf:"fixed32,12,req,name=skip_fixed32,json=skipFixed32" json:"skip_fixed32,omitempty"` + SkipFixed64 *uint64 `protobuf:"fixed64,13,req,name=skip_fixed64,json=skipFixed64" json:"skip_fixed64,omitempty"` + SkipString *string `protobuf:"bytes,14,req,name=skip_string,json=skipString" json:"skip_string,omitempty"` + Skipgroup *GoSkipTest_SkipGroup `protobuf:"group,15,req,name=SkipGroup,json=skipgroup" json:"skipgroup,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GoSkipTest) Reset() { *m = GoSkipTest{} } +func (m *GoSkipTest) String() string { return proto.CompactTextString(m) } +func (*GoSkipTest) ProtoMessage() {} +func (*GoSkipTest) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{4} +} + +func (m *GoSkipTest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GoSkipTest.Unmarshal(m, b) +} +func (m *GoSkipTest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GoSkipTest.Marshal(b, m, deterministic) +} +func (m *GoSkipTest) XXX_Merge(src proto.Message) { + xxx_messageInfo_GoSkipTest.Merge(m, src) +} +func (m *GoSkipTest) XXX_Size() int { + return xxx_messageInfo_GoSkipTest.Size(m) +} +func (m *GoSkipTest) XXX_DiscardUnknown() { + xxx_messageInfo_GoSkipTest.DiscardUnknown(m) +} + +var xxx_messageInfo_GoSkipTest proto.InternalMessageInfo + +func (m *GoSkipTest) GetSkipInt32() int32 { + if m != nil && m.SkipInt32 != nil { + return *m.SkipInt32 + } + return 0 +} + +func (m *GoSkipTest) GetSkipFixed32() uint32 { + if m != nil && m.SkipFixed32 != nil { + return *m.SkipFixed32 + } + return 0 +} + +func (m *GoSkipTest) GetSkipFixed64() uint64 { + if m != nil && m.SkipFixed64 != nil { + return *m.SkipFixed64 + } + return 0 +} + +func (m *GoSkipTest) GetSkipString() string { + if m != nil && m.SkipString != nil { + return *m.SkipString + } + return "" +} + +func (m *GoSkipTest) GetSkipgroup() *GoSkipTest_SkipGroup { + if m != nil { + return m.Skipgroup + } + return nil +} + +type GoSkipTest_SkipGroup struct { + GroupInt32 *int32 `protobuf:"varint,16,req,name=group_int32,json=groupInt32" json:"group_int32,omitempty"` + GroupString *string `protobuf:"bytes,17,req,name=group_string,json=groupString" json:"group_string,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GoSkipTest_SkipGroup) Reset() { *m = GoSkipTest_SkipGroup{} } +func (m *GoSkipTest_SkipGroup) String() string { return proto.CompactTextString(m) } +func (*GoSkipTest_SkipGroup) ProtoMessage() {} +func (*GoSkipTest_SkipGroup) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{4, 0} +} + +func (m *GoSkipTest_SkipGroup) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GoSkipTest_SkipGroup.Unmarshal(m, b) +} +func (m *GoSkipTest_SkipGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GoSkipTest_SkipGroup.Marshal(b, m, deterministic) +} +func (m *GoSkipTest_SkipGroup) XXX_Merge(src proto.Message) { + xxx_messageInfo_GoSkipTest_SkipGroup.Merge(m, src) +} +func (m *GoSkipTest_SkipGroup) XXX_Size() int { + return xxx_messageInfo_GoSkipTest_SkipGroup.Size(m) +} +func (m *GoSkipTest_SkipGroup) XXX_DiscardUnknown() { + xxx_messageInfo_GoSkipTest_SkipGroup.DiscardUnknown(m) +} + +var xxx_messageInfo_GoSkipTest_SkipGroup proto.InternalMessageInfo + +func (m *GoSkipTest_SkipGroup) GetGroupInt32() int32 { + if m != nil && m.GroupInt32 != nil { + return *m.GroupInt32 + } + return 0 +} + +func (m *GoSkipTest_SkipGroup) GetGroupString() string { + if m != nil && m.GroupString != nil { + return *m.GroupString + } + return "" +} + +// For testing packed/non-packed decoder switching. +// A serialized instance of one should be deserializable as the other. +type NonPackedTest struct { + A []int32 `protobuf:"varint,1,rep,name=a" json:"a,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *NonPackedTest) Reset() { *m = NonPackedTest{} } +func (m *NonPackedTest) String() string { return proto.CompactTextString(m) } +func (*NonPackedTest) ProtoMessage() {} +func (*NonPackedTest) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{5} +} + +func (m *NonPackedTest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_NonPackedTest.Unmarshal(m, b) +} +func (m *NonPackedTest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_NonPackedTest.Marshal(b, m, deterministic) +} +func (m *NonPackedTest) XXX_Merge(src proto.Message) { + xxx_messageInfo_NonPackedTest.Merge(m, src) +} +func (m *NonPackedTest) XXX_Size() int { + return xxx_messageInfo_NonPackedTest.Size(m) +} +func (m *NonPackedTest) XXX_DiscardUnknown() { + xxx_messageInfo_NonPackedTest.DiscardUnknown(m) +} + +var xxx_messageInfo_NonPackedTest proto.InternalMessageInfo + +func (m *NonPackedTest) GetA() []int32 { + if m != nil { + return m.A + } + return nil +} + +type PackedTest struct { + B []int32 `protobuf:"varint,1,rep,packed,name=b" json:"b,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PackedTest) Reset() { *m = PackedTest{} } +func (m *PackedTest) String() string { return proto.CompactTextString(m) } +func (*PackedTest) ProtoMessage() {} +func (*PackedTest) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{6} +} + +func (m *PackedTest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PackedTest.Unmarshal(m, b) +} +func (m *PackedTest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PackedTest.Marshal(b, m, deterministic) +} +func (m *PackedTest) XXX_Merge(src proto.Message) { + xxx_messageInfo_PackedTest.Merge(m, src) +} +func (m *PackedTest) XXX_Size() int { + return xxx_messageInfo_PackedTest.Size(m) +} +func (m *PackedTest) XXX_DiscardUnknown() { + xxx_messageInfo_PackedTest.DiscardUnknown(m) +} + +var xxx_messageInfo_PackedTest proto.InternalMessageInfo + +func (m *PackedTest) GetB() []int32 { + if m != nil { + return m.B + } + return nil +} + +type MaxTag struct { + // Maximum possible tag number. + LastField *string `protobuf:"bytes,536870911,opt,name=last_field,json=lastField" json:"last_field,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MaxTag) Reset() { *m = MaxTag{} } +func (m *MaxTag) String() string { return proto.CompactTextString(m) } +func (*MaxTag) ProtoMessage() {} +func (*MaxTag) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{7} +} + +func (m *MaxTag) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MaxTag.Unmarshal(m, b) +} +func (m *MaxTag) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MaxTag.Marshal(b, m, deterministic) +} +func (m *MaxTag) XXX_Merge(src proto.Message) { + xxx_messageInfo_MaxTag.Merge(m, src) +} +func (m *MaxTag) XXX_Size() int { + return xxx_messageInfo_MaxTag.Size(m) +} +func (m *MaxTag) XXX_DiscardUnknown() { + xxx_messageInfo_MaxTag.DiscardUnknown(m) +} + +var xxx_messageInfo_MaxTag proto.InternalMessageInfo + +func (m *MaxTag) GetLastField() string { + if m != nil && m.LastField != nil { + return *m.LastField + } + return "" +} + +type OldMessage struct { + Nested *OldMessage_Nested `protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"` + Num *int32 `protobuf:"varint,2,opt,name=num" json:"num,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *OldMessage) Reset() { *m = OldMessage{} } +func (m *OldMessage) String() string { return proto.CompactTextString(m) } +func (*OldMessage) ProtoMessage() {} +func (*OldMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{8} +} + +func (m *OldMessage) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_OldMessage.Unmarshal(m, b) +} +func (m *OldMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_OldMessage.Marshal(b, m, deterministic) +} +func (m *OldMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_OldMessage.Merge(m, src) +} +func (m *OldMessage) XXX_Size() int { + return xxx_messageInfo_OldMessage.Size(m) +} +func (m *OldMessage) XXX_DiscardUnknown() { + xxx_messageInfo_OldMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_OldMessage proto.InternalMessageInfo + +func (m *OldMessage) GetNested() *OldMessage_Nested { + if m != nil { + return m.Nested + } + return nil +} + +func (m *OldMessage) GetNum() int32 { + if m != nil && m.Num != nil { + return *m.Num + } + return 0 +} + +type OldMessage_Nested struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *OldMessage_Nested) Reset() { *m = OldMessage_Nested{} } +func (m *OldMessage_Nested) String() string { return proto.CompactTextString(m) } +func (*OldMessage_Nested) ProtoMessage() {} +func (*OldMessage_Nested) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{8, 0} +} + +func (m *OldMessage_Nested) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_OldMessage_Nested.Unmarshal(m, b) +} +func (m *OldMessage_Nested) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_OldMessage_Nested.Marshal(b, m, deterministic) +} +func (m *OldMessage_Nested) XXX_Merge(src proto.Message) { + xxx_messageInfo_OldMessage_Nested.Merge(m, src) +} +func (m *OldMessage_Nested) XXX_Size() int { + return xxx_messageInfo_OldMessage_Nested.Size(m) +} +func (m *OldMessage_Nested) XXX_DiscardUnknown() { + xxx_messageInfo_OldMessage_Nested.DiscardUnknown(m) +} + +var xxx_messageInfo_OldMessage_Nested proto.InternalMessageInfo + +func (m *OldMessage_Nested) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +// NewMessage is wire compatible with OldMessage; +// imagine it as a future version. +type NewMessage struct { + Nested *NewMessage_Nested `protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"` + // This is an int32 in OldMessage. + Num *int64 `protobuf:"varint,2,opt,name=num" json:"num,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *NewMessage) Reset() { *m = NewMessage{} } +func (m *NewMessage) String() string { return proto.CompactTextString(m) } +func (*NewMessage) ProtoMessage() {} +func (*NewMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{9} +} + +func (m *NewMessage) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_NewMessage.Unmarshal(m, b) +} +func (m *NewMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_NewMessage.Marshal(b, m, deterministic) +} +func (m *NewMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_NewMessage.Merge(m, src) +} +func (m *NewMessage) XXX_Size() int { + return xxx_messageInfo_NewMessage.Size(m) +} +func (m *NewMessage) XXX_DiscardUnknown() { + xxx_messageInfo_NewMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_NewMessage proto.InternalMessageInfo + +func (m *NewMessage) GetNested() *NewMessage_Nested { + if m != nil { + return m.Nested + } + return nil +} + +func (m *NewMessage) GetNum() int64 { + if m != nil && m.Num != nil { + return *m.Num + } + return 0 +} + +type NewMessage_Nested struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + FoodGroup *string `protobuf:"bytes,2,opt,name=food_group,json=foodGroup" json:"food_group,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *NewMessage_Nested) Reset() { *m = NewMessage_Nested{} } +func (m *NewMessage_Nested) String() string { return proto.CompactTextString(m) } +func (*NewMessage_Nested) ProtoMessage() {} +func (*NewMessage_Nested) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{9, 0} +} + +func (m *NewMessage_Nested) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_NewMessage_Nested.Unmarshal(m, b) +} +func (m *NewMessage_Nested) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_NewMessage_Nested.Marshal(b, m, deterministic) +} +func (m *NewMessage_Nested) XXX_Merge(src proto.Message) { + xxx_messageInfo_NewMessage_Nested.Merge(m, src) +} +func (m *NewMessage_Nested) XXX_Size() int { + return xxx_messageInfo_NewMessage_Nested.Size(m) +} +func (m *NewMessage_Nested) XXX_DiscardUnknown() { + xxx_messageInfo_NewMessage_Nested.DiscardUnknown(m) +} + +var xxx_messageInfo_NewMessage_Nested proto.InternalMessageInfo + +func (m *NewMessage_Nested) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *NewMessage_Nested) GetFoodGroup() string { + if m != nil && m.FoodGroup != nil { + return *m.FoodGroup + } + return "" +} + +type InnerMessage struct { + Host *string `protobuf:"bytes,1,req,name=host" json:"host,omitempty"` + Port *int32 `protobuf:"varint,2,opt,name=port,def=4000" json:"port,omitempty"` + Connected *bool `protobuf:"varint,3,opt,name=connected" json:"connected,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *InnerMessage) Reset() { *m = InnerMessage{} } +func (m *InnerMessage) String() string { return proto.CompactTextString(m) } +func (*InnerMessage) ProtoMessage() {} +func (*InnerMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{10} +} + +func (m *InnerMessage) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_InnerMessage.Unmarshal(m, b) +} +func (m *InnerMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_InnerMessage.Marshal(b, m, deterministic) +} +func (m *InnerMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_InnerMessage.Merge(m, src) +} +func (m *InnerMessage) XXX_Size() int { + return xxx_messageInfo_InnerMessage.Size(m) +} +func (m *InnerMessage) XXX_DiscardUnknown() { + xxx_messageInfo_InnerMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_InnerMessage proto.InternalMessageInfo + +const Default_InnerMessage_Port int32 = 4000 + +func (m *InnerMessage) GetHost() string { + if m != nil && m.Host != nil { + return *m.Host + } + return "" +} + +func (m *InnerMessage) GetPort() int32 { + if m != nil && m.Port != nil { + return *m.Port + } + return Default_InnerMessage_Port +} + +func (m *InnerMessage) GetConnected() bool { + if m != nil && m.Connected != nil { + return *m.Connected + } + return false +} + +type OtherMessage struct { + Key *int64 `protobuf:"varint,1,opt,name=key" json:"key,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` + Weight *float32 `protobuf:"fixed32,3,opt,name=weight" json:"weight,omitempty"` + Inner *InnerMessage `protobuf:"bytes,4,opt,name=inner" json:"inner,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *OtherMessage) Reset() { *m = OtherMessage{} } +func (m *OtherMessage) String() string { return proto.CompactTextString(m) } +func (*OtherMessage) ProtoMessage() {} +func (*OtherMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{11} +} + +var extRange_OtherMessage = []proto.ExtensionRange{ + {Start: 100, End: 536870911}, +} + +func (*OtherMessage) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_OtherMessage +} + +func (m *OtherMessage) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_OtherMessage.Unmarshal(m, b) +} +func (m *OtherMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_OtherMessage.Marshal(b, m, deterministic) +} +func (m *OtherMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_OtherMessage.Merge(m, src) +} +func (m *OtherMessage) XXX_Size() int { + return xxx_messageInfo_OtherMessage.Size(m) +} +func (m *OtherMessage) XXX_DiscardUnknown() { + xxx_messageInfo_OtherMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_OtherMessage proto.InternalMessageInfo + +func (m *OtherMessage) GetKey() int64 { + if m != nil && m.Key != nil { + return *m.Key + } + return 0 +} + +func (m *OtherMessage) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func (m *OtherMessage) GetWeight() float32 { + if m != nil && m.Weight != nil { + return *m.Weight + } + return 0 +} + +func (m *OtherMessage) GetInner() *InnerMessage { + if m != nil { + return m.Inner + } + return nil +} + +type RequiredInnerMessage struct { + LeoFinallyWonAnOscar *InnerMessage `protobuf:"bytes,1,req,name=leo_finally_won_an_oscar,json=leoFinallyWonAnOscar" json:"leo_finally_won_an_oscar,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RequiredInnerMessage) Reset() { *m = RequiredInnerMessage{} } +func (m *RequiredInnerMessage) String() string { return proto.CompactTextString(m) } +func (*RequiredInnerMessage) ProtoMessage() {} +func (*RequiredInnerMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{12} +} + +func (m *RequiredInnerMessage) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RequiredInnerMessage.Unmarshal(m, b) +} +func (m *RequiredInnerMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RequiredInnerMessage.Marshal(b, m, deterministic) +} +func (m *RequiredInnerMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_RequiredInnerMessage.Merge(m, src) +} +func (m *RequiredInnerMessage) XXX_Size() int { + return xxx_messageInfo_RequiredInnerMessage.Size(m) +} +func (m *RequiredInnerMessage) XXX_DiscardUnknown() { + xxx_messageInfo_RequiredInnerMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_RequiredInnerMessage proto.InternalMessageInfo + +func (m *RequiredInnerMessage) GetLeoFinallyWonAnOscar() *InnerMessage { + if m != nil { + return m.LeoFinallyWonAnOscar + } + return nil +} + +type MyMessage struct { + Count *int32 `protobuf:"varint,1,req,name=count" json:"count,omitempty"` + Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + Quote *string `protobuf:"bytes,3,opt,name=quote" json:"quote,omitempty"` + Pet []string `protobuf:"bytes,4,rep,name=pet" json:"pet,omitempty"` + Inner *InnerMessage `protobuf:"bytes,5,opt,name=inner" json:"inner,omitempty"` + Others []*OtherMessage `protobuf:"bytes,6,rep,name=others" json:"others,omitempty"` + WeMustGoDeeper *RequiredInnerMessage `protobuf:"bytes,13,opt,name=we_must_go_deeper,json=weMustGoDeeper" json:"we_must_go_deeper,omitempty"` + RepInner []*InnerMessage `protobuf:"bytes,12,rep,name=rep_inner,json=repInner" json:"rep_inner,omitempty"` + Bikeshed *MyMessage_Color `protobuf:"varint,7,opt,name=bikeshed,enum=proto2_test.MyMessage_Color" json:"bikeshed,omitempty"` + Somegroup *MyMessage_SomeGroup `protobuf:"group,8,opt,name=SomeGroup,json=somegroup" json:"somegroup,omitempty"` + // This field becomes [][]byte in the generated code. + RepBytes [][]byte `protobuf:"bytes,10,rep,name=rep_bytes,json=repBytes" json:"rep_bytes,omitempty"` + Bigfloat *float64 `protobuf:"fixed64,11,opt,name=bigfloat" json:"bigfloat,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MyMessage) Reset() { *m = MyMessage{} } +func (m *MyMessage) String() string { return proto.CompactTextString(m) } +func (*MyMessage) ProtoMessage() {} +func (*MyMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{13} +} + +var extRange_MyMessage = []proto.ExtensionRange{ + {Start: 100, End: 536870911}, +} + +func (*MyMessage) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_MyMessage +} + +func (m *MyMessage) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MyMessage.Unmarshal(m, b) +} +func (m *MyMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MyMessage.Marshal(b, m, deterministic) +} +func (m *MyMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_MyMessage.Merge(m, src) +} +func (m *MyMessage) XXX_Size() int { + return xxx_messageInfo_MyMessage.Size(m) +} +func (m *MyMessage) XXX_DiscardUnknown() { + xxx_messageInfo_MyMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_MyMessage proto.InternalMessageInfo + +func (m *MyMessage) GetCount() int32 { + if m != nil && m.Count != nil { + return *m.Count + } + return 0 +} + +func (m *MyMessage) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *MyMessage) GetQuote() string { + if m != nil && m.Quote != nil { + return *m.Quote + } + return "" +} + +func (m *MyMessage) GetPet() []string { + if m != nil { + return m.Pet + } + return nil +} + +func (m *MyMessage) GetInner() *InnerMessage { + if m != nil { + return m.Inner + } + return nil +} + +func (m *MyMessage) GetOthers() []*OtherMessage { + if m != nil { + return m.Others + } + return nil +} + +func (m *MyMessage) GetWeMustGoDeeper() *RequiredInnerMessage { + if m != nil { + return m.WeMustGoDeeper + } + return nil +} + +func (m *MyMessage) GetRepInner() []*InnerMessage { + if m != nil { + return m.RepInner + } + return nil +} + +func (m *MyMessage) GetBikeshed() MyMessage_Color { + if m != nil && m.Bikeshed != nil { + return *m.Bikeshed + } + return MyMessage_RED +} + +func (m *MyMessage) GetSomegroup() *MyMessage_SomeGroup { + if m != nil { + return m.Somegroup + } + return nil +} + +func (m *MyMessage) GetRepBytes() [][]byte { + if m != nil { + return m.RepBytes + } + return nil +} + +func (m *MyMessage) GetBigfloat() float64 { + if m != nil && m.Bigfloat != nil { + return *m.Bigfloat + } + return 0 +} + +type MyMessage_SomeGroup struct { + GroupField *int32 `protobuf:"varint,9,opt,name=group_field,json=groupField" json:"group_field,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MyMessage_SomeGroup) Reset() { *m = MyMessage_SomeGroup{} } +func (m *MyMessage_SomeGroup) String() string { return proto.CompactTextString(m) } +func (*MyMessage_SomeGroup) ProtoMessage() {} +func (*MyMessage_SomeGroup) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{13, 0} +} + +func (m *MyMessage_SomeGroup) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MyMessage_SomeGroup.Unmarshal(m, b) +} +func (m *MyMessage_SomeGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MyMessage_SomeGroup.Marshal(b, m, deterministic) +} +func (m *MyMessage_SomeGroup) XXX_Merge(src proto.Message) { + xxx_messageInfo_MyMessage_SomeGroup.Merge(m, src) +} +func (m *MyMessage_SomeGroup) XXX_Size() int { + return xxx_messageInfo_MyMessage_SomeGroup.Size(m) +} +func (m *MyMessage_SomeGroup) XXX_DiscardUnknown() { + xxx_messageInfo_MyMessage_SomeGroup.DiscardUnknown(m) +} + +var xxx_messageInfo_MyMessage_SomeGroup proto.InternalMessageInfo + +func (m *MyMessage_SomeGroup) GetGroupField() int32 { + if m != nil && m.GroupField != nil { + return *m.GroupField + } + return 0 +} + +type Ext struct { + Data *string `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"` + MapField map[int32]int32 `protobuf:"bytes,2,rep,name=map_field,json=mapField" json:"map_field,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Ext) Reset() { *m = Ext{} } +func (m *Ext) String() string { return proto.CompactTextString(m) } +func (*Ext) ProtoMessage() {} +func (*Ext) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{14} +} + +func (m *Ext) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Ext.Unmarshal(m, b) +} +func (m *Ext) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Ext.Marshal(b, m, deterministic) +} +func (m *Ext) XXX_Merge(src proto.Message) { + xxx_messageInfo_Ext.Merge(m, src) +} +func (m *Ext) XXX_Size() int { + return xxx_messageInfo_Ext.Size(m) +} +func (m *Ext) XXX_DiscardUnknown() { + xxx_messageInfo_Ext.DiscardUnknown(m) +} + +var xxx_messageInfo_Ext proto.InternalMessageInfo + +func (m *Ext) GetData() string { + if m != nil && m.Data != nil { + return *m.Data + } + return "" +} + +func (m *Ext) GetMapField() map[int32]int32 { + if m != nil { + return m.MapField + } + return nil +} + +var E_Ext_More = &proto.ExtensionDesc{ + ExtendedType: (*MyMessage)(nil), + ExtensionType: (*Ext)(nil), + Field: 103, + Name: "proto2_test.Ext.more", + Tag: "bytes,103,opt,name=more", + Filename: "proto2_proto/test.proto", +} + +var E_Ext_Text = &proto.ExtensionDesc{ + ExtendedType: (*MyMessage)(nil), + ExtensionType: (*string)(nil), + Field: 104, + Name: "proto2_test.Ext.text", + Tag: "bytes,104,opt,name=text", + Filename: "proto2_proto/test.proto", +} + +var E_Ext_Number = &proto.ExtensionDesc{ + ExtendedType: (*MyMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 105, + Name: "proto2_test.Ext.number", + Tag: "varint,105,opt,name=number", + Filename: "proto2_proto/test.proto", +} + +type ComplexExtension struct { + First *int32 `protobuf:"varint,1,opt,name=first" json:"first,omitempty"` + Second *int32 `protobuf:"varint,2,opt,name=second" json:"second,omitempty"` + Third []int32 `protobuf:"varint,3,rep,name=third" json:"third,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ComplexExtension) Reset() { *m = ComplexExtension{} } +func (m *ComplexExtension) String() string { return proto.CompactTextString(m) } +func (*ComplexExtension) ProtoMessage() {} +func (*ComplexExtension) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{15} +} + +func (m *ComplexExtension) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_ComplexExtension.Unmarshal(m, b) +} +func (m *ComplexExtension) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_ComplexExtension.Marshal(b, m, deterministic) +} +func (m *ComplexExtension) XXX_Merge(src proto.Message) { + xxx_messageInfo_ComplexExtension.Merge(m, src) +} +func (m *ComplexExtension) XXX_Size() int { + return xxx_messageInfo_ComplexExtension.Size(m) +} +func (m *ComplexExtension) XXX_DiscardUnknown() { + xxx_messageInfo_ComplexExtension.DiscardUnknown(m) +} + +var xxx_messageInfo_ComplexExtension proto.InternalMessageInfo + +func (m *ComplexExtension) GetFirst() int32 { + if m != nil && m.First != nil { + return *m.First + } + return 0 +} + +func (m *ComplexExtension) GetSecond() int32 { + if m != nil && m.Second != nil { + return *m.Second + } + return 0 +} + +func (m *ComplexExtension) GetThird() []int32 { + if m != nil { + return m.Third + } + return nil +} + +type DefaultsMessage struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + proto.XXX_InternalExtensions `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DefaultsMessage) Reset() { *m = DefaultsMessage{} } +func (m *DefaultsMessage) String() string { return proto.CompactTextString(m) } +func (*DefaultsMessage) ProtoMessage() {} +func (*DefaultsMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{16} +} + +var extRange_DefaultsMessage = []proto.ExtensionRange{ + {Start: 100, End: 536870911}, +} + +func (*DefaultsMessage) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_DefaultsMessage +} + +func (m *DefaultsMessage) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DefaultsMessage.Unmarshal(m, b) +} +func (m *DefaultsMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DefaultsMessage.Marshal(b, m, deterministic) +} +func (m *DefaultsMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_DefaultsMessage.Merge(m, src) +} +func (m *DefaultsMessage) XXX_Size() int { + return xxx_messageInfo_DefaultsMessage.Size(m) +} +func (m *DefaultsMessage) XXX_DiscardUnknown() { + xxx_messageInfo_DefaultsMessage.DiscardUnknown(m) +} + +var xxx_messageInfo_DefaultsMessage proto.InternalMessageInfo + +type Empty struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Empty) Reset() { *m = Empty{} } +func (m *Empty) String() string { return proto.CompactTextString(m) } +func (*Empty) ProtoMessage() {} +func (*Empty) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{17} +} + +func (m *Empty) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Empty.Unmarshal(m, b) +} +func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Empty.Marshal(b, m, deterministic) +} +func (m *Empty) XXX_Merge(src proto.Message) { + xxx_messageInfo_Empty.Merge(m, src) +} +func (m *Empty) XXX_Size() int { + return xxx_messageInfo_Empty.Size(m) +} +func (m *Empty) XXX_DiscardUnknown() { + xxx_messageInfo_Empty.DiscardUnknown(m) +} + +var xxx_messageInfo_Empty proto.InternalMessageInfo + +type MessageList struct { + Message []*MessageList_Message `protobuf:"group,1,rep,name=Message,json=message" json:"message,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MessageList) Reset() { *m = MessageList{} } +func (m *MessageList) String() string { return proto.CompactTextString(m) } +func (*MessageList) ProtoMessage() {} +func (*MessageList) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{18} +} + +func (m *MessageList) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MessageList.Unmarshal(m, b) +} +func (m *MessageList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MessageList.Marshal(b, m, deterministic) +} +func (m *MessageList) XXX_Merge(src proto.Message) { + xxx_messageInfo_MessageList.Merge(m, src) +} +func (m *MessageList) XXX_Size() int { + return xxx_messageInfo_MessageList.Size(m) +} +func (m *MessageList) XXX_DiscardUnknown() { + xxx_messageInfo_MessageList.DiscardUnknown(m) +} + +var xxx_messageInfo_MessageList proto.InternalMessageInfo + +func (m *MessageList) GetMessage() []*MessageList_Message { + if m != nil { + return m.Message + } + return nil +} + +type MessageList_Message struct { + Name *string `protobuf:"bytes,2,req,name=name" json:"name,omitempty"` + Count *int32 `protobuf:"varint,3,req,name=count" json:"count,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MessageList_Message) Reset() { *m = MessageList_Message{} } +func (m *MessageList_Message) String() string { return proto.CompactTextString(m) } +func (*MessageList_Message) ProtoMessage() {} +func (*MessageList_Message) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{18, 0} +} + +func (m *MessageList_Message) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MessageList_Message.Unmarshal(m, b) +} +func (m *MessageList_Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MessageList_Message.Marshal(b, m, deterministic) +} +func (m *MessageList_Message) XXX_Merge(src proto.Message) { + xxx_messageInfo_MessageList_Message.Merge(m, src) +} +func (m *MessageList_Message) XXX_Size() int { + return xxx_messageInfo_MessageList_Message.Size(m) +} +func (m *MessageList_Message) XXX_DiscardUnknown() { + xxx_messageInfo_MessageList_Message.DiscardUnknown(m) +} + +var xxx_messageInfo_MessageList_Message proto.InternalMessageInfo + +func (m *MessageList_Message) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *MessageList_Message) GetCount() int32 { + if m != nil && m.Count != nil { + return *m.Count + } + return 0 +} + +type Strings struct { + StringField *string `protobuf:"bytes,1,opt,name=string_field,json=stringField" json:"string_field,omitempty"` + BytesField []byte `protobuf:"bytes,2,opt,name=bytes_field,json=bytesField" json:"bytes_field,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Strings) Reset() { *m = Strings{} } +func (m *Strings) String() string { return proto.CompactTextString(m) } +func (*Strings) ProtoMessage() {} +func (*Strings) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{19} +} + +func (m *Strings) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Strings.Unmarshal(m, b) +} +func (m *Strings) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Strings.Marshal(b, m, deterministic) +} +func (m *Strings) XXX_Merge(src proto.Message) { + xxx_messageInfo_Strings.Merge(m, src) +} +func (m *Strings) XXX_Size() int { + return xxx_messageInfo_Strings.Size(m) +} +func (m *Strings) XXX_DiscardUnknown() { + xxx_messageInfo_Strings.DiscardUnknown(m) +} + +var xxx_messageInfo_Strings proto.InternalMessageInfo + +func (m *Strings) GetStringField() string { + if m != nil && m.StringField != nil { + return *m.StringField + } + return "" +} + +func (m *Strings) GetBytesField() []byte { + if m != nil { + return m.BytesField + } + return nil +} + +type Defaults struct { + // Default-valued fields of all basic types. + // Same as GoTest, but copied here to make testing easier. + F_Bool *bool `protobuf:"varint,1,opt,name=F_Bool,json=FBool,def=1" json:"F_Bool,omitempty"` + F_Int32 *int32 `protobuf:"varint,2,opt,name=F_Int32,json=FInt32,def=32" json:"F_Int32,omitempty"` + F_Int64 *int64 `protobuf:"varint,3,opt,name=F_Int64,json=FInt64,def=64" json:"F_Int64,omitempty"` + F_Fixed32 *uint32 `protobuf:"fixed32,4,opt,name=F_Fixed32,json=FFixed32,def=320" json:"F_Fixed32,omitempty"` + F_Fixed64 *uint64 `protobuf:"fixed64,5,opt,name=F_Fixed64,json=FFixed64,def=640" json:"F_Fixed64,omitempty"` + F_Uint32 *uint32 `protobuf:"varint,6,opt,name=F_Uint32,json=FUint32,def=3200" json:"F_Uint32,omitempty"` + F_Uint64 *uint64 `protobuf:"varint,7,opt,name=F_Uint64,json=FUint64,def=6400" json:"F_Uint64,omitempty"` + F_Float *float32 `protobuf:"fixed32,8,opt,name=F_Float,json=FFloat,def=314159" json:"F_Float,omitempty"` + F_Double *float64 `protobuf:"fixed64,9,opt,name=F_Double,json=FDouble,def=271828" json:"F_Double,omitempty"` + F_String *string `protobuf:"bytes,10,opt,name=F_String,json=FString,def=hello, \"world!\"\n" json:"F_String,omitempty"` + F_Bytes []byte `protobuf:"bytes,11,opt,name=F_Bytes,json=FBytes,def=Bignose" json:"F_Bytes,omitempty"` + F_Sint32 *int32 `protobuf:"zigzag32,12,opt,name=F_Sint32,json=FSint32,def=-32" json:"F_Sint32,omitempty"` + F_Sint64 *int64 `protobuf:"zigzag64,13,opt,name=F_Sint64,json=FSint64,def=-64" json:"F_Sint64,omitempty"` + F_Enum *Defaults_Color `protobuf:"varint,14,opt,name=F_Enum,json=FEnum,enum=proto2_test.Defaults_Color,def=1" json:"F_Enum,omitempty"` + // More fields with crazy defaults. + F_Pinf *float32 `protobuf:"fixed32,15,opt,name=F_Pinf,json=FPinf,def=inf" json:"F_Pinf,omitempty"` + F_Ninf *float32 `protobuf:"fixed32,16,opt,name=F_Ninf,json=FNinf,def=-inf" json:"F_Ninf,omitempty"` + F_Nan *float32 `protobuf:"fixed32,17,opt,name=F_Nan,json=FNan,def=nan" json:"F_Nan,omitempty"` + // Sub-message. + Sub *SubDefaults `protobuf:"bytes,18,opt,name=sub" json:"sub,omitempty"` + // Redundant but explicit defaults. + StrZero *string `protobuf:"bytes,19,opt,name=str_zero,json=strZero,def=" json:"str_zero,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Defaults) Reset() { *m = Defaults{} } +func (m *Defaults) String() string { return proto.CompactTextString(m) } +func (*Defaults) ProtoMessage() {} +func (*Defaults) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{20} +} + +func (m *Defaults) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Defaults.Unmarshal(m, b) +} +func (m *Defaults) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Defaults.Marshal(b, m, deterministic) +} +func (m *Defaults) XXX_Merge(src proto.Message) { + xxx_messageInfo_Defaults.Merge(m, src) +} +func (m *Defaults) XXX_Size() int { + return xxx_messageInfo_Defaults.Size(m) +} +func (m *Defaults) XXX_DiscardUnknown() { + xxx_messageInfo_Defaults.DiscardUnknown(m) +} + +var xxx_messageInfo_Defaults proto.InternalMessageInfo + +const Default_Defaults_F_Bool bool = true +const Default_Defaults_F_Int32 int32 = 32 +const Default_Defaults_F_Int64 int64 = 64 +const Default_Defaults_F_Fixed32 uint32 = 320 +const Default_Defaults_F_Fixed64 uint64 = 640 +const Default_Defaults_F_Uint32 uint32 = 3200 +const Default_Defaults_F_Uint64 uint64 = 6400 +const Default_Defaults_F_Float float32 = 314159 +const Default_Defaults_F_Double float64 = 271828 +const Default_Defaults_F_String string = "hello, \"world!\"\n" + +var Default_Defaults_F_Bytes []byte = []byte("Bignose") + +const Default_Defaults_F_Sint32 int32 = -32 +const Default_Defaults_F_Sint64 int64 = -64 +const Default_Defaults_F_Enum Defaults_Color = Defaults_GREEN + +var Default_Defaults_F_Pinf float32 = float32(math.Inf(1)) +var Default_Defaults_F_Ninf float32 = float32(math.Inf(-1)) +var Default_Defaults_F_Nan float32 = float32(math.NaN()) + +func (m *Defaults) GetF_Bool() bool { + if m != nil && m.F_Bool != nil { + return *m.F_Bool + } + return Default_Defaults_F_Bool +} + +func (m *Defaults) GetF_Int32() int32 { + if m != nil && m.F_Int32 != nil { + return *m.F_Int32 + } + return Default_Defaults_F_Int32 +} + +func (m *Defaults) GetF_Int64() int64 { + if m != nil && m.F_Int64 != nil { + return *m.F_Int64 + } + return Default_Defaults_F_Int64 +} + +func (m *Defaults) GetF_Fixed32() uint32 { + if m != nil && m.F_Fixed32 != nil { + return *m.F_Fixed32 + } + return Default_Defaults_F_Fixed32 +} + +func (m *Defaults) GetF_Fixed64() uint64 { + if m != nil && m.F_Fixed64 != nil { + return *m.F_Fixed64 + } + return Default_Defaults_F_Fixed64 +} + +func (m *Defaults) GetF_Uint32() uint32 { + if m != nil && m.F_Uint32 != nil { + return *m.F_Uint32 + } + return Default_Defaults_F_Uint32 +} + +func (m *Defaults) GetF_Uint64() uint64 { + if m != nil && m.F_Uint64 != nil { + return *m.F_Uint64 + } + return Default_Defaults_F_Uint64 +} + +func (m *Defaults) GetF_Float() float32 { + if m != nil && m.F_Float != nil { + return *m.F_Float + } + return Default_Defaults_F_Float +} + +func (m *Defaults) GetF_Double() float64 { + if m != nil && m.F_Double != nil { + return *m.F_Double + } + return Default_Defaults_F_Double +} + +func (m *Defaults) GetF_String() string { + if m != nil && m.F_String != nil { + return *m.F_String + } + return Default_Defaults_F_String +} + +func (m *Defaults) GetF_Bytes() []byte { + if m != nil && m.F_Bytes != nil { + return m.F_Bytes + } + return append([]byte(nil), Default_Defaults_F_Bytes...) +} + +func (m *Defaults) GetF_Sint32() int32 { + if m != nil && m.F_Sint32 != nil { + return *m.F_Sint32 + } + return Default_Defaults_F_Sint32 +} + +func (m *Defaults) GetF_Sint64() int64 { + if m != nil && m.F_Sint64 != nil { + return *m.F_Sint64 + } + return Default_Defaults_F_Sint64 +} + +func (m *Defaults) GetF_Enum() Defaults_Color { + if m != nil && m.F_Enum != nil { + return *m.F_Enum + } + return Default_Defaults_F_Enum +} + +func (m *Defaults) GetF_Pinf() float32 { + if m != nil && m.F_Pinf != nil { + return *m.F_Pinf + } + return Default_Defaults_F_Pinf +} + +func (m *Defaults) GetF_Ninf() float32 { + if m != nil && m.F_Ninf != nil { + return *m.F_Ninf + } + return Default_Defaults_F_Ninf +} + +func (m *Defaults) GetF_Nan() float32 { + if m != nil && m.F_Nan != nil { + return *m.F_Nan + } + return Default_Defaults_F_Nan +} + +func (m *Defaults) GetSub() *SubDefaults { + if m != nil { + return m.Sub + } + return nil +} + +func (m *Defaults) GetStrZero() string { + if m != nil && m.StrZero != nil { + return *m.StrZero + } + return "" +} + +type SubDefaults struct { + N *int64 `protobuf:"varint,1,opt,name=n,def=7" json:"n,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SubDefaults) Reset() { *m = SubDefaults{} } +func (m *SubDefaults) String() string { return proto.CompactTextString(m) } +func (*SubDefaults) ProtoMessage() {} +func (*SubDefaults) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{21} +} + +func (m *SubDefaults) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SubDefaults.Unmarshal(m, b) +} +func (m *SubDefaults) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SubDefaults.Marshal(b, m, deterministic) +} +func (m *SubDefaults) XXX_Merge(src proto.Message) { + xxx_messageInfo_SubDefaults.Merge(m, src) +} +func (m *SubDefaults) XXX_Size() int { + return xxx_messageInfo_SubDefaults.Size(m) +} +func (m *SubDefaults) XXX_DiscardUnknown() { + xxx_messageInfo_SubDefaults.DiscardUnknown(m) +} + +var xxx_messageInfo_SubDefaults proto.InternalMessageInfo + +const Default_SubDefaults_N int64 = 7 + +func (m *SubDefaults) GetN() int64 { + if m != nil && m.N != nil { + return *m.N + } + return Default_SubDefaults_N +} + +type RepeatedEnum struct { + Color []RepeatedEnum_Color `protobuf:"varint,1,rep,name=color,enum=proto2_test.RepeatedEnum_Color" json:"color,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RepeatedEnum) Reset() { *m = RepeatedEnum{} } +func (m *RepeatedEnum) String() string { return proto.CompactTextString(m) } +func (*RepeatedEnum) ProtoMessage() {} +func (*RepeatedEnum) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{22} +} + +func (m *RepeatedEnum) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_RepeatedEnum.Unmarshal(m, b) +} +func (m *RepeatedEnum) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_RepeatedEnum.Marshal(b, m, deterministic) +} +func (m *RepeatedEnum) XXX_Merge(src proto.Message) { + xxx_messageInfo_RepeatedEnum.Merge(m, src) +} +func (m *RepeatedEnum) XXX_Size() int { + return xxx_messageInfo_RepeatedEnum.Size(m) +} +func (m *RepeatedEnum) XXX_DiscardUnknown() { + xxx_messageInfo_RepeatedEnum.DiscardUnknown(m) +} + +var xxx_messageInfo_RepeatedEnum proto.InternalMessageInfo + +func (m *RepeatedEnum) GetColor() []RepeatedEnum_Color { + if m != nil { + return m.Color + } + return nil +} + +type MoreRepeated struct { + Bools []bool `protobuf:"varint,1,rep,name=bools" json:"bools,omitempty"` + BoolsPacked []bool `protobuf:"varint,2,rep,packed,name=bools_packed,json=boolsPacked" json:"bools_packed,omitempty"` + Ints []int32 `protobuf:"varint,3,rep,name=ints" json:"ints,omitempty"` + IntsPacked []int32 `protobuf:"varint,4,rep,packed,name=ints_packed,json=intsPacked" json:"ints_packed,omitempty"` + Int64SPacked []int64 `protobuf:"varint,7,rep,packed,name=int64s_packed,json=int64sPacked" json:"int64s_packed,omitempty"` + Strings []string `protobuf:"bytes,5,rep,name=strings" json:"strings,omitempty"` + Fixeds []uint32 `protobuf:"fixed32,6,rep,name=fixeds" json:"fixeds,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MoreRepeated) Reset() { *m = MoreRepeated{} } +func (m *MoreRepeated) String() string { return proto.CompactTextString(m) } +func (*MoreRepeated) ProtoMessage() {} +func (*MoreRepeated) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{23} +} + +func (m *MoreRepeated) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MoreRepeated.Unmarshal(m, b) +} +func (m *MoreRepeated) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MoreRepeated.Marshal(b, m, deterministic) +} +func (m *MoreRepeated) XXX_Merge(src proto.Message) { + xxx_messageInfo_MoreRepeated.Merge(m, src) +} +func (m *MoreRepeated) XXX_Size() int { + return xxx_messageInfo_MoreRepeated.Size(m) +} +func (m *MoreRepeated) XXX_DiscardUnknown() { + xxx_messageInfo_MoreRepeated.DiscardUnknown(m) +} + +var xxx_messageInfo_MoreRepeated proto.InternalMessageInfo + +func (m *MoreRepeated) GetBools() []bool { + if m != nil { + return m.Bools + } + return nil +} + +func (m *MoreRepeated) GetBoolsPacked() []bool { + if m != nil { + return m.BoolsPacked + } + return nil +} + +func (m *MoreRepeated) GetInts() []int32 { + if m != nil { + return m.Ints + } + return nil +} + +func (m *MoreRepeated) GetIntsPacked() []int32 { + if m != nil { + return m.IntsPacked + } + return nil +} + +func (m *MoreRepeated) GetInt64SPacked() []int64 { + if m != nil { + return m.Int64SPacked + } + return nil +} + +func (m *MoreRepeated) GetStrings() []string { + if m != nil { + return m.Strings + } + return nil +} + +func (m *MoreRepeated) GetFixeds() []uint32 { + if m != nil { + return m.Fixeds + } + return nil +} + +type GroupOld struct { + G *GroupOld_G `protobuf:"group,101,opt,name=G,json=g" json:"g,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GroupOld) Reset() { *m = GroupOld{} } +func (m *GroupOld) String() string { return proto.CompactTextString(m) } +func (*GroupOld) ProtoMessage() {} +func (*GroupOld) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{24} +} + +func (m *GroupOld) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GroupOld.Unmarshal(m, b) +} +func (m *GroupOld) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GroupOld.Marshal(b, m, deterministic) +} +func (m *GroupOld) XXX_Merge(src proto.Message) { + xxx_messageInfo_GroupOld.Merge(m, src) +} +func (m *GroupOld) XXX_Size() int { + return xxx_messageInfo_GroupOld.Size(m) +} +func (m *GroupOld) XXX_DiscardUnknown() { + xxx_messageInfo_GroupOld.DiscardUnknown(m) +} + +var xxx_messageInfo_GroupOld proto.InternalMessageInfo + +func (m *GroupOld) GetG() *GroupOld_G { + if m != nil { + return m.G + } + return nil +} + +type GroupOld_G struct { + X *int32 `protobuf:"varint,2,opt,name=x" json:"x,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GroupOld_G) Reset() { *m = GroupOld_G{} } +func (m *GroupOld_G) String() string { return proto.CompactTextString(m) } +func (*GroupOld_G) ProtoMessage() {} +func (*GroupOld_G) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{24, 0} +} + +func (m *GroupOld_G) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GroupOld_G.Unmarshal(m, b) +} +func (m *GroupOld_G) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GroupOld_G.Marshal(b, m, deterministic) +} +func (m *GroupOld_G) XXX_Merge(src proto.Message) { + xxx_messageInfo_GroupOld_G.Merge(m, src) +} +func (m *GroupOld_G) XXX_Size() int { + return xxx_messageInfo_GroupOld_G.Size(m) +} +func (m *GroupOld_G) XXX_DiscardUnknown() { + xxx_messageInfo_GroupOld_G.DiscardUnknown(m) +} + +var xxx_messageInfo_GroupOld_G proto.InternalMessageInfo + +func (m *GroupOld_G) GetX() int32 { + if m != nil && m.X != nil { + return *m.X + } + return 0 +} + +type GroupNew struct { + G *GroupNew_G `protobuf:"group,101,opt,name=G,json=g" json:"g,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GroupNew) Reset() { *m = GroupNew{} } +func (m *GroupNew) String() string { return proto.CompactTextString(m) } +func (*GroupNew) ProtoMessage() {} +func (*GroupNew) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{25} +} + +func (m *GroupNew) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GroupNew.Unmarshal(m, b) +} +func (m *GroupNew) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GroupNew.Marshal(b, m, deterministic) +} +func (m *GroupNew) XXX_Merge(src proto.Message) { + xxx_messageInfo_GroupNew.Merge(m, src) +} +func (m *GroupNew) XXX_Size() int { + return xxx_messageInfo_GroupNew.Size(m) +} +func (m *GroupNew) XXX_DiscardUnknown() { + xxx_messageInfo_GroupNew.DiscardUnknown(m) +} + +var xxx_messageInfo_GroupNew proto.InternalMessageInfo + +func (m *GroupNew) GetG() *GroupNew_G { + if m != nil { + return m.G + } + return nil +} + +type GroupNew_G struct { + X *int32 `protobuf:"varint,2,opt,name=x" json:"x,omitempty"` + Y *int32 `protobuf:"varint,3,opt,name=y" json:"y,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GroupNew_G) Reset() { *m = GroupNew_G{} } +func (m *GroupNew_G) String() string { return proto.CompactTextString(m) } +func (*GroupNew_G) ProtoMessage() {} +func (*GroupNew_G) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{25, 0} +} + +func (m *GroupNew_G) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GroupNew_G.Unmarshal(m, b) +} +func (m *GroupNew_G) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GroupNew_G.Marshal(b, m, deterministic) +} +func (m *GroupNew_G) XXX_Merge(src proto.Message) { + xxx_messageInfo_GroupNew_G.Merge(m, src) +} +func (m *GroupNew_G) XXX_Size() int { + return xxx_messageInfo_GroupNew_G.Size(m) +} +func (m *GroupNew_G) XXX_DiscardUnknown() { + xxx_messageInfo_GroupNew_G.DiscardUnknown(m) +} + +var xxx_messageInfo_GroupNew_G proto.InternalMessageInfo + +func (m *GroupNew_G) GetX() int32 { + if m != nil && m.X != nil { + return *m.X + } + return 0 +} + +func (m *GroupNew_G) GetY() int32 { + if m != nil && m.Y != nil { + return *m.Y + } + return 0 +} + +type FloatingPoint struct { + F *float64 `protobuf:"fixed64,1,req,name=f" json:"f,omitempty"` + Exact *bool `protobuf:"varint,2,opt,name=exact" json:"exact,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FloatingPoint) Reset() { *m = FloatingPoint{} } +func (m *FloatingPoint) String() string { return proto.CompactTextString(m) } +func (*FloatingPoint) ProtoMessage() {} +func (*FloatingPoint) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{26} +} + +func (m *FloatingPoint) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FloatingPoint.Unmarshal(m, b) +} +func (m *FloatingPoint) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FloatingPoint.Marshal(b, m, deterministic) +} +func (m *FloatingPoint) XXX_Merge(src proto.Message) { + xxx_messageInfo_FloatingPoint.Merge(m, src) +} +func (m *FloatingPoint) XXX_Size() int { + return xxx_messageInfo_FloatingPoint.Size(m) +} +func (m *FloatingPoint) XXX_DiscardUnknown() { + xxx_messageInfo_FloatingPoint.DiscardUnknown(m) +} + +var xxx_messageInfo_FloatingPoint proto.InternalMessageInfo + +func (m *FloatingPoint) GetF() float64 { + if m != nil && m.F != nil { + return *m.F + } + return 0 +} + +func (m *FloatingPoint) GetExact() bool { + if m != nil && m.Exact != nil { + return *m.Exact + } + return false +} + +type MessageWithMap struct { + NameMapping map[int32]string `protobuf:"bytes,1,rep,name=name_mapping,json=nameMapping" json:"name_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + MsgMapping map[int64]*FloatingPoint `protobuf:"bytes,2,rep,name=msg_mapping,json=msgMapping" json:"msg_mapping,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + ByteMapping map[bool][]byte `protobuf:"bytes,3,rep,name=byte_mapping,json=byteMapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + StrToStr map[string]string `protobuf:"bytes,4,rep,name=str_to_str,json=strToStr" json:"str_to_str,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MessageWithMap) Reset() { *m = MessageWithMap{} } +func (m *MessageWithMap) String() string { return proto.CompactTextString(m) } +func (*MessageWithMap) ProtoMessage() {} +func (*MessageWithMap) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{27} +} + +func (m *MessageWithMap) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MessageWithMap.Unmarshal(m, b) +} +func (m *MessageWithMap) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MessageWithMap.Marshal(b, m, deterministic) +} +func (m *MessageWithMap) XXX_Merge(src proto.Message) { + xxx_messageInfo_MessageWithMap.Merge(m, src) +} +func (m *MessageWithMap) XXX_Size() int { + return xxx_messageInfo_MessageWithMap.Size(m) +} +func (m *MessageWithMap) XXX_DiscardUnknown() { + xxx_messageInfo_MessageWithMap.DiscardUnknown(m) +} + +var xxx_messageInfo_MessageWithMap proto.InternalMessageInfo + +func (m *MessageWithMap) GetNameMapping() map[int32]string { + if m != nil { + return m.NameMapping + } + return nil +} + +func (m *MessageWithMap) GetMsgMapping() map[int64]*FloatingPoint { + if m != nil { + return m.MsgMapping + } + return nil +} + +func (m *MessageWithMap) GetByteMapping() map[bool][]byte { + if m != nil { + return m.ByteMapping + } + return nil +} + +func (m *MessageWithMap) GetStrToStr() map[string]string { + if m != nil { + return m.StrToStr + } + return nil +} + +type Oneof struct { + // Types that are valid to be assigned to Union: + // *Oneof_F_Bool + // *Oneof_F_Int32 + // *Oneof_F_Int64 + // *Oneof_F_Fixed32 + // *Oneof_F_Fixed64 + // *Oneof_F_Uint32 + // *Oneof_F_Uint64 + // *Oneof_F_Float + // *Oneof_F_Double + // *Oneof_F_String + // *Oneof_F_Bytes + // *Oneof_F_Sint32 + // *Oneof_F_Sint64 + // *Oneof_F_Enum + // *Oneof_F_Message + // *Oneof_FGroup + // *Oneof_F_Largest_Tag + Union isOneof_Union `protobuf_oneof:"union"` + // Types that are valid to be assigned to Tormato: + // *Oneof_Value + Tormato isOneof_Tormato `protobuf_oneof:"tormato"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Oneof) Reset() { *m = Oneof{} } +func (m *Oneof) String() string { return proto.CompactTextString(m) } +func (*Oneof) ProtoMessage() {} +func (*Oneof) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{28} +} + +func (m *Oneof) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Oneof.Unmarshal(m, b) +} +func (m *Oneof) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Oneof.Marshal(b, m, deterministic) +} +func (m *Oneof) XXX_Merge(src proto.Message) { + xxx_messageInfo_Oneof.Merge(m, src) +} +func (m *Oneof) XXX_Size() int { + return xxx_messageInfo_Oneof.Size(m) +} +func (m *Oneof) XXX_DiscardUnknown() { + xxx_messageInfo_Oneof.DiscardUnknown(m) +} + +var xxx_messageInfo_Oneof proto.InternalMessageInfo + +type isOneof_Union interface { + isOneof_Union() +} + +type Oneof_F_Bool struct { + F_Bool bool `protobuf:"varint,1,opt,name=F_Bool,json=FBool,oneof"` +} + +type Oneof_F_Int32 struct { + F_Int32 int32 `protobuf:"varint,2,opt,name=F_Int32,json=FInt32,oneof"` +} + +type Oneof_F_Int64 struct { + F_Int64 int64 `protobuf:"varint,3,opt,name=F_Int64,json=FInt64,oneof"` +} + +type Oneof_F_Fixed32 struct { + F_Fixed32 uint32 `protobuf:"fixed32,4,opt,name=F_Fixed32,json=FFixed32,oneof"` +} + +type Oneof_F_Fixed64 struct { + F_Fixed64 uint64 `protobuf:"fixed64,5,opt,name=F_Fixed64,json=FFixed64,oneof"` +} + +type Oneof_F_Uint32 struct { + F_Uint32 uint32 `protobuf:"varint,6,opt,name=F_Uint32,json=FUint32,oneof"` +} + +type Oneof_F_Uint64 struct { + F_Uint64 uint64 `protobuf:"varint,7,opt,name=F_Uint64,json=FUint64,oneof"` +} + +type Oneof_F_Float struct { + F_Float float32 `protobuf:"fixed32,8,opt,name=F_Float,json=FFloat,oneof"` +} + +type Oneof_F_Double struct { + F_Double float64 `protobuf:"fixed64,9,opt,name=F_Double,json=FDouble,oneof"` +} + +type Oneof_F_String struct { + F_String string `protobuf:"bytes,10,opt,name=F_String,json=FString,oneof"` +} + +type Oneof_F_Bytes struct { + F_Bytes []byte `protobuf:"bytes,11,opt,name=F_Bytes,json=FBytes,oneof"` +} + +type Oneof_F_Sint32 struct { + F_Sint32 int32 `protobuf:"zigzag32,12,opt,name=F_Sint32,json=FSint32,oneof"` +} + +type Oneof_F_Sint64 struct { + F_Sint64 int64 `protobuf:"zigzag64,13,opt,name=F_Sint64,json=FSint64,oneof"` +} + +type Oneof_F_Enum struct { + F_Enum MyMessage_Color `protobuf:"varint,14,opt,name=F_Enum,json=FEnum,enum=proto2_test.MyMessage_Color,oneof"` +} + +type Oneof_F_Message struct { + F_Message *GoTestField `protobuf:"bytes,15,opt,name=F_Message,json=FMessage,oneof"` +} + +type Oneof_FGroup struct { + FGroup *Oneof_F_Group `protobuf:"group,16,opt,name=F_Group,json=fGroup,oneof"` +} + +type Oneof_F_Largest_Tag struct { + F_Largest_Tag int32 `protobuf:"varint,536870911,opt,name=F_Largest_Tag,json=FLargestTag,oneof"` +} + +func (*Oneof_F_Bool) isOneof_Union() {} + +func (*Oneof_F_Int32) isOneof_Union() {} + +func (*Oneof_F_Int64) isOneof_Union() {} + +func (*Oneof_F_Fixed32) isOneof_Union() {} + +func (*Oneof_F_Fixed64) isOneof_Union() {} + +func (*Oneof_F_Uint32) isOneof_Union() {} + +func (*Oneof_F_Uint64) isOneof_Union() {} + +func (*Oneof_F_Float) isOneof_Union() {} + +func (*Oneof_F_Double) isOneof_Union() {} + +func (*Oneof_F_String) isOneof_Union() {} + +func (*Oneof_F_Bytes) isOneof_Union() {} + +func (*Oneof_F_Sint32) isOneof_Union() {} + +func (*Oneof_F_Sint64) isOneof_Union() {} + +func (*Oneof_F_Enum) isOneof_Union() {} + +func (*Oneof_F_Message) isOneof_Union() {} + +func (*Oneof_FGroup) isOneof_Union() {} + +func (*Oneof_F_Largest_Tag) isOneof_Union() {} + +func (m *Oneof) GetUnion() isOneof_Union { + if m != nil { + return m.Union + } + return nil +} + +func (m *Oneof) GetF_Bool() bool { + if x, ok := m.GetUnion().(*Oneof_F_Bool); ok { + return x.F_Bool + } + return false +} + +func (m *Oneof) GetF_Int32() int32 { + if x, ok := m.GetUnion().(*Oneof_F_Int32); ok { + return x.F_Int32 + } + return 0 +} + +func (m *Oneof) GetF_Int64() int64 { + if x, ok := m.GetUnion().(*Oneof_F_Int64); ok { + return x.F_Int64 + } + return 0 +} + +func (m *Oneof) GetF_Fixed32() uint32 { + if x, ok := m.GetUnion().(*Oneof_F_Fixed32); ok { + return x.F_Fixed32 + } + return 0 +} + +func (m *Oneof) GetF_Fixed64() uint64 { + if x, ok := m.GetUnion().(*Oneof_F_Fixed64); ok { + return x.F_Fixed64 + } + return 0 +} + +func (m *Oneof) GetF_Uint32() uint32 { + if x, ok := m.GetUnion().(*Oneof_F_Uint32); ok { + return x.F_Uint32 + } + return 0 +} + +func (m *Oneof) GetF_Uint64() uint64 { + if x, ok := m.GetUnion().(*Oneof_F_Uint64); ok { + return x.F_Uint64 + } + return 0 +} + +func (m *Oneof) GetF_Float() float32 { + if x, ok := m.GetUnion().(*Oneof_F_Float); ok { + return x.F_Float + } + return 0 +} + +func (m *Oneof) GetF_Double() float64 { + if x, ok := m.GetUnion().(*Oneof_F_Double); ok { + return x.F_Double + } + return 0 +} + +func (m *Oneof) GetF_String() string { + if x, ok := m.GetUnion().(*Oneof_F_String); ok { + return x.F_String + } + return "" +} + +func (m *Oneof) GetF_Bytes() []byte { + if x, ok := m.GetUnion().(*Oneof_F_Bytes); ok { + return x.F_Bytes + } + return nil +} + +func (m *Oneof) GetF_Sint32() int32 { + if x, ok := m.GetUnion().(*Oneof_F_Sint32); ok { + return x.F_Sint32 + } + return 0 +} + +func (m *Oneof) GetF_Sint64() int64 { + if x, ok := m.GetUnion().(*Oneof_F_Sint64); ok { + return x.F_Sint64 + } + return 0 +} + +func (m *Oneof) GetF_Enum() MyMessage_Color { + if x, ok := m.GetUnion().(*Oneof_F_Enum); ok { + return x.F_Enum + } + return MyMessage_RED +} + +func (m *Oneof) GetF_Message() *GoTestField { + if x, ok := m.GetUnion().(*Oneof_F_Message); ok { + return x.F_Message + } + return nil +} + +func (m *Oneof) GetFGroup() *Oneof_F_Group { + if x, ok := m.GetUnion().(*Oneof_FGroup); ok { + return x.FGroup + } + return nil +} + +func (m *Oneof) GetF_Largest_Tag() int32 { + if x, ok := m.GetUnion().(*Oneof_F_Largest_Tag); ok { + return x.F_Largest_Tag + } + return 0 +} + +type isOneof_Tormato interface { + isOneof_Tormato() +} + +type Oneof_Value struct { + Value int32 `protobuf:"varint,100,opt,name=value,oneof"` +} + +func (*Oneof_Value) isOneof_Tormato() {} + +func (m *Oneof) GetTormato() isOneof_Tormato { + if m != nil { + return m.Tormato + } + return nil +} + +func (m *Oneof) GetValue() int32 { + if x, ok := m.GetTormato().(*Oneof_Value); ok { + return x.Value + } + return 0 +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*Oneof) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*Oneof_F_Bool)(nil), + (*Oneof_F_Int32)(nil), + (*Oneof_F_Int64)(nil), + (*Oneof_F_Fixed32)(nil), + (*Oneof_F_Fixed64)(nil), + (*Oneof_F_Uint32)(nil), + (*Oneof_F_Uint64)(nil), + (*Oneof_F_Float)(nil), + (*Oneof_F_Double)(nil), + (*Oneof_F_String)(nil), + (*Oneof_F_Bytes)(nil), + (*Oneof_F_Sint32)(nil), + (*Oneof_F_Sint64)(nil), + (*Oneof_F_Enum)(nil), + (*Oneof_F_Message)(nil), + (*Oneof_FGroup)(nil), + (*Oneof_F_Largest_Tag)(nil), + (*Oneof_Value)(nil), + } +} + +type Oneof_F_Group struct { + X *int32 `protobuf:"varint,17,opt,name=x" json:"x,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Oneof_F_Group) Reset() { *m = Oneof_F_Group{} } +func (m *Oneof_F_Group) String() string { return proto.CompactTextString(m) } +func (*Oneof_F_Group) ProtoMessage() {} +func (*Oneof_F_Group) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{28, 0} +} + +func (m *Oneof_F_Group) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Oneof_F_Group.Unmarshal(m, b) +} +func (m *Oneof_F_Group) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Oneof_F_Group.Marshal(b, m, deterministic) +} +func (m *Oneof_F_Group) XXX_Merge(src proto.Message) { + xxx_messageInfo_Oneof_F_Group.Merge(m, src) +} +func (m *Oneof_F_Group) XXX_Size() int { + return xxx_messageInfo_Oneof_F_Group.Size(m) +} +func (m *Oneof_F_Group) XXX_DiscardUnknown() { + xxx_messageInfo_Oneof_F_Group.DiscardUnknown(m) +} + +var xxx_messageInfo_Oneof_F_Group proto.InternalMessageInfo + +func (m *Oneof_F_Group) GetX() int32 { + if m != nil && m.X != nil { + return *m.X + } + return 0 +} + +type Communique struct { + MakeMeCry *bool `protobuf:"varint,1,opt,name=make_me_cry,json=makeMeCry" json:"make_me_cry,omitempty"` + // This is a oneof, called "union". + // + // Types that are valid to be assigned to Union: + // *Communique_Number + // *Communique_Name + // *Communique_Data + // *Communique_TempC + // *Communique_Col + // *Communique_Msg + Union isCommunique_Union `protobuf_oneof:"union"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Communique) Reset() { *m = Communique{} } +func (m *Communique) String() string { return proto.CompactTextString(m) } +func (*Communique) ProtoMessage() {} +func (*Communique) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{29} +} + +func (m *Communique) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Communique.Unmarshal(m, b) +} +func (m *Communique) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Communique.Marshal(b, m, deterministic) +} +func (m *Communique) XXX_Merge(src proto.Message) { + xxx_messageInfo_Communique.Merge(m, src) +} +func (m *Communique) XXX_Size() int { + return xxx_messageInfo_Communique.Size(m) +} +func (m *Communique) XXX_DiscardUnknown() { + xxx_messageInfo_Communique.DiscardUnknown(m) +} + +var xxx_messageInfo_Communique proto.InternalMessageInfo + +func (m *Communique) GetMakeMeCry() bool { + if m != nil && m.MakeMeCry != nil { + return *m.MakeMeCry + } + return false +} + +type isCommunique_Union interface { + isCommunique_Union() +} + +type Communique_Number struct { + Number int32 `protobuf:"varint,5,opt,name=number,oneof"` +} + +type Communique_Name struct { + Name string `protobuf:"bytes,6,opt,name=name,oneof"` +} + +type Communique_Data struct { + Data []byte `protobuf:"bytes,7,opt,name=data,oneof"` +} + +type Communique_TempC struct { + TempC float64 `protobuf:"fixed64,8,opt,name=temp_c,json=tempC,oneof"` +} + +type Communique_Col struct { + Col MyMessage_Color `protobuf:"varint,9,opt,name=col,enum=proto2_test.MyMessage_Color,oneof"` +} + +type Communique_Msg struct { + Msg *Strings `protobuf:"bytes,10,opt,name=msg,oneof"` +} + +func (*Communique_Number) isCommunique_Union() {} + +func (*Communique_Name) isCommunique_Union() {} + +func (*Communique_Data) isCommunique_Union() {} + +func (*Communique_TempC) isCommunique_Union() {} + +func (*Communique_Col) isCommunique_Union() {} + +func (*Communique_Msg) isCommunique_Union() {} + +func (m *Communique) GetUnion() isCommunique_Union { + if m != nil { + return m.Union + } + return nil +} + +func (m *Communique) GetNumber() int32 { + if x, ok := m.GetUnion().(*Communique_Number); ok { + return x.Number + } + return 0 +} + +func (m *Communique) GetName() string { + if x, ok := m.GetUnion().(*Communique_Name); ok { + return x.Name + } + return "" +} + +func (m *Communique) GetData() []byte { + if x, ok := m.GetUnion().(*Communique_Data); ok { + return x.Data + } + return nil +} + +func (m *Communique) GetTempC() float64 { + if x, ok := m.GetUnion().(*Communique_TempC); ok { + return x.TempC + } + return 0 +} + +func (m *Communique) GetCol() MyMessage_Color { + if x, ok := m.GetUnion().(*Communique_Col); ok { + return x.Col + } + return MyMessage_RED +} + +func (m *Communique) GetMsg() *Strings { + if x, ok := m.GetUnion().(*Communique_Msg); ok { + return x.Msg + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*Communique) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*Communique_Number)(nil), + (*Communique_Name)(nil), + (*Communique_Data)(nil), + (*Communique_TempC)(nil), + (*Communique_Col)(nil), + (*Communique_Msg)(nil), + } +} + +type TestUTF8 struct { + Scalar *string `protobuf:"bytes,1,opt,name=scalar" json:"scalar,omitempty"` + Vector []string `protobuf:"bytes,2,rep,name=vector" json:"vector,omitempty"` + // Types that are valid to be assigned to Oneof: + // *TestUTF8_Field + Oneof isTestUTF8_Oneof `protobuf_oneof:"oneof"` + MapKey map[string]int64 `protobuf:"bytes,4,rep,name=map_key,json=mapKey" json:"map_key,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` + MapValue map[int64]string `protobuf:"bytes,5,rep,name=map_value,json=mapValue" json:"map_value,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TestUTF8) Reset() { *m = TestUTF8{} } +func (m *TestUTF8) String() string { return proto.CompactTextString(m) } +func (*TestUTF8) ProtoMessage() {} +func (*TestUTF8) Descriptor() ([]byte, []int) { + return fileDescriptor_e5b3e7ca68f98362, []int{30} +} + +func (m *TestUTF8) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TestUTF8.Unmarshal(m, b) +} +func (m *TestUTF8) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TestUTF8.Marshal(b, m, deterministic) +} +func (m *TestUTF8) XXX_Merge(src proto.Message) { + xxx_messageInfo_TestUTF8.Merge(m, src) +} +func (m *TestUTF8) XXX_Size() int { + return xxx_messageInfo_TestUTF8.Size(m) +} +func (m *TestUTF8) XXX_DiscardUnknown() { + xxx_messageInfo_TestUTF8.DiscardUnknown(m) +} + +var xxx_messageInfo_TestUTF8 proto.InternalMessageInfo + +func (m *TestUTF8) GetScalar() string { + if m != nil && m.Scalar != nil { + return *m.Scalar + } + return "" +} + +func (m *TestUTF8) GetVector() []string { + if m != nil { + return m.Vector + } + return nil +} + +type isTestUTF8_Oneof interface { + isTestUTF8_Oneof() +} + +type TestUTF8_Field struct { + Field string `protobuf:"bytes,3,opt,name=field,oneof"` +} + +func (*TestUTF8_Field) isTestUTF8_Oneof() {} + +func (m *TestUTF8) GetOneof() isTestUTF8_Oneof { + if m != nil { + return m.Oneof + } + return nil +} + +func (m *TestUTF8) GetField() string { + if x, ok := m.GetOneof().(*TestUTF8_Field); ok { + return x.Field + } + return "" +} + +func (m *TestUTF8) GetMapKey() map[string]int64 { + if m != nil { + return m.MapKey + } + return nil +} + +func (m *TestUTF8) GetMapValue() map[int64]string { + if m != nil { + return m.MapValue + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*TestUTF8) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*TestUTF8_Field)(nil), + } +} + +var E_Greeting = &proto.ExtensionDesc{ + ExtendedType: (*MyMessage)(nil), + ExtensionType: ([]string)(nil), + Field: 106, + Name: "proto2_test.greeting", + Tag: "bytes,106,rep,name=greeting", + Filename: "proto2_proto/test.proto", +} + +var E_Complex = &proto.ExtensionDesc{ + ExtendedType: (*OtherMessage)(nil), + ExtensionType: (*ComplexExtension)(nil), + Field: 200, + Name: "proto2_test.complex", + Tag: "bytes,200,opt,name=complex", + Filename: "proto2_proto/test.proto", +} + +var E_RComplex = &proto.ExtensionDesc{ + ExtendedType: (*OtherMessage)(nil), + ExtensionType: ([]*ComplexExtension)(nil), + Field: 201, + Name: "proto2_test.r_complex", + Tag: "bytes,201,rep,name=r_complex", + Filename: "proto2_proto/test.proto", +} + +var E_NoDefaultDouble = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*float64)(nil), + Field: 101, + Name: "proto2_test.no_default_double", + Tag: "fixed64,101,opt,name=no_default_double", + Filename: "proto2_proto/test.proto", +} + +var E_NoDefaultFloat = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*float32)(nil), + Field: 102, + Name: "proto2_test.no_default_float", + Tag: "fixed32,102,opt,name=no_default_float", + Filename: "proto2_proto/test.proto", +} + +var E_NoDefaultInt32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 103, + Name: "proto2_test.no_default_int32", + Tag: "varint,103,opt,name=no_default_int32", + Filename: "proto2_proto/test.proto", +} + +var E_NoDefaultInt64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 104, + Name: "proto2_test.no_default_int64", + Tag: "varint,104,opt,name=no_default_int64", + Filename: "proto2_proto/test.proto", +} + +var E_NoDefaultUint32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint32)(nil), + Field: 105, + Name: "proto2_test.no_default_uint32", + Tag: "varint,105,opt,name=no_default_uint32", + Filename: "proto2_proto/test.proto", +} + +var E_NoDefaultUint64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint64)(nil), + Field: 106, + Name: "proto2_test.no_default_uint64", + Tag: "varint,106,opt,name=no_default_uint64", + Filename: "proto2_proto/test.proto", +} + +var E_NoDefaultSint32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 107, + Name: "proto2_test.no_default_sint32", + Tag: "zigzag32,107,opt,name=no_default_sint32", + Filename: "proto2_proto/test.proto", +} + +var E_NoDefaultSint64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 108, + Name: "proto2_test.no_default_sint64", + Tag: "zigzag64,108,opt,name=no_default_sint64", + Filename: "proto2_proto/test.proto", +} + +var E_NoDefaultFixed32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint32)(nil), + Field: 109, + Name: "proto2_test.no_default_fixed32", + Tag: "fixed32,109,opt,name=no_default_fixed32", + Filename: "proto2_proto/test.proto", +} + +var E_NoDefaultFixed64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint64)(nil), + Field: 110, + Name: "proto2_test.no_default_fixed64", + Tag: "fixed64,110,opt,name=no_default_fixed64", + Filename: "proto2_proto/test.proto", +} + +var E_NoDefaultSfixed32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 111, + Name: "proto2_test.no_default_sfixed32", + Tag: "fixed32,111,opt,name=no_default_sfixed32", + Filename: "proto2_proto/test.proto", +} + +var E_NoDefaultSfixed64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 112, + Name: "proto2_test.no_default_sfixed64", + Tag: "fixed64,112,opt,name=no_default_sfixed64", + Filename: "proto2_proto/test.proto", +} + +var E_NoDefaultBool = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*bool)(nil), + Field: 113, + Name: "proto2_test.no_default_bool", + Tag: "varint,113,opt,name=no_default_bool", + Filename: "proto2_proto/test.proto", +} + +var E_NoDefaultString = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*string)(nil), + Field: 114, + Name: "proto2_test.no_default_string", + Tag: "bytes,114,opt,name=no_default_string", + Filename: "proto2_proto/test.proto", +} + +var E_NoDefaultBytes = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: ([]byte)(nil), + Field: 115, + Name: "proto2_test.no_default_bytes", + Tag: "bytes,115,opt,name=no_default_bytes", + Filename: "proto2_proto/test.proto", +} + +var E_NoDefaultEnum = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*DefaultsMessage_DefaultsEnum)(nil), + Field: 116, + Name: "proto2_test.no_default_enum", + Tag: "varint,116,opt,name=no_default_enum,enum=proto2_test.DefaultsMessage_DefaultsEnum", + Filename: "proto2_proto/test.proto", +} + +var E_DefaultDouble = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*float64)(nil), + Field: 201, + Name: "proto2_test.default_double", + Tag: "fixed64,201,opt,name=default_double,def=3.1415", + Filename: "proto2_proto/test.proto", +} + +var E_DefaultFloat = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*float32)(nil), + Field: 202, + Name: "proto2_test.default_float", + Tag: "fixed32,202,opt,name=default_float,def=3.14", + Filename: "proto2_proto/test.proto", +} + +var E_DefaultInt32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 203, + Name: "proto2_test.default_int32", + Tag: "varint,203,opt,name=default_int32,def=42", + Filename: "proto2_proto/test.proto", +} + +var E_DefaultInt64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 204, + Name: "proto2_test.default_int64", + Tag: "varint,204,opt,name=default_int64,def=43", + Filename: "proto2_proto/test.proto", +} + +var E_DefaultUint32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint32)(nil), + Field: 205, + Name: "proto2_test.default_uint32", + Tag: "varint,205,opt,name=default_uint32,def=44", + Filename: "proto2_proto/test.proto", +} + +var E_DefaultUint64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint64)(nil), + Field: 206, + Name: "proto2_test.default_uint64", + Tag: "varint,206,opt,name=default_uint64,def=45", + Filename: "proto2_proto/test.proto", +} + +var E_DefaultSint32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 207, + Name: "proto2_test.default_sint32", + Tag: "zigzag32,207,opt,name=default_sint32,def=46", + Filename: "proto2_proto/test.proto", +} + +var E_DefaultSint64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 208, + Name: "proto2_test.default_sint64", + Tag: "zigzag64,208,opt,name=default_sint64,def=47", + Filename: "proto2_proto/test.proto", +} + +var E_DefaultFixed32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint32)(nil), + Field: 209, + Name: "proto2_test.default_fixed32", + Tag: "fixed32,209,opt,name=default_fixed32,def=48", + Filename: "proto2_proto/test.proto", +} + +var E_DefaultFixed64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint64)(nil), + Field: 210, + Name: "proto2_test.default_fixed64", + Tag: "fixed64,210,opt,name=default_fixed64,def=49", + Filename: "proto2_proto/test.proto", +} + +var E_DefaultSfixed32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 211, + Name: "proto2_test.default_sfixed32", + Tag: "fixed32,211,opt,name=default_sfixed32,def=50", + Filename: "proto2_proto/test.proto", +} + +var E_DefaultSfixed64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 212, + Name: "proto2_test.default_sfixed64", + Tag: "fixed64,212,opt,name=default_sfixed64,def=51", + Filename: "proto2_proto/test.proto", +} + +var E_DefaultBool = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*bool)(nil), + Field: 213, + Name: "proto2_test.default_bool", + Tag: "varint,213,opt,name=default_bool,def=1", + Filename: "proto2_proto/test.proto", +} + +var E_DefaultString = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*string)(nil), + Field: 214, + Name: "proto2_test.default_string", + Tag: "bytes,214,opt,name=default_string,def=Hello, string,def=foo", + Filename: "proto2_proto/test.proto", +} + +var E_DefaultBytes = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: ([]byte)(nil), + Field: 215, + Name: "proto2_test.default_bytes", + Tag: "bytes,215,opt,name=default_bytes,def=Hello, bytes", + Filename: "proto2_proto/test.proto", +} + +var E_DefaultEnum = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*DefaultsMessage_DefaultsEnum)(nil), + Field: 216, + Name: "proto2_test.default_enum", + Tag: "varint,216,opt,name=default_enum,enum=proto2_test.DefaultsMessage_DefaultsEnum,def=1", + Filename: "proto2_proto/test.proto", +} + +func init() { + proto.RegisterEnum("proto2_test.FOO", FOO_name, FOO_value) + proto.RegisterEnum("proto2_test.GoTest_KIND", GoTest_KIND_name, GoTest_KIND_value) + proto.RegisterEnum("proto2_test.MyMessage_Color", MyMessage_Color_name, MyMessage_Color_value) + proto.RegisterEnum("proto2_test.DefaultsMessage_DefaultsEnum", DefaultsMessage_DefaultsEnum_name, DefaultsMessage_DefaultsEnum_value) + proto.RegisterEnum("proto2_test.Defaults_Color", Defaults_Color_name, Defaults_Color_value) + proto.RegisterEnum("proto2_test.RepeatedEnum_Color", RepeatedEnum_Color_name, RepeatedEnum_Color_value) + proto.RegisterType((*GoEnum)(nil), "proto2_test.GoEnum") + proto.RegisterType((*GoTestField)(nil), "proto2_test.GoTestField") + proto.RegisterType((*GoTest)(nil), "proto2_test.GoTest") + proto.RegisterType((*GoTest_RequiredGroup)(nil), "proto2_test.GoTest.RequiredGroup") + proto.RegisterType((*GoTest_RepeatedGroup)(nil), "proto2_test.GoTest.RepeatedGroup") + proto.RegisterType((*GoTest_OptionalGroup)(nil), "proto2_test.GoTest.OptionalGroup") + proto.RegisterType((*GoTestRequiredGroupField)(nil), "proto2_test.GoTestRequiredGroupField") + proto.RegisterType((*GoTestRequiredGroupField_Group)(nil), "proto2_test.GoTestRequiredGroupField.Group") + proto.RegisterType((*GoSkipTest)(nil), "proto2_test.GoSkipTest") + proto.RegisterType((*GoSkipTest_SkipGroup)(nil), "proto2_test.GoSkipTest.SkipGroup") + proto.RegisterType((*NonPackedTest)(nil), "proto2_test.NonPackedTest") + proto.RegisterType((*PackedTest)(nil), "proto2_test.PackedTest") + proto.RegisterType((*MaxTag)(nil), "proto2_test.MaxTag") + proto.RegisterType((*OldMessage)(nil), "proto2_test.OldMessage") + proto.RegisterType((*OldMessage_Nested)(nil), "proto2_test.OldMessage.Nested") + proto.RegisterType((*NewMessage)(nil), "proto2_test.NewMessage") + proto.RegisterType((*NewMessage_Nested)(nil), "proto2_test.NewMessage.Nested") + proto.RegisterType((*InnerMessage)(nil), "proto2_test.InnerMessage") + proto.RegisterType((*OtherMessage)(nil), "proto2_test.OtherMessage") + proto.RegisterType((*RequiredInnerMessage)(nil), "proto2_test.RequiredInnerMessage") + proto.RegisterType((*MyMessage)(nil), "proto2_test.MyMessage") + proto.RegisterType((*MyMessage_SomeGroup)(nil), "proto2_test.MyMessage.SomeGroup") + proto.RegisterExtension(E_Ext_More) + proto.RegisterExtension(E_Ext_Text) + proto.RegisterExtension(E_Ext_Number) + proto.RegisterType((*Ext)(nil), "proto2_test.Ext") + proto.RegisterMapType((map[int32]int32)(nil), "proto2_test.Ext.MapFieldEntry") + proto.RegisterType((*ComplexExtension)(nil), "proto2_test.ComplexExtension") + proto.RegisterType((*DefaultsMessage)(nil), "proto2_test.DefaultsMessage") + proto.RegisterType((*Empty)(nil), "proto2_test.Empty") + proto.RegisterType((*MessageList)(nil), "proto2_test.MessageList") + proto.RegisterType((*MessageList_Message)(nil), "proto2_test.MessageList.Message") + proto.RegisterType((*Strings)(nil), "proto2_test.Strings") + proto.RegisterType((*Defaults)(nil), "proto2_test.Defaults") + proto.RegisterType((*SubDefaults)(nil), "proto2_test.SubDefaults") + proto.RegisterType((*RepeatedEnum)(nil), "proto2_test.RepeatedEnum") + proto.RegisterType((*MoreRepeated)(nil), "proto2_test.MoreRepeated") + proto.RegisterType((*GroupOld)(nil), "proto2_test.GroupOld") + proto.RegisterType((*GroupOld_G)(nil), "proto2_test.GroupOld.G") + proto.RegisterType((*GroupNew)(nil), "proto2_test.GroupNew") + proto.RegisterType((*GroupNew_G)(nil), "proto2_test.GroupNew.G") + proto.RegisterType((*FloatingPoint)(nil), "proto2_test.FloatingPoint") + proto.RegisterType((*MessageWithMap)(nil), "proto2_test.MessageWithMap") + proto.RegisterMapType((map[bool][]byte)(nil), "proto2_test.MessageWithMap.ByteMappingEntry") + proto.RegisterMapType((map[int64]*FloatingPoint)(nil), "proto2_test.MessageWithMap.MsgMappingEntry") + proto.RegisterMapType((map[int32]string)(nil), "proto2_test.MessageWithMap.NameMappingEntry") + proto.RegisterMapType((map[string]string)(nil), "proto2_test.MessageWithMap.StrToStrEntry") + proto.RegisterType((*Oneof)(nil), "proto2_test.Oneof") + proto.RegisterType((*Oneof_F_Group)(nil), "proto2_test.Oneof.F_Group") + proto.RegisterType((*Communique)(nil), "proto2_test.Communique") + proto.RegisterType((*TestUTF8)(nil), "proto2_test.TestUTF8") + proto.RegisterMapType((map[string]int64)(nil), "proto2_test.TestUTF8.MapKeyEntry") + proto.RegisterMapType((map[int64]string)(nil), "proto2_test.TestUTF8.MapValueEntry") + proto.RegisterExtension(E_Greeting) + proto.RegisterExtension(E_Complex) + proto.RegisterExtension(E_RComplex) + proto.RegisterExtension(E_NoDefaultDouble) + proto.RegisterExtension(E_NoDefaultFloat) + proto.RegisterExtension(E_NoDefaultInt32) + proto.RegisterExtension(E_NoDefaultInt64) + proto.RegisterExtension(E_NoDefaultUint32) + proto.RegisterExtension(E_NoDefaultUint64) + proto.RegisterExtension(E_NoDefaultSint32) + proto.RegisterExtension(E_NoDefaultSint64) + proto.RegisterExtension(E_NoDefaultFixed32) + proto.RegisterExtension(E_NoDefaultFixed64) + proto.RegisterExtension(E_NoDefaultSfixed32) + proto.RegisterExtension(E_NoDefaultSfixed64) + proto.RegisterExtension(E_NoDefaultBool) + proto.RegisterExtension(E_NoDefaultString) + proto.RegisterExtension(E_NoDefaultBytes) + proto.RegisterExtension(E_NoDefaultEnum) + proto.RegisterExtension(E_DefaultDouble) + proto.RegisterExtension(E_DefaultFloat) + proto.RegisterExtension(E_DefaultInt32) + proto.RegisterExtension(E_DefaultInt64) + proto.RegisterExtension(E_DefaultUint32) + proto.RegisterExtension(E_DefaultUint64) + proto.RegisterExtension(E_DefaultSint32) + proto.RegisterExtension(E_DefaultSint64) + proto.RegisterExtension(E_DefaultFixed32) + proto.RegisterExtension(E_DefaultFixed64) + proto.RegisterExtension(E_DefaultSfixed32) + proto.RegisterExtension(E_DefaultSfixed64) + proto.RegisterExtension(E_DefaultBool) + proto.RegisterExtension(E_DefaultString) + proto.RegisterExtension(E_DefaultBytes) + proto.RegisterExtension(E_DefaultEnum) +} + +func init() { proto.RegisterFile("proto2_proto/test.proto", fileDescriptor_e5b3e7ca68f98362) } + +var fileDescriptor_e5b3e7ca68f98362 = []byte{ + // 4330 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x5b, 0x4b, 0x73, 0xdb, 0x58, + 0x76, 0x36, 0xc0, 0xf7, 0x21, 0x25, 0x42, 0xb7, 0xd5, 0x36, 0x2d, 0xb5, 0x6d, 0x98, 0x3d, 0x3d, + 0xc3, 0xb6, 0xdd, 0xb4, 0x4c, 0x51, 0xb4, 0x4d, 0x4f, 0x3b, 0x63, 0xd9, 0xa2, 0xac, 0xb4, 0x24, + 0x7a, 0x20, 0xb9, 0xbb, 0xda, 0xb3, 0x60, 0x41, 0x22, 0x48, 0x71, 0x4c, 0x02, 0x6c, 0x12, 0x1c, + 0x4b, 0xa9, 0x54, 0xaa, 0xb7, 0xd9, 0xa4, 0x2a, 0x99, 0xa4, 0x2a, 0x3f, 0x20, 0xdb, 0xc9, 0x63, + 0x97, 0x45, 0x7e, 0x40, 0x7a, 0x1e, 0x49, 0x26, 0xef, 0xac, 0x52, 0xf9, 0x07, 0x59, 0xe5, 0xb1, + 0xea, 0xa9, 0x73, 0xee, 0x05, 0x70, 0x01, 0x52, 0xaf, 0x95, 0x70, 0xef, 0xfd, 0xbe, 0x73, 0x5f, + 0x1f, 0xce, 0x39, 0xf7, 0x12, 0x82, 0x6b, 0xc3, 0x91, 0xe3, 0x3a, 0x95, 0x16, 0xfd, 0xb9, 0xef, + 0x5a, 0x63, 0xb7, 0x4c, 0x8f, 0x2c, 0x2b, 0x1a, 0xb0, 0xaa, 0x78, 0x0f, 0x92, 0x9b, 0xce, 0x86, + 0x3d, 0x19, 0xb0, 0x22, 0xc4, 0x3a, 0x8e, 0x53, 0x50, 0x74, 0xb5, 0x34, 0x5f, 0xd1, 0xca, 0x12, + 0xa8, 0xdc, 0x68, 0x36, 0x0d, 0x6c, 0x2c, 0x3e, 0x84, 0xec, 0xa6, 0xb3, 0x6f, 0x8d, 0xdd, 0x46, + 0xcf, 0xea, 0xb7, 0xd9, 0x22, 0x24, 0xb6, 0xcd, 0x03, 0xab, 0x4f, 0xa4, 0x8c, 0xc1, 0x0b, 0x8c, + 0x41, 0x7c, 0xff, 0x64, 0x68, 0x15, 0x54, 0xaa, 0xa4, 0xe7, 0xe2, 0xdf, 0x14, 0xb1, 0x1f, 0x64, + 0xb2, 0x7b, 0x10, 0xff, 0xac, 0x67, 0xb7, 0x45, 0x47, 0x85, 0x50, 0x47, 0x1c, 0x52, 0xfe, 0x6c, + 0x6b, 0xf7, 0x85, 0x41, 0x28, 0xec, 0x62, 0xdf, 0x3c, 0xe8, 0xa3, 0x35, 0x05, 0xbb, 0xa0, 0x02, + 0xd6, 0xbe, 0x32, 0x47, 0xe6, 0xa0, 0x10, 0xd3, 0x95, 0x52, 0xc2, 0xe0, 0x05, 0xf6, 0x14, 0xe6, + 0x0c, 0xeb, 0xab, 0x49, 0x6f, 0x64, 0xb5, 0x69, 0x7c, 0x85, 0xb8, 0xae, 0x96, 0xb2, 0x33, 0xbb, + 0xa0, 0x76, 0x23, 0x0c, 0xe7, 0xfc, 0xa1, 0x65, 0xba, 0x1e, 0x3f, 0xa1, 0xc7, 0xce, 0xe3, 0x4b, + 0x70, 0xe4, 0x37, 0x87, 0x6e, 0xcf, 0xb1, 0xcd, 0x3e, 0xe7, 0x27, 0x75, 0xe5, 0x6c, 0x7e, 0x08, + 0xce, 0xbe, 0x0b, 0xf9, 0x46, 0x6b, 0xdd, 0x71, 0xfa, 0xad, 0x91, 0x18, 0x57, 0x01, 0x74, 0xb5, + 0x94, 0x36, 0xe6, 0x1a, 0x58, 0xeb, 0x0d, 0x96, 0x95, 0x40, 0x6b, 0xb4, 0xb6, 0x6c, 0x77, 0xb5, + 0x12, 0x00, 0xb3, 0xba, 0x5a, 0x4a, 0x18, 0xf3, 0x0d, 0xaa, 0x9e, 0x42, 0xd6, 0xaa, 0x01, 0x32, + 0xa7, 0xab, 0xa5, 0x18, 0x47, 0xd6, 0xaa, 0x3e, 0xf2, 0x1e, 0xb0, 0x46, 0xab, 0xd1, 0x3b, 0xb6, + 0xda, 0xb2, 0xd5, 0x39, 0x5d, 0x2d, 0xa5, 0x0c, 0xad, 0x21, 0x1a, 0x66, 0xa0, 0x65, 0xcb, 0xf3, + 0xba, 0x5a, 0x4a, 0x7a, 0x68, 0xc9, 0xf6, 0x1d, 0x58, 0x68, 0xb4, 0x5e, 0xf7, 0xc2, 0x03, 0xce, + 0xeb, 0x6a, 0x69, 0xce, 0xc8, 0x37, 0x78, 0xfd, 0x34, 0x56, 0x36, 0xac, 0xe9, 0x6a, 0x29, 0x2e, + 0xb0, 0x92, 0x5d, 0x9a, 0x5d, 0xa3, 0xef, 0x98, 0x6e, 0x00, 0x5d, 0xd0, 0xd5, 0x92, 0x6a, 0xcc, + 0x37, 0xa8, 0x3a, 0x6c, 0xf5, 0x85, 0x33, 0x39, 0xe8, 0x5b, 0x01, 0x94, 0xe9, 0x6a, 0x49, 0x31, + 0xf2, 0x0d, 0x5e, 0x1f, 0xc6, 0xee, 0xb9, 0xa3, 0x9e, 0xdd, 0x0d, 0xb0, 0xef, 0x91, 0x96, 0xf3, + 0x0d, 0x5e, 0x1f, 0x1e, 0xc1, 0xfa, 0x89, 0x6b, 0x8d, 0x03, 0xa8, 0xa5, 0xab, 0xa5, 0x9c, 0x31, + 0xdf, 0xa0, 0xea, 0x88, 0xd5, 0xc8, 0x1a, 0x74, 0x74, 0xb5, 0xb4, 0x80, 0x56, 0x67, 0xac, 0xc1, + 0x5e, 0x64, 0x0d, 0xba, 0xba, 0x5a, 0x62, 0x02, 0x2b, 0xad, 0x41, 0x19, 0xde, 0x6b, 0xb4, 0xf6, + 0x3a, 0xd1, 0x8d, 0x3b, 0xd2, 0xd5, 0x52, 0xde, 0x58, 0x68, 0x78, 0x2d, 0xb3, 0xf0, 0xb2, 0xf5, + 0x9e, 0xae, 0x96, 0x34, 0x1f, 0x2f, 0xd9, 0x97, 0x35, 0xc9, 0xb5, 0x5e, 0x58, 0xd4, 0x63, 0x92, + 0x26, 0x79, 0x65, 0x58, 0x93, 0x02, 0xf8, 0xbe, 0x1e, 0x93, 0x35, 0x19, 0x41, 0x52, 0xf7, 0x02, + 0x79, 0x55, 0x8f, 0xc9, 0x9a, 0x14, 0xc8, 0x88, 0x26, 0x05, 0xf6, 0x9a, 0x1e, 0x0b, 0x6b, 0x72, + 0x0a, 0x2d, 0x5b, 0x2e, 0xe8, 0xb1, 0xb0, 0x26, 0x05, 0x3a, 0xac, 0x49, 0x01, 0xbe, 0xae, 0xc7, + 0x42, 0x9a, 0x8c, 0x62, 0x65, 0xc3, 0x4b, 0x7a, 0x2c, 0xa4, 0x49, 0x79, 0x76, 0x9e, 0x26, 0x05, + 0x74, 0x59, 0x8f, 0xc9, 0x9a, 0x94, 0xad, 0xfa, 0x9a, 0x14, 0xd0, 0x0f, 0xf4, 0x58, 0x48, 0x93, + 0x32, 0xd6, 0xd7, 0xa4, 0xc0, 0xde, 0xd0, 0x63, 0x21, 0x4d, 0x0a, 0xec, 0xc7, 0xb2, 0x26, 0x05, + 0xf4, 0x1b, 0x45, 0x8f, 0xc9, 0xa2, 0x14, 0xd0, 0xbb, 0x21, 0x51, 0x0a, 0xec, 0xcf, 0x11, 0x2b, + 0xab, 0x32, 0x0a, 0x96, 0x57, 0xe1, 0x17, 0x08, 0x96, 0x65, 0x29, 0xc0, 0xf7, 0x23, 0xb2, 0x14, + 0xf0, 0x5f, 0x22, 0x3c, 0xac, 0xcb, 0x69, 0x82, 0x6c, 0xff, 0x57, 0x48, 0x08, 0x0b, 0x53, 0x10, + 0x02, 0x61, 0x3a, 0xc2, 0x89, 0x16, 0x6e, 0xea, 0x8a, 0x2f, 0x4c, 0xcf, 0xb3, 0xca, 0xc2, 0xf4, + 0x81, 0xb7, 0x28, 0x6a, 0x08, 0x61, 0x4e, 0x21, 0x6b, 0xd5, 0x00, 0xa9, 0xeb, 0x4a, 0x20, 0x4c, + 0x1f, 0x19, 0x12, 0xa6, 0x8f, 0xbd, 0xad, 0x2b, 0xb2, 0x30, 0x67, 0xa0, 0x65, 0xcb, 0x45, 0x5d, + 0x91, 0x85, 0xe9, 0xa3, 0x65, 0x61, 0xfa, 0xe0, 0x0f, 0x75, 0x45, 0x12, 0xe6, 0x34, 0x56, 0x36, + 0xfc, 0x1d, 0x5d, 0x91, 0x84, 0x19, 0x9e, 0x1d, 0x17, 0xa6, 0x0f, 0xfd, 0x48, 0x57, 0x02, 0x61, + 0x86, 0xad, 0x0a, 0x61, 0xfa, 0xd0, 0xef, 0xea, 0x8a, 0x24, 0xcc, 0x30, 0x56, 0x08, 0xd3, 0xc7, + 0x7e, 0x8f, 0x42, 0xb5, 0x27, 0x4c, 0x1f, 0x2b, 0x09, 0xd3, 0x87, 0xfe, 0x0c, 0xc3, 0xba, 0x2f, + 0x4c, 0x1f, 0x2a, 0x0b, 0xd3, 0xc7, 0xfe, 0x39, 0x62, 0x03, 0x61, 0x4e, 0x83, 0xe5, 0x55, 0xf8, + 0x0b, 0x04, 0x07, 0xc2, 0xf4, 0xc1, 0x61, 0x61, 0xfa, 0xf0, 0xbf, 0x44, 0xb8, 0x2c, 0xcc, 0x59, + 0x04, 0xd9, 0xfe, 0x5f, 0x21, 0x41, 0x16, 0xa6, 0x4f, 0x28, 0xd3, 0x34, 0x51, 0x98, 0x6d, 0xab, + 0x63, 0x4e, 0xfa, 0x28, 0xe3, 0x12, 0x2a, 0xb3, 0x1e, 0x77, 0x47, 0x13, 0x0b, 0xe7, 0xea, 0x38, + 0xfd, 0x17, 0x5e, 0x1b, 0x2b, 0xe3, 0xf0, 0xb9, 0x40, 0x03, 0xc2, 0xc7, 0xa8, 0xd0, 0xba, 0xba, + 0x5a, 0x31, 0xf2, 0x5c, 0xa5, 0xd3, 0xf8, 0x5a, 0x55, 0xc2, 0xdf, 0x41, 0x9d, 0xd6, 0xd5, 0x5a, + 0x95, 0xe3, 0x6b, 0xd5, 0x00, 0xbf, 0x8a, 0x13, 0xf0, 0xc4, 0x1a, 0x30, 0xee, 0xa2, 0x5a, 0xeb, + 0xb1, 0xd5, 0xca, 0x8a, 0xb1, 0xe0, 0x49, 0x76, 0x16, 0x29, 0xd4, 0xcd, 0x3d, 0x14, 0x6d, 0x3d, + 0x56, 0xab, 0xfa, 0x24, 0xb9, 0xa7, 0x0a, 0x0a, 0x5d, 0x48, 0x37, 0xe0, 0x7c, 0x82, 0xda, 0xad, + 0xc7, 0x57, 0x2b, 0x2b, 0x2b, 0x86, 0x26, 0x14, 0x3c, 0x83, 0x13, 0xea, 0xa7, 0x8c, 0x1a, 0xae, + 0xc7, 0x6b, 0x55, 0x9f, 0x13, 0xee, 0x67, 0xc1, 0x93, 0x72, 0x40, 0xb9, 0x8f, 0x5a, 0xae, 0x27, + 0x57, 0x1f, 0x54, 0x1f, 0xac, 0x3d, 0x36, 0xf2, 0x5c, 0xd3, 0x01, 0xa7, 0x8a, 0xfd, 0x08, 0x51, + 0x07, 0xa4, 0x15, 0x54, 0x75, 0x3d, 0x59, 0x79, 0xf8, 0xe0, 0x51, 0xe5, 0x91, 0xa1, 0x09, 0x75, + 0x07, 0xac, 0xa7, 0xc8, 0x12, 0xf2, 0x0e, 0x58, 0x0f, 0x50, 0xdf, 0x75, 0xed, 0xc8, 0xea, 0xf7, + 0x9d, 0x7b, 0x7a, 0xf1, 0x9d, 0x33, 0xea, 0xb7, 0x6f, 0x17, 0xc1, 0xd0, 0x84, 0xe2, 0xe5, 0x5e, + 0x17, 0x3c, 0xc9, 0x07, 0xf4, 0x3f, 0xc4, 0xa4, 0x35, 0x57, 0x4f, 0xad, 0xf7, 0xba, 0xb6, 0x33, + 0xb6, 0x8c, 0x3c, 0x17, 0x7f, 0x64, 0x4d, 0xf6, 0xa2, 0xeb, 0xf8, 0x47, 0x48, 0x5b, 0xa8, 0xc7, + 0x3e, 0x59, 0xad, 0x60, 0x4f, 0xb3, 0xd6, 0x71, 0x2f, 0xba, 0x8e, 0x3f, 0x45, 0x0e, 0xab, 0xc7, + 0x3e, 0xa9, 0x55, 0x05, 0x47, 0x5e, 0xc7, 0x1a, 0x2c, 0x4a, 0xef, 0x42, 0xc0, 0xfa, 0x63, 0x64, + 0xe5, 0x79, 0x4f, 0xcc, 0x7f, 0x23, 0x66, 0xf2, 0x42, 0xbd, 0xfd, 0x09, 0xf2, 0x34, 0xde, 0x1b, + 0xf3, 0x5f, 0x8c, 0x80, 0xf7, 0x10, 0xae, 0x46, 0x72, 0x89, 0xd6, 0xd0, 0x3c, 0x7c, 0x6b, 0xb5, + 0x0b, 0x15, 0x4c, 0x29, 0xd6, 0x55, 0x4d, 0x31, 0xde, 0x0b, 0xa5, 0x15, 0xaf, 0xa8, 0x99, 0x3d, + 0x86, 0x6b, 0xd1, 0xe4, 0xc2, 0x63, 0xae, 0x62, 0x8e, 0x41, 0xcc, 0xc5, 0x70, 0x9e, 0x11, 0xa1, + 0x4a, 0x41, 0xc5, 0xa3, 0x56, 0x31, 0xe9, 0x08, 0xa8, 0x41, 0x6c, 0x11, 0xd4, 0x4f, 0xe1, 0xfa, + 0x74, 0xfa, 0xe1, 0x91, 0xd7, 0x30, 0x0b, 0x21, 0xf2, 0xd5, 0x68, 0x26, 0x32, 0x45, 0x9f, 0xd1, + 0x77, 0x0d, 0xd3, 0x12, 0x99, 0x3e, 0xd5, 0xfb, 0x13, 0x28, 0x4c, 0x25, 0x28, 0x1e, 0xfb, 0x21, + 0xe6, 0x29, 0xc4, 0x7e, 0x3f, 0x92, 0xab, 0x44, 0xc9, 0x33, 0xba, 0x7e, 0x84, 0x89, 0x8b, 0x44, + 0x9e, 0xea, 0x99, 0x96, 0x2c, 0x9c, 0xc2, 0x78, 0xdc, 0xc7, 0x98, 0xc9, 0x88, 0x25, 0x0b, 0x65, + 0x33, 0x72, 0xbf, 0x91, 0x9c, 0xc6, 0xe3, 0xd6, 0x31, 0xb5, 0x11, 0xfd, 0x86, 0xd3, 0x1b, 0x41, + 0xfe, 0x3e, 0x92, 0xf7, 0x66, 0xcf, 0xf8, 0x7f, 0x62, 0x98, 0x94, 0x08, 0xf6, 0xde, 0xac, 0x29, + 0xfb, 0xec, 0x19, 0x53, 0xfe, 0x5f, 0x64, 0x33, 0x89, 0x3d, 0x35, 0xe7, 0x1f, 0xc0, 0xd2, 0x8c, + 0x7c, 0xc5, 0xe3, 0xff, 0x1f, 0xf2, 0xf3, 0xc4, 0xbf, 0x36, 0x95, 0xba, 0x4c, 0x5b, 0x98, 0x31, + 0x82, 0xff, 0x47, 0x0b, 0x5a, 0xc8, 0xc2, 0xd4, 0x18, 0x36, 0x61, 0xce, 0xcb, 0xc7, 0xbb, 0x23, + 0x67, 0x32, 0x2c, 0x34, 0x74, 0xb5, 0x04, 0x95, 0xdb, 0xb3, 0x4e, 0xc8, 0x5e, 0x7e, 0xbe, 0x89, + 0x40, 0x23, 0xcc, 0xe3, 0x86, 0xb8, 0x69, 0x6e, 0xe8, 0x95, 0x1e, 0x3b, 0xdd, 0x10, 0x07, 0xfa, + 0x86, 0x24, 0x1e, 0x1a, 0xf2, 0x02, 0x1e, 0x37, 0xf4, 0x46, 0x57, 0x4e, 0x33, 0xe4, 0xc5, 0x3f, + 0x61, 0x28, 0xc4, 0x5b, 0x5a, 0x0b, 0x4e, 0xe6, 0xd4, 0xce, 0xbe, 0x13, 0x3d, 0xaa, 0x6f, 0xd2, + 0x01, 0x2b, 0x5c, 0xc9, 0x69, 0xd2, 0xf8, 0xa6, 0x69, 0x3f, 0x3c, 0x85, 0x16, 0x1a, 0xcd, 0x34, + 0xed, 0x47, 0x33, 0x68, 0xc5, 0x3f, 0x55, 0x20, 0xfe, 0xd9, 0xd6, 0xee, 0x0b, 0x96, 0x86, 0xf8, + 0xe7, 0xcd, 0xad, 0x17, 0xda, 0x15, 0x7c, 0x5a, 0x6f, 0x36, 0xb7, 0x35, 0x85, 0x65, 0x20, 0xb1, + 0xfe, 0xe5, 0xfe, 0xc6, 0x9e, 0xa6, 0xb2, 0x3c, 0x64, 0x1b, 0x5b, 0xbb, 0x9b, 0x1b, 0xc6, 0x2b, + 0x63, 0x6b, 0x77, 0x5f, 0x8b, 0x61, 0x5b, 0x63, 0xbb, 0xf9, 0x6c, 0x5f, 0x8b, 0xb3, 0x14, 0xc4, + 0xb0, 0x2e, 0xc1, 0x00, 0x92, 0x7b, 0xfb, 0xc6, 0xd6, 0xee, 0xa6, 0x96, 0x44, 0x2b, 0xfb, 0x5b, + 0x3b, 0x1b, 0x5a, 0x0a, 0x91, 0xfb, 0xaf, 0x5f, 0x6d, 0x6f, 0x68, 0x69, 0x7c, 0x7c, 0x66, 0x18, + 0xcf, 0xbe, 0xd4, 0x32, 0x48, 0xda, 0x79, 0xf6, 0x4a, 0x03, 0x6a, 0x7e, 0xb6, 0xbe, 0xbd, 0xa1, + 0x65, 0x59, 0x0e, 0xd2, 0x8d, 0xd7, 0xbb, 0xcf, 0xf7, 0xb7, 0x9a, 0xbb, 0x5a, 0xae, 0xf8, 0xbb, + 0x50, 0xe0, 0xcb, 0x1c, 0x5a, 0x45, 0x7e, 0x6b, 0xf0, 0x0c, 0x12, 0x7c, 0x73, 0x14, 0x92, 0xcb, + 0xdd, 0x19, 0x9b, 0x33, 0xcd, 0x2a, 0xf3, 0x6d, 0xe2, 0xcc, 0xa5, 0x1b, 0x90, 0xe0, 0x0b, 0xb5, + 0x08, 0x09, 0xbe, 0x40, 0x2a, 0x5d, 0x27, 0xf0, 0x42, 0xf1, 0xcf, 0x54, 0x80, 0x4d, 0x67, 0xef, + 0x6d, 0x6f, 0x48, 0x17, 0x38, 0x37, 0x00, 0xc6, 0x6f, 0x7b, 0xc3, 0x16, 0xbd, 0x85, 0xe2, 0xe2, + 0x21, 0x83, 0x35, 0xe4, 0x7f, 0xd9, 0x6d, 0xc8, 0x51, 0xb3, 0x78, 0x4d, 0xe8, 0xbe, 0x21, 0x65, + 0x64, 0xb1, 0x4e, 0x38, 0xca, 0x30, 0xa4, 0x56, 0xa5, 0x6b, 0x86, 0xa4, 0x04, 0xa9, 0x55, 0xd9, + 0x2d, 0xa0, 0x62, 0x6b, 0x4c, 0x11, 0x95, 0xae, 0x16, 0x32, 0x06, 0xf5, 0xcb, 0x63, 0x2c, 0xfb, + 0x2d, 0xa0, 0x3e, 0xf9, 0xd4, 0xf3, 0x33, 0xdf, 0x14, 0x6f, 0xc4, 0x65, 0x7c, 0xe0, 0x13, 0x0e, + 0x38, 0x4b, 0x4d, 0xc8, 0xf8, 0xf5, 0xd8, 0x1d, 0xd5, 0x8a, 0x49, 0x69, 0x34, 0x29, 0xa0, 0x2a, + 0x7f, 0x56, 0x1c, 0x20, 0x06, 0xb4, 0x40, 0x03, 0xe2, 0x24, 0x3e, 0xa2, 0xe2, 0x0d, 0x98, 0xdb, + 0x75, 0x6c, 0xfe, 0x32, 0xd3, 0x42, 0xe5, 0x40, 0x31, 0x0b, 0x0a, 0x1d, 0x82, 0x15, 0xb3, 0x78, + 0x13, 0x40, 0x6a, 0xd3, 0x40, 0x39, 0xe0, 0x6d, 0xe4, 0x14, 0x94, 0x83, 0xe2, 0x5d, 0x48, 0xee, + 0x98, 0xc7, 0xfb, 0x66, 0x97, 0xdd, 0x06, 0xe8, 0x9b, 0x63, 0xb7, 0xd5, 0xa1, 0xad, 0xf8, 0xf6, + 0xdb, 0x6f, 0xbf, 0x55, 0x28, 0xa3, 0xce, 0x60, 0x2d, 0xdf, 0x12, 0x17, 0xa0, 0xd9, 0x6f, 0xef, + 0x58, 0xe3, 0xb1, 0xd9, 0xb5, 0x58, 0x0d, 0x92, 0xb6, 0x35, 0xc6, 0x10, 0xac, 0xd0, 0x8d, 0xd3, + 0xcd, 0xd0, 0x42, 0x04, 0xc0, 0xf2, 0x2e, 0xa1, 0x0c, 0x81, 0x66, 0x1a, 0xc4, 0xec, 0xc9, 0x80, + 0xae, 0xd6, 0x12, 0x06, 0x3e, 0x2e, 0x7d, 0x00, 0x49, 0x8e, 0x61, 0x0c, 0xe2, 0xb6, 0x39, 0xb0, + 0x0a, 0xbc, 0x6b, 0x7a, 0x2e, 0xfe, 0x54, 0x01, 0xd8, 0xb5, 0xde, 0x5d, 0xac, 0xdb, 0x00, 0x78, + 0x46, 0xb7, 0x31, 0xde, 0xed, 0x93, 0xb3, 0xba, 0x45, 0xc1, 0x75, 0x1c, 0xa7, 0xdd, 0xe2, 0x7b, + 0xcd, 0x2f, 0x02, 0x33, 0x58, 0x43, 0x7b, 0x57, 0x7c, 0x03, 0xb9, 0x2d, 0xdb, 0xb6, 0x46, 0xde, + 0xb0, 0x18, 0xc4, 0x8f, 0x9c, 0xb1, 0x2b, 0x2e, 0x25, 0xe9, 0x99, 0x15, 0x20, 0x3e, 0x74, 0x46, + 0x2e, 0x9f, 0x6a, 0x3d, 0x5e, 0x5d, 0x59, 0x59, 0x31, 0xa8, 0x86, 0x7d, 0x00, 0x99, 0x43, 0xc7, + 0xb6, 0xad, 0x43, 0x9c, 0x47, 0x8c, 0x4e, 0x90, 0x41, 0x45, 0xf1, 0xf7, 0x15, 0xc8, 0x35, 0xdd, + 0xa3, 0xc0, 0xb8, 0x06, 0xb1, 0xb7, 0xd6, 0x09, 0x0d, 0x2f, 0x66, 0xe0, 0x23, 0xbe, 0x33, 0x3f, + 0x31, 0xfb, 0x13, 0x7e, 0x43, 0x99, 0x33, 0x78, 0x81, 0x5d, 0x85, 0xe4, 0x3b, 0xab, 0xd7, 0x3d, + 0x72, 0xc9, 0xa6, 0x6a, 0x88, 0x12, 0xbb, 0x0f, 0x89, 0x1e, 0x0e, 0xb6, 0x10, 0xa7, 0x25, 0xbb, + 0x1e, 0x5a, 0x32, 0x79, 0x1a, 0x06, 0xc7, 0xdd, 0x49, 0xa7, 0xdb, 0xda, 0xd7, 0x5f, 0x7f, 0xfd, + 0xb5, 0x5a, 0xec, 0xc1, 0xa2, 0xf7, 0x22, 0x87, 0xe6, 0xfb, 0x43, 0x28, 0xf4, 0x2d, 0xa7, 0xd5, + 0xe9, 0xd9, 0x66, 0xbf, 0x7f, 0xd2, 0x7a, 0xe7, 0xd8, 0x2d, 0xd3, 0x6e, 0x39, 0xe3, 0x43, 0x73, + 0x44, 0x6b, 0x70, 0x66, 0x2f, 0x8b, 0x7d, 0xcb, 0x69, 0x70, 0xe6, 0x17, 0x8e, 0xfd, 0xcc, 0x6e, + 0x22, 0xad, 0xf8, 0x1f, 0x71, 0xc8, 0xec, 0x9c, 0x78, 0x1d, 0x2c, 0x42, 0xe2, 0xd0, 0x99, 0xd8, + 0x7c, 0x45, 0x13, 0x06, 0x2f, 0xf8, 0x3b, 0xa5, 0x4a, 0x3b, 0xb5, 0x08, 0x89, 0xaf, 0x26, 0x8e, + 0x6b, 0xd1, 0xa4, 0x33, 0x06, 0x2f, 0xe0, 0x9a, 0x0d, 0x2d, 0xb7, 0x10, 0xa7, 0xfb, 0x0a, 0x7c, + 0x0c, 0x56, 0x21, 0x71, 0xb1, 0x55, 0x60, 0x0f, 0x20, 0xe9, 0xe0, 0x36, 0x8c, 0x0b, 0x49, 0xba, + 0x93, 0x0d, 0x33, 0xe4, 0x1d, 0x32, 0x04, 0x90, 0x6d, 0xc3, 0xc2, 0x3b, 0xab, 0x35, 0x98, 0x8c, + 0xdd, 0x56, 0xd7, 0x69, 0xb5, 0x2d, 0x6b, 0x68, 0x8d, 0x0a, 0x73, 0xd4, 0x5f, 0xd8, 0x51, 0xcc, + 0x5a, 0x54, 0x63, 0xfe, 0x9d, 0xb5, 0x33, 0x19, 0xbb, 0x9b, 0xce, 0x0b, 0x22, 0xb2, 0x1a, 0x64, + 0x46, 0x16, 0xba, 0x07, 0x1c, 0x75, 0x6e, 0xc6, 0x18, 0x42, 0xec, 0xf4, 0xc8, 0x1a, 0x52, 0x05, + 0x7b, 0x04, 0xe9, 0x83, 0xde, 0x5b, 0x6b, 0x7c, 0x64, 0xb5, 0x0b, 0x29, 0x5d, 0x29, 0xcd, 0x57, + 0x3e, 0x08, 0xd1, 0xfc, 0x55, 0x2e, 0x3f, 0x77, 0xfa, 0xce, 0xc8, 0xf0, 0xd1, 0xec, 0x29, 0x64, + 0xc6, 0xce, 0xc0, 0xe2, 0xa2, 0x4f, 0x53, 0xe0, 0xd5, 0x4f, 0xa1, 0xee, 0x39, 0x03, 0xcb, 0xf3, + 0x6f, 0x1e, 0x85, 0x2d, 0xf3, 0x11, 0x1f, 0xe0, 0xd9, 0xa2, 0x00, 0x74, 0xff, 0x83, 0xc3, 0xa2, + 0xb3, 0x06, 0x5b, 0xc2, 0x61, 0x75, 0x3b, 0x98, 0xc2, 0x15, 0xb2, 0x74, 0xb4, 0xf7, 0xcb, 0x4b, + 0xf7, 0x20, 0xe3, 0x1b, 0x0c, 0x1c, 0x23, 0x77, 0x46, 0x19, 0x72, 0x15, 0xdc, 0x31, 0x72, 0x4f, + 0xf4, 0x11, 0x24, 0x68, 0xe4, 0x18, 0xc5, 0x8c, 0x0d, 0x0c, 0x9a, 0x19, 0x48, 0x6c, 0x1a, 0x1b, + 0x1b, 0xbb, 0x9a, 0x42, 0xf1, 0x73, 0xfb, 0xf5, 0x86, 0xa6, 0x4a, 0x32, 0xfe, 0x99, 0x0a, 0xb1, + 0x8d, 0x63, 0xd2, 0x4f, 0xdb, 0x74, 0x4d, 0xef, 0x4d, 0xc7, 0x67, 0xf6, 0x04, 0x32, 0x03, 0xd3, + 0xeb, 0x4b, 0xa5, 0x55, 0x0e, 0x3b, 0x95, 0x8d, 0x63, 0xb7, 0xbc, 0x63, 0xf2, 0xae, 0x37, 0x6c, + 0x77, 0x74, 0x62, 0xa4, 0x07, 0xa2, 0xb8, 0xf4, 0x04, 0xe6, 0x42, 0x4d, 0xf2, 0xbb, 0x9a, 0x98, + 0xf1, 0xae, 0x26, 0xc4, 0xbb, 0x5a, 0x57, 0x1f, 0x29, 0x95, 0xef, 0x43, 0x7c, 0xe0, 0x8c, 0x2c, + 0x76, 0x75, 0xf6, 0x12, 0x17, 0xba, 0x24, 0x1c, 0x2d, 0x3a, 0x18, 0x83, 0x58, 0x95, 0x3b, 0x10, + 0x77, 0xad, 0x63, 0xf7, 0x54, 0xf6, 0x11, 0x9f, 0x23, 0x62, 0x2a, 0x65, 0x48, 0xda, 0x93, 0xc1, + 0x81, 0x35, 0x3a, 0x15, 0xdd, 0xa3, 0xc1, 0x09, 0x54, 0xf1, 0x73, 0xd0, 0x9e, 0x3b, 0x83, 0x61, + 0xdf, 0x3a, 0xde, 0x38, 0x76, 0x2d, 0x7b, 0xdc, 0x73, 0x6c, 0x9c, 0x47, 0xa7, 0x37, 0x22, 0x1f, + 0x47, 0xf3, 0xa0, 0x02, 0xfa, 0x9c, 0xb1, 0x75, 0xe8, 0xd8, 0x6d, 0x31, 0x3d, 0x51, 0x42, 0xb4, + 0x7b, 0xd4, 0x1b, 0xa1, 0x7b, 0xc3, 0x58, 0xc4, 0x0b, 0xc5, 0x4d, 0xc8, 0x8b, 0xa3, 0xd9, 0x58, + 0x74, 0x5c, 0xbc, 0x03, 0x39, 0xaf, 0x8a, 0x7e, 0x12, 0x4a, 0x43, 0xfc, 0xcd, 0x86, 0xd1, 0xd4, + 0xae, 0xe0, 0xe6, 0x36, 0x77, 0x37, 0x34, 0x05, 0x1f, 0xf6, 0xbf, 0x68, 0x86, 0x36, 0x34, 0x05, + 0x89, 0x8d, 0xc1, 0xd0, 0x3d, 0x29, 0xfe, 0x1e, 0x64, 0x85, 0xa5, 0xed, 0xde, 0xd8, 0x65, 0x75, + 0x48, 0x0d, 0xc4, 0x8c, 0x14, 0x4a, 0x40, 0x23, 0xf2, 0x0d, 0xa0, 0xde, 0xb3, 0xe1, 0x11, 0x96, + 0x56, 0x21, 0x25, 0xb9, 0x73, 0xe1, 0x67, 0x54, 0xd9, 0xcf, 0x70, 0x8f, 0x14, 0x93, 0x3c, 0x52, + 0x71, 0x07, 0x52, 0x3c, 0x14, 0x8f, 0x29, 0xc3, 0xe0, 0xc7, 0x76, 0xae, 0x25, 0x2e, 0xb2, 0x2c, + 0xaf, 0xe3, 0x79, 0xd3, 0x2d, 0xc8, 0xd2, 0xbb, 0xe1, 0xab, 0x0d, 0xbd, 0x37, 0x50, 0x15, 0x57, + 0xf6, 0x5f, 0x27, 0x20, 0xed, 0x2d, 0x07, 0x5b, 0x86, 0x24, 0x3f, 0xbb, 0x92, 0x29, 0xef, 0x2e, + 0x27, 0x41, 0xa7, 0x55, 0xb6, 0x0c, 0x29, 0x71, 0x3e, 0x15, 0x01, 0x46, 0x5d, 0xad, 0x18, 0x49, + 0x7e, 0x1e, 0xf5, 0x1b, 0x6b, 0x55, 0xf2, 0x8a, 0xfc, 0x96, 0x26, 0xc9, 0x4f, 0x9c, 0x4c, 0x87, + 0x8c, 0x7f, 0xc6, 0xa4, 0x90, 0x20, 0xae, 0x64, 0xd2, 0xde, 0xa1, 0x52, 0x42, 0xd4, 0xaa, 0xe4, + 0x2e, 0xc5, 0xfd, 0x4b, 0xba, 0x11, 0xa4, 0x4a, 0x69, 0xef, 0xa4, 0x48, 0xbf, 0x38, 0x79, 0x97, + 0x2d, 0x29, 0x71, 0x36, 0x0c, 0x00, 0xb5, 0x2a, 0xf9, 0x20, 0xef, 0x66, 0x25, 0x25, 0xce, 0x7f, + 0xec, 0x16, 0x0e, 0x91, 0xce, 0x73, 0xe4, 0x68, 0x82, 0x6b, 0x94, 0x24, 0x3f, 0xe5, 0xb1, 0xdb, + 0x68, 0x81, 0x1f, 0xda, 0xc8, 0x05, 0x04, 0x77, 0x26, 0x29, 0x71, 0x96, 0x63, 0x77, 0x11, 0xc2, + 0x97, 0xbf, 0x00, 0xa7, 0x5c, 0x90, 0xa4, 0xc4, 0x05, 0x09, 0xd3, 0xb1, 0x43, 0xf2, 0x44, 0xe4, + 0x7d, 0xa4, 0xcb, 0x90, 0x24, 0xbf, 0x0c, 0x61, 0x37, 0xc9, 0x1c, 0x9f, 0x54, 0x2e, 0xb8, 0xf8, + 0x48, 0x89, 0xc3, 0x5f, 0xd0, 0x4e, 0xe9, 0xa3, 0x7f, 0xc9, 0x91, 0x12, 0xc7, 0x3b, 0xf6, 0x18, + 0xf7, 0x0b, 0x45, 0x5c, 0x98, 0x27, 0xaf, 0xbb, 0x1c, 0xd2, 0x9e, 0xb7, 0xad, 0xdc, 0xe9, 0xd6, + 0xb9, 0xbf, 0x32, 0x12, 0x0d, 0x52, 0xfd, 0x12, 0x52, 0x5f, 0xf5, 0xec, 0x4e, 0x21, 0x4f, 0x8b, + 0x11, 0xeb, 0xd9, 0x1d, 0x23, 0xd1, 0xc0, 0x1a, 0x2e, 0x83, 0x5d, 0x6c, 0xd3, 0xa8, 0x2d, 0xfe, + 0x09, 0x6f, 0xc4, 0x2a, 0x56, 0x80, 0x44, 0xa3, 0xb5, 0x6b, 0xda, 0x85, 0x05, 0xce, 0xb3, 0x4d, + 0xdb, 0x88, 0x37, 0x76, 0x4d, 0x9b, 0xdd, 0x81, 0xd8, 0x78, 0x72, 0x50, 0x60, 0x33, 0x7e, 0x0f, + 0xdc, 0x9b, 0x1c, 0x78, 0xa3, 0x31, 0x10, 0xc4, 0x96, 0x21, 0x3d, 0x76, 0x47, 0xad, 0xdf, 0xb1, + 0x46, 0x4e, 0xe1, 0x3d, 0x5a, 0xc8, 0x2b, 0x46, 0x6a, 0xec, 0x8e, 0xde, 0x58, 0x23, 0xe7, 0x82, + 0xde, 0xb6, 0x78, 0x13, 0xb2, 0x92, 0x5d, 0x96, 0x07, 0xc5, 0xe6, 0x29, 0x4b, 0x5d, 0x79, 0x68, + 0x28, 0x76, 0xf1, 0x0b, 0xc8, 0x79, 0x07, 0x2b, 0x9a, 0xf2, 0x1a, 0xbe, 0x4f, 0x7d, 0x67, 0x44, + 0x2f, 0xea, 0x7c, 0xe5, 0x56, 0x24, 0x3e, 0x06, 0x48, 0x11, 0xa5, 0x38, 0xba, 0xa8, 0x45, 0x46, + 0xa3, 0x14, 0xff, 0x53, 0x81, 0xdc, 0x8e, 0x33, 0x0a, 0x7e, 0xb9, 0x58, 0x84, 0xc4, 0x81, 0xe3, + 0xf4, 0xc7, 0x64, 0x39, 0x6d, 0xf0, 0x02, 0xfb, 0x08, 0x72, 0xf4, 0xe0, 0x1d, 0x8f, 0x55, 0xff, + 0xfe, 0x27, 0x4b, 0xf5, 0xe2, 0x44, 0xcc, 0x20, 0xde, 0xb3, 0xdd, 0xb1, 0xf0, 0x5b, 0xf4, 0xcc, + 0x3e, 0x84, 0x2c, 0xfe, 0xf5, 0x98, 0x71, 0x3f, 0x85, 0x06, 0xac, 0x16, 0xc4, 0xef, 0xc1, 0x1c, + 0xc9, 0xc0, 0x87, 0xa5, 0xfc, 0xbb, 0x9e, 0x1c, 0x6f, 0x10, 0xc0, 0x02, 0xa4, 0xb8, 0x4f, 0x18, + 0xd3, 0x8f, 0xbd, 0x19, 0xc3, 0x2b, 0xa2, 0x33, 0xa5, 0xe3, 0x09, 0xcf, 0x38, 0x52, 0x86, 0x28, + 0x15, 0x5f, 0x40, 0x9a, 0x22, 0x63, 0xb3, 0xdf, 0x66, 0x1f, 0x81, 0xd2, 0x2d, 0x58, 0x14, 0x9a, + 0xaf, 0x85, 0xcf, 0x1e, 0x02, 0x51, 0xde, 0x34, 0x94, 0xee, 0xd2, 0x02, 0x28, 0x9b, 0x78, 0x18, + 0x38, 0x16, 0x7e, 0x59, 0x39, 0x2e, 0x1a, 0xc2, 0xca, 0xae, 0xf5, 0xee, 0x1c, 0x2b, 0xbb, 0xd6, + 0x3b, 0x6e, 0xe5, 0xd6, 0x94, 0x15, 0x2c, 0x9d, 0x88, 0x9f, 0xc0, 0x95, 0x93, 0xe2, 0x2a, 0xcc, + 0xd1, 0xdb, 0xda, 0xb3, 0xbb, 0xaf, 0x9c, 0x9e, 0x4d, 0xe7, 0x8f, 0x0e, 0xe5, 0x6c, 0x8a, 0xa1, + 0x74, 0x70, 0x27, 0xac, 0x63, 0xf3, 0x90, 0xe7, 0xc0, 0x69, 0x83, 0x17, 0x8a, 0xff, 0x15, 0x87, + 0x79, 0xe1, 0x69, 0xbf, 0xe8, 0xb9, 0x47, 0x3b, 0xe6, 0x90, 0x35, 0x21, 0x87, 0x4e, 0xb6, 0x35, + 0x30, 0x87, 0x43, 0x7c, 0x9b, 0x15, 0x8a, 0xc3, 0xf7, 0x66, 0x39, 0x6f, 0x41, 0x29, 0xef, 0x9a, + 0x03, 0x6b, 0x87, 0xc3, 0x79, 0x54, 0xce, 0xda, 0x41, 0x0d, 0xdb, 0x86, 0xec, 0x60, 0xdc, 0xf5, + 0xed, 0xf1, 0xb8, 0x7e, 0xf7, 0x2c, 0x7b, 0x3b, 0xe3, 0x6e, 0xc8, 0x1c, 0x0c, 0xfc, 0x0a, 0x1c, + 0x1e, 0x3a, 0x69, 0xdf, 0x5c, 0xec, 0xfc, 0xe1, 0xa1, 0x4b, 0x09, 0x0f, 0xef, 0x20, 0xa8, 0x61, + 0x9b, 0x00, 0xf8, 0xc2, 0xb9, 0x0e, 0x9e, 0xed, 0x48, 0x50, 0xd9, 0xca, 0xc7, 0x67, 0x99, 0xdb, + 0x73, 0x47, 0xfb, 0xce, 0x9e, 0x3b, 0x12, 0x09, 0xc8, 0x58, 0x14, 0x97, 0x9e, 0x82, 0x16, 0x5d, + 0x88, 0xf3, 0x72, 0x90, 0x8c, 0x94, 0x83, 0x2c, 0x7d, 0x09, 0xf9, 0xc8, 0xc4, 0x65, 0x3a, 0xe3, + 0xf4, 0x15, 0x99, 0x9e, 0xad, 0x2c, 0x85, 0x3f, 0xd4, 0x90, 0xf7, 0x5f, 0x36, 0xfd, 0x14, 0xb4, + 0xe8, 0x22, 0xc8, 0xb6, 0xd3, 0x67, 0x1c, 0x65, 0x88, 0xff, 0x04, 0xe6, 0x42, 0xb3, 0x96, 0xc9, + 0x99, 0x73, 0xe6, 0x55, 0xfc, 0x83, 0x04, 0x24, 0x9a, 0xb6, 0xe5, 0x74, 0xd8, 0xb5, 0x70, 0x14, + 0x7d, 0x79, 0xc5, 0x8b, 0xa0, 0xd7, 0x23, 0x11, 0xf4, 0xe5, 0x15, 0x3f, 0x7e, 0x5e, 0x8f, 0xc4, + 0x4f, 0xaf, 0xa9, 0x56, 0x65, 0x37, 0xa6, 0xa2, 0xe7, 0xcb, 0x2b, 0x52, 0xe8, 0xbc, 0x31, 0x15, + 0x3a, 0x83, 0xe6, 0x5a, 0x15, 0x1d, 0x6d, 0x38, 0x6e, 0xbe, 0xbc, 0x12, 0xc4, 0xcc, 0xe5, 0x68, + 0xcc, 0xf4, 0x1b, 0x6b, 0x55, 0x3e, 0x24, 0x29, 0x5e, 0xd2, 0x90, 0x78, 0xa4, 0x5c, 0x8e, 0x46, + 0x4a, 0xe2, 0x89, 0x18, 0xb9, 0x1c, 0x8d, 0x91, 0xd4, 0x28, 0x62, 0xe2, 0xf5, 0x48, 0x4c, 0x24, + 0xa3, 0x3c, 0x18, 0x2e, 0x47, 0x83, 0x21, 0xe7, 0x49, 0x23, 0x95, 0x23, 0xa1, 0xdf, 0x58, 0xab, + 0xb2, 0xb5, 0x48, 0x18, 0x3c, 0xf3, 0xf0, 0x41, 0xdb, 0x41, 0xf1, 0xe0, 0x21, 0xae, 0x9c, 0x97, + 0x8e, 0xe6, 0xcf, 0xfe, 0x8a, 0x85, 0xd6, 0xd4, 0x4b, 0xd6, 0xd6, 0x20, 0xd5, 0x11, 0xe7, 0x74, + 0x8d, 0x3c, 0x5a, 0x58, 0x9f, 0xa4, 0x82, 0x72, 0xa3, 0x45, 0x9e, 0x0d, 0x27, 0xd8, 0xe1, 0xa7, + 0x8c, 0x12, 0xcc, 0x35, 0x5a, 0xdb, 0xe6, 0xa8, 0x6b, 0x8d, 0xdd, 0xd6, 0xbe, 0xd9, 0xf5, 0x2f, + 0x3d, 0x50, 0x08, 0xd9, 0x86, 0x68, 0xd9, 0x37, 0xbb, 0xec, 0xaa, 0xa7, 0xb2, 0x36, 0xb5, 0x2a, + 0x42, 0x67, 0x4b, 0xd7, 0x70, 0xf5, 0xb8, 0x31, 0xf2, 0x91, 0x0b, 0xc2, 0x47, 0xae, 0xa7, 0x20, + 0x31, 0xb1, 0x7b, 0x8e, 0xbd, 0x9e, 0x81, 0x94, 0xeb, 0x8c, 0x06, 0xa6, 0xeb, 0x14, 0xff, 0x5b, + 0x01, 0x78, 0xee, 0x0c, 0x06, 0x13, 0xbb, 0xf7, 0xd5, 0xc4, 0x62, 0x37, 0x21, 0x3b, 0x30, 0xdf, + 0x5a, 0xad, 0x81, 0xd5, 0x3a, 0x1c, 0x79, 0x2f, 0x44, 0x06, 0xab, 0x76, 0xac, 0xe7, 0xa3, 0x13, + 0x56, 0xf0, 0x32, 0x76, 0x12, 0x11, 0x69, 0x53, 0x64, 0xf0, 0x8b, 0x22, 0x37, 0x4d, 0x8a, 0xcd, + 0xf4, 0xb2, 0x53, 0x7e, 0xb2, 0x49, 0x89, 0x6d, 0xe4, 0x67, 0x9b, 0x6b, 0x90, 0x74, 0xad, 0xc1, + 0xb0, 0x75, 0x48, 0x9a, 0x41, 0x5d, 0x24, 0xb0, 0xfc, 0x9c, 0xad, 0x40, 0xec, 0xd0, 0xe9, 0x93, + 0x5a, 0xce, 0xdf, 0x20, 0x84, 0xb2, 0x12, 0xc4, 0x06, 0x63, 0x2e, 0xa1, 0x6c, 0x65, 0x31, 0x9c, + 0x4e, 0xf0, 0xf0, 0x85, 0xc8, 0xc1, 0xb8, 0xeb, 0xcf, 0xbe, 0xf8, 0x6b, 0x15, 0xd2, 0xb8, 0x65, + 0xaf, 0xf7, 0x1b, 0x8f, 0xe8, 0xa0, 0x70, 0x68, 0xf6, 0xe9, 0x7e, 0x00, 0xdf, 0x55, 0x51, 0xc2, + 0xfa, 0x9f, 0x58, 0x87, 0xae, 0x33, 0x22, 0x1f, 0x9d, 0x31, 0x44, 0x09, 0x17, 0x9d, 0x27, 0xc9, + 0x31, 0x31, 0x4f, 0x5e, 0xa4, 0x0c, 0xdf, 0x1c, 0xb6, 0xd0, 0x11, 0x70, 0xb7, 0x19, 0x3e, 0x58, + 0x7b, 0xfd, 0xe1, 0x89, 0xed, 0x33, 0xeb, 0x84, 0xbb, 0xcb, 0xe4, 0x80, 0x0a, 0xec, 0x07, 0xfc, + 0xa8, 0xc7, 0x37, 0x93, 0x7f, 0x68, 0xf5, 0xe1, 0xa9, 0xec, 0xcf, 0x11, 0x15, 0x9c, 0xf7, 0xa8, + 0xb8, 0xf4, 0x18, 0xb2, 0x92, 0xe1, 0xf3, 0x3c, 0x52, 0x2c, 0xe2, 0xce, 0x42, 0x56, 0xcf, 0xbb, + 0xd6, 0x91, 0xdd, 0x19, 0xae, 0xa9, 0x83, 0x3a, 0xbe, 0x93, 0x87, 0x58, 0xa3, 0xd9, 0xc4, 0xb4, + 0xab, 0xd1, 0x6c, 0x3e, 0xd0, 0x94, 0x7a, 0x05, 0xd2, 0xdd, 0x91, 0x65, 0xa1, 0x07, 0x3e, 0xf5, + 0x70, 0xf7, 0x63, 0x5a, 0x59, 0x1f, 0x57, 0xdf, 0x83, 0xd4, 0x21, 0x3f, 0xde, 0xb1, 0xd3, 0x2f, + 0x35, 0x0a, 0x7f, 0xcb, 0x6f, 0xd8, 0x6e, 0x84, 0x10, 0xd1, 0x63, 0xa1, 0xe1, 0x59, 0xaa, 0x7f, + 0x0e, 0x99, 0x51, 0xeb, 0x02, 0x66, 0xbf, 0xe1, 0xb1, 0xfd, 0x1c, 0xb3, 0xe9, 0x91, 0xa8, 0xaa, + 0xbf, 0x84, 0x05, 0xdb, 0xf1, 0x7e, 0xf1, 0x6b, 0xb5, 0xb9, 0x57, 0xfb, 0x60, 0x66, 0x6a, 0xed, + 0x75, 0x61, 0xf1, 0x0f, 0x07, 0x6c, 0x47, 0x34, 0x70, 0x57, 0x58, 0x6f, 0x80, 0x26, 0x59, 0xa2, + 0x8b, 0x87, 0x73, 0x0c, 0x75, 0xf8, 0xc7, 0x0a, 0xbe, 0x21, 0xf2, 0xb7, 0x11, 0x3b, 0xdc, 0x23, + 0x9e, 0x6d, 0xa7, 0xcb, 0x3f, 0xfe, 0xf0, 0xed, 0x50, 0x94, 0x99, 0xb6, 0x53, 0xab, 0x9e, 0x63, + 0xe7, 0x88, 0x7f, 0x1a, 0x22, 0xdb, 0xa9, 0x55, 0x23, 0x2b, 0x34, 0xb9, 0xc8, 0x80, 0x7a, 0xfc, + 0xe3, 0x0e, 0xdf, 0x10, 0x8f, 0x40, 0x33, 0x2c, 0x9d, 0x3b, 0xa4, 0x1f, 0xf3, 0x4f, 0x3f, 0x42, + 0x96, 0xa6, 0xc6, 0x34, 0xbe, 0xc8, 0x98, 0xde, 0xf2, 0x4f, 0x2d, 0x7c, 0x4b, 0x7b, 0xb3, 0xc6, + 0x34, 0xbe, 0xc8, 0x98, 0xfa, 0xfc, 0x3b, 0x8c, 0x90, 0xa5, 0x5a, 0xb5, 0xfe, 0xdb, 0xc0, 0xe4, + 0xfd, 0x17, 0x11, 0xfb, 0x6c, 0x53, 0x03, 0xfe, 0x81, 0x4d, 0xa0, 0x00, 0xce, 0x9a, 0x65, 0xeb, + 0xdc, 0x61, 0xd9, 0xfc, 0xf3, 0x9b, 0xb0, 0xad, 0x5a, 0xb5, 0xbe, 0x0d, 0xef, 0xc9, 0x33, 0xbc, + 0xd8, 0xc0, 0x1c, 0xfe, 0xf1, 0x48, 0x30, 0x47, 0x41, 0x9b, 0x69, 0xed, 0xdc, 0xa1, 0x0d, 0xf9, + 0x97, 0x25, 0x11, 0x6b, 0xb5, 0x6a, 0xfd, 0x05, 0xe4, 0x25, 0x6b, 0x78, 0x50, 0x3a, 0xc7, 0xd2, + 0x57, 0xfc, 0x83, 0x28, 0xdf, 0x12, 0xa6, 0x5a, 0xd1, 0x3d, 0xe4, 0xc9, 0xc7, 0xd9, 0x76, 0x46, + 0xfc, 0x83, 0x9e, 0x60, 0x44, 0x44, 0x8a, 0xbc, 0x33, 0x74, 0x73, 0x72, 0x8e, 0xa1, 0x31, 0xff, + 0xda, 0x27, 0x18, 0x10, 0x72, 0xea, 0x4e, 0x68, 0x5e, 0x16, 0x26, 0x20, 0x67, 0x9b, 0x71, 0x29, + 0x54, 0x7e, 0x7c, 0x16, 0xa6, 0x2c, 0x5f, 0x64, 0x49, 0x4b, 0x80, 0xc5, 0xfa, 0x36, 0xcc, 0x5f, + 0xca, 0x87, 0x7d, 0xa3, 0xf0, 0x3b, 0x8f, 0xd5, 0xf2, 0x83, 0xea, 0x83, 0x35, 0x63, 0xae, 0x1d, + 0x72, 0x65, 0x2f, 0x61, 0xee, 0x32, 0x7e, 0xec, 0xe7, 0x0a, 0xbf, 0x39, 0x40, 0x63, 0x46, 0xae, + 0x1d, 0x76, 0x66, 0x73, 0x97, 0xf1, 0x64, 0xbf, 0x50, 0xf8, 0x65, 0x53, 0xb5, 0xe2, 0xdb, 0xf1, + 0x9c, 0xd9, 0xdc, 0x65, 0x3c, 0xd9, 0x2f, 0xf9, 0xd5, 0x80, 0x5a, 0x5d, 0x95, 0xed, 0x90, 0xe3, + 0x98, 0xbf, 0x94, 0x27, 0xfb, 0x95, 0x42, 0xd7, 0x4f, 0x6a, 0xb5, 0xea, 0xaf, 0x91, 0xef, 0xcc, + 0xe6, 0x2f, 0xe5, 0xc9, 0xfe, 0x4e, 0xa1, 0x7b, 0x2a, 0xb5, 0xba, 0x16, 0xb2, 0x14, 0x1e, 0xd3, + 0x85, 0x3c, 0xd9, 0xdf, 0x2b, 0x74, 0x7b, 0xa4, 0x56, 0x6b, 0xbe, 0xa5, 0xbd, 0xa9, 0x31, 0x5d, + 0xc8, 0x93, 0xfd, 0x03, 0x9d, 0xc2, 0xea, 0x6a, 0xf5, 0x61, 0xc8, 0x12, 0x39, 0xb3, 0xfc, 0xe5, + 0x3c, 0xd9, 0xaf, 0x15, 0xba, 0xea, 0x53, 0xab, 0x8f, 0x0c, 0x6f, 0x0c, 0x81, 0x33, 0xcb, 0x5f, + 0xce, 0x93, 0xfd, 0xa3, 0x42, 0x97, 0x82, 0x6a, 0xf5, 0x71, 0xd8, 0x16, 0x39, 0x33, 0xed, 0x92, + 0x9e, 0xec, 0x9f, 0x14, 0xfa, 0xf4, 0x47, 0x5d, 0x5b, 0x31, 0xbc, 0x61, 0x48, 0xce, 0x4c, 0xbb, + 0xa4, 0x27, 0xfb, 0x67, 0x85, 0x3e, 0x08, 0x52, 0xd7, 0x1e, 0x44, 0xac, 0xd5, 0xaa, 0xf5, 0x06, + 0xe4, 0x2e, 0xe1, 0xc9, 0xfe, 0x45, 0xbe, 0x75, 0xcd, 0xb6, 0x25, 0x77, 0xf6, 0x23, 0x69, 0x17, + 0x2f, 0xe2, 0xcb, 0xfe, 0x95, 0x12, 0xc4, 0xfa, 0xfb, 0x2f, 0xf9, 0xe5, 0x24, 0xe7, 0xdc, 0x6b, + 0x5b, 0x9d, 0x4f, 0x3b, 0x8e, 0x13, 0x6c, 0x2c, 0xf7, 0x70, 0xaf, 0x82, 0x17, 0xe9, 0x22, 0xee, + 0xed, 0xdf, 0x14, 0xba, 0xcc, 0xcc, 0x09, 0xdb, 0x44, 0xf1, 0x5f, 0x29, 0xee, 0xeb, 0x86, 0xc1, + 0xb4, 0x2f, 0xe0, 0xe8, 0xfe, 0x5d, 0xb9, 0xa4, 0xa7, 0xab, 0xc7, 0x9a, 0xbb, 0x1b, 0xfe, 0x02, + 0x61, 0xcd, 0xfa, 0xa7, 0x6f, 0x9e, 0x74, 0x7b, 0xee, 0xd1, 0xe4, 0xa0, 0x7c, 0xe8, 0x0c, 0xee, + 0x77, 0x9d, 0xbe, 0x69, 0x77, 0xef, 0x93, 0xbd, 0x83, 0x49, 0xe7, 0x7e, 0xcf, 0x76, 0xad, 0x91, + 0x6d, 0xf6, 0xe9, 0x1f, 0x44, 0xa8, 0x76, 0x7c, 0x5f, 0xfe, 0xc7, 0x91, 0xdf, 0x04, 0x00, 0x00, + 0xff, 0xff, 0x4a, 0x65, 0x66, 0xff, 0x47, 0x32, 0x00, 0x00, +} diff --git a/pkg/golang-protobuf/internal/testprotos/proto2_proto/test.proto b/pkg/golang-protobuf/internal/testprotos/proto2_proto/test.proto new file mode 100644 index 000000000..3b9fe04e2 --- /dev/null +++ b/pkg/golang-protobuf/internal/testprotos/proto2_proto/test.proto @@ -0,0 +1,485 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// A feature-rich test file for the protocol compiler and libraries. + +syntax = "proto2"; + +option go_package = "github.com/golang/protobuf/internal/testprotos/proto2_proto"; + +package proto2_test; + +enum FOO { FOO1 = 1; }; + +message GoEnum { + required FOO foo = 1; +} + +message GoTestField { + required string Label = 1; + required string Type = 2; +} + +message GoTest { + // An enum, for completeness. + enum KIND { + VOID = 0; + + // Basic types + BOOL = 1; + BYTES = 2; + FINGERPRINT = 3; + FLOAT = 4; + INT = 5; + STRING = 6; + TIME = 7; + + // Groupings + TUPLE = 8; + ARRAY = 9; + MAP = 10; + + // Table types + TABLE = 11; + + // Functions + FUNCTION = 12; // last tag + }; + + // Some typical parameters + required KIND Kind = 1; + optional string Table = 2; + optional int32 Param = 3; + + // Required, repeated and optional foreign fields. + required GoTestField RequiredField = 4; + repeated GoTestField RepeatedField = 5; + optional GoTestField OptionalField = 6; + + // Required fields of all basic types + required bool F_Bool_required = 10; + required int32 F_Int32_required = 11; + required int64 F_Int64_required = 12; + required fixed32 F_Fixed32_required = 13; + required fixed64 F_Fixed64_required = 14; + required uint32 F_Uint32_required = 15; + required uint64 F_Uint64_required = 16; + required float F_Float_required = 17; + required double F_Double_required = 18; + required string F_String_required = 19; + required bytes F_Bytes_required = 101; + required sint32 F_Sint32_required = 102; + required sint64 F_Sint64_required = 103; + required sfixed32 F_Sfixed32_required = 104; + required sfixed64 F_Sfixed64_required = 105; + + // Repeated fields of all basic types + repeated bool F_Bool_repeated = 20; + repeated int32 F_Int32_repeated = 21; + repeated int64 F_Int64_repeated = 22; + repeated fixed32 F_Fixed32_repeated = 23; + repeated fixed64 F_Fixed64_repeated = 24; + repeated uint32 F_Uint32_repeated = 25; + repeated uint64 F_Uint64_repeated = 26; + repeated float F_Float_repeated = 27; + repeated double F_Double_repeated = 28; + repeated string F_String_repeated = 29; + repeated bytes F_Bytes_repeated = 201; + repeated sint32 F_Sint32_repeated = 202; + repeated sint64 F_Sint64_repeated = 203; + repeated sfixed32 F_Sfixed32_repeated = 204; + repeated sfixed64 F_Sfixed64_repeated = 205; + + // Optional fields of all basic types + optional bool F_Bool_optional = 30; + optional int32 F_Int32_optional = 31; + optional int64 F_Int64_optional = 32; + optional fixed32 F_Fixed32_optional = 33; + optional fixed64 F_Fixed64_optional = 34; + optional uint32 F_Uint32_optional = 35; + optional uint64 F_Uint64_optional = 36; + optional float F_Float_optional = 37; + optional double F_Double_optional = 38; + optional string F_String_optional = 39; + optional bytes F_Bytes_optional = 301; + optional sint32 F_Sint32_optional = 302; + optional sint64 F_Sint64_optional = 303; + optional sfixed32 F_Sfixed32_optional = 304; + optional sfixed64 F_Sfixed64_optional = 305; + + // Default-valued fields of all basic types + optional bool F_Bool_defaulted = 40 [default=true]; + optional int32 F_Int32_defaulted = 41 [default=32]; + optional int64 F_Int64_defaulted = 42 [default=64]; + optional fixed32 F_Fixed32_defaulted = 43 [default=320]; + optional fixed64 F_Fixed64_defaulted = 44 [default=640]; + optional uint32 F_Uint32_defaulted = 45 [default=3200]; + optional uint64 F_Uint64_defaulted = 46 [default=6400]; + optional float F_Float_defaulted = 47 [default=314159.]; + optional double F_Double_defaulted = 48 [default=271828.]; + optional string F_String_defaulted = 49 [default="hello, \"world!\"\n"]; + optional bytes F_Bytes_defaulted = 401 [default="Bignose"]; + optional sint32 F_Sint32_defaulted = 402 [default = -32]; + optional sint64 F_Sint64_defaulted = 403 [default = -64]; + optional sfixed32 F_Sfixed32_defaulted = 404 [default = -32]; + optional sfixed64 F_Sfixed64_defaulted = 405 [default = -64]; + + // Packed repeated fields (no string or bytes). + repeated bool F_Bool_repeated_packed = 50 [packed=true]; + repeated int32 F_Int32_repeated_packed = 51 [packed=true]; + repeated int64 F_Int64_repeated_packed = 52 [packed=true]; + repeated fixed32 F_Fixed32_repeated_packed = 53 [packed=true]; + repeated fixed64 F_Fixed64_repeated_packed = 54 [packed=true]; + repeated uint32 F_Uint32_repeated_packed = 55 [packed=true]; + repeated uint64 F_Uint64_repeated_packed = 56 [packed=true]; + repeated float F_Float_repeated_packed = 57 [packed=true]; + repeated double F_Double_repeated_packed = 58 [packed=true]; + repeated sint32 F_Sint32_repeated_packed = 502 [packed=true]; + repeated sint64 F_Sint64_repeated_packed = 503 [packed=true]; + repeated sfixed32 F_Sfixed32_repeated_packed = 504 [packed=true]; + repeated sfixed64 F_Sfixed64_repeated_packed = 505 [packed=true]; + + // Required, repeated, and optional groups. + required group RequiredGroup = 70 { + required string RequiredField = 71; + }; + + repeated group RepeatedGroup = 80 { + required string RequiredField = 81; + }; + + optional group OptionalGroup = 90 { + required string RequiredField = 91; + }; +} + +// For testing a group containing a required field. +message GoTestRequiredGroupField { + required group Group = 1 { + required int32 Field = 2; + }; +} + +// For testing skipping of unrecognized fields. +// Numbers are all big, larger than tag numbers in GoTestField, +// the message used in the corresponding test. +message GoSkipTest { + required int32 skip_int32 = 11; + required fixed32 skip_fixed32 = 12; + required fixed64 skip_fixed64 = 13; + required string skip_string = 14; + required group SkipGroup = 15 { + required int32 group_int32 = 16; + required string group_string = 17; + } +} + +// For testing packed/non-packed decoder switching. +// A serialized instance of one should be deserializable as the other. +message NonPackedTest { + repeated int32 a = 1; +} + +message PackedTest { + repeated int32 b = 1 [packed=true]; +} + +message MaxTag { + // Maximum possible tag number. + optional string last_field = 536870911; +} + +message OldMessage { + message Nested { + optional string name = 1; + } + optional Nested nested = 1; + + optional int32 num = 2; +} + +// NewMessage is wire compatible with OldMessage; +// imagine it as a future version. +message NewMessage { + message Nested { + optional string name = 1; + optional string food_group = 2; + } + optional Nested nested = 1; + + // This is an int32 in OldMessage. + optional int64 num = 2; +} + +// Smaller tests for ASCII formatting. + +message InnerMessage { + required string host = 1; + optional int32 port = 2 [default=4000]; + optional bool connected = 3; +} + +message OtherMessage { + optional int64 key = 1; + optional bytes value = 2; + optional float weight = 3; + optional InnerMessage inner = 4; + + extensions 100 to max; +} + +message RequiredInnerMessage { + required InnerMessage leo_finally_won_an_oscar = 1; +} + +message MyMessage { + required int32 count = 1; + optional string name = 2; + optional string quote = 3; + repeated string pet = 4; + optional InnerMessage inner = 5; + repeated OtherMessage others = 6; + optional RequiredInnerMessage we_must_go_deeper = 13; + repeated InnerMessage rep_inner = 12; + + enum Color { + RED = 0; + GREEN = 1; + BLUE = 2; + }; + optional Color bikeshed = 7; + + optional group SomeGroup = 8 { + optional int32 group_field = 9; + } + + // This field becomes [][]byte in the generated code. + repeated bytes rep_bytes = 10; + + optional double bigfloat = 11; + + extensions 100 to max; +} + +message Ext { + extend MyMessage { + optional Ext more = 103; + optional string text = 104; + optional int32 number = 105; + } + + optional string data = 1; + map map_field = 2; +} + +extend MyMessage { + repeated string greeting = 106; + // leave field 200 unregistered for testing +} + +message ComplexExtension { + optional int32 first = 1; + optional int32 second = 2; + repeated int32 third = 3; +} + +extend OtherMessage { + optional ComplexExtension complex = 200; + repeated ComplexExtension r_complex = 201; +} + +message DefaultsMessage { + enum DefaultsEnum { + ZERO = 0; + ONE = 1; + TWO = 2; + }; + extensions 100 to max; +} + +extend DefaultsMessage { + optional double no_default_double = 101; + optional float no_default_float = 102; + optional int32 no_default_int32 = 103; + optional int64 no_default_int64 = 104; + optional uint32 no_default_uint32 = 105; + optional uint64 no_default_uint64 = 106; + optional sint32 no_default_sint32 = 107; + optional sint64 no_default_sint64 = 108; + optional fixed32 no_default_fixed32 = 109; + optional fixed64 no_default_fixed64 = 110; + optional sfixed32 no_default_sfixed32 = 111; + optional sfixed64 no_default_sfixed64 = 112; + optional bool no_default_bool = 113; + optional string no_default_string = 114; + optional bytes no_default_bytes = 115; + optional DefaultsMessage.DefaultsEnum no_default_enum = 116; + + optional double default_double = 201 [default = 3.1415]; + optional float default_float = 202 [default = 3.14]; + optional int32 default_int32 = 203 [default = 42]; + optional int64 default_int64 = 204 [default = 43]; + optional uint32 default_uint32 = 205 [default = 44]; + optional uint64 default_uint64 = 206 [default = 45]; + optional sint32 default_sint32 = 207 [default = 46]; + optional sint64 default_sint64 = 208 [default = 47]; + optional fixed32 default_fixed32 = 209 [default = 48]; + optional fixed64 default_fixed64 = 210 [default = 49]; + optional sfixed32 default_sfixed32 = 211 [default = 50]; + optional sfixed64 default_sfixed64 = 212 [default = 51]; + optional bool default_bool = 213 [default = true]; + optional string default_string = 214 [default = "Hello, string,def=foo"]; + optional bytes default_bytes = 215 [default = "Hello, bytes"]; + optional DefaultsMessage.DefaultsEnum default_enum = 216 [default = ONE]; +} + +message Empty { +} + +message MessageList { + repeated group Message = 1 { + required string name = 2; + required int32 count = 3; + } +} + +message Strings { + optional string string_field = 1; + optional bytes bytes_field = 2; +} + +message Defaults { + enum Color { + RED = 0; + GREEN = 1; + BLUE = 2; + } + + // Default-valued fields of all basic types. + // Same as GoTest, but copied here to make testing easier. + optional bool F_Bool = 1 [default=true]; + optional int32 F_Int32 = 2 [default=32]; + optional int64 F_Int64 = 3 [default=64]; + optional fixed32 F_Fixed32 = 4 [default=320]; + optional fixed64 F_Fixed64 = 5 [default=640]; + optional uint32 F_Uint32 = 6 [default=3200]; + optional uint64 F_Uint64 = 7 [default=6400]; + optional float F_Float = 8 [default=314159.]; + optional double F_Double = 9 [default=271828.]; + optional string F_String = 10 [default="hello, \"world!\"\n"]; + optional bytes F_Bytes = 11 [default="Bignose"]; + optional sint32 F_Sint32 = 12 [default=-32]; + optional sint64 F_Sint64 = 13 [default=-64]; + optional Color F_Enum = 14 [default=GREEN]; + + // More fields with crazy defaults. + optional float F_Pinf = 15 [default=inf]; + optional float F_Ninf = 16 [default=-inf]; + optional float F_Nan = 17 [default=nan]; + + // Sub-message. + optional SubDefaults sub = 18; + + // Redundant but explicit defaults. + optional string str_zero = 19 [default=""]; +} + +message SubDefaults { + optional int64 n = 1 [default=7]; +} + +message RepeatedEnum { + enum Color { + RED = 1; + } + repeated Color color = 1; +} + +message MoreRepeated { + repeated bool bools = 1; + repeated bool bools_packed = 2 [packed=true]; + repeated int32 ints = 3; + repeated int32 ints_packed = 4 [packed=true]; + repeated int64 int64s_packed = 7 [packed=true]; + repeated string strings = 5; + repeated fixed32 fixeds = 6; +} + +// GroupOld and GroupNew have the same wire format. +// GroupNew has a new field inside a group. + +message GroupOld { + optional group G = 101 { + optional int32 x = 2; + } +} + +message GroupNew { + optional group G = 101 { + optional int32 x = 2; + optional int32 y = 3; + } +} + +message FloatingPoint { + required double f = 1; + optional bool exact = 2; +} + +message MessageWithMap { + map name_mapping = 1; + map msg_mapping = 2; + map byte_mapping = 3; + map str_to_str = 4; +} + +message Oneof { + oneof union { + bool F_Bool = 1; + int32 F_Int32 = 2; + int64 F_Int64 = 3; + fixed32 F_Fixed32 = 4; + fixed64 F_Fixed64 = 5; + uint32 F_Uint32 = 6; + uint64 F_Uint64 = 7; + float F_Float = 8; + double F_Double = 9; + string F_String = 10; + bytes F_Bytes = 11; + sint32 F_Sint32 = 12; + sint64 F_Sint64 = 13; + MyMessage.Color F_Enum = 14; + GoTestField F_Message = 15; + group F_Group = 16 { + optional int32 x = 17; + } + int32 F_Largest_Tag = 536870911; + } + + oneof tormato { + int32 value = 100; + } +} + +message Communique { + optional bool make_me_cry = 1; + + // This is a oneof, called "union". + oneof union { + int32 number = 5; + string name = 6; + bytes data = 7; + double temp_c = 8; + MyMessage.Color col = 9; + Strings msg = 10; + } +} + +message TestUTF8 { + optional string scalar = 1; + repeated string vector = 2; + oneof oneof { string field = 3; } + map map_key = 4; + map map_value = 5; +} diff --git a/pkg/golang-protobuf/internal/testprotos/proto3_proto/test.pb.go b/pkg/golang-protobuf/internal/testprotos/proto3_proto/test.pb.go new file mode 100644 index 000000000..0aa2d9d07 --- /dev/null +++ b/pkg/golang-protobuf/internal/testprotos/proto3_proto/test.pb.go @@ -0,0 +1,579 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: proto3_proto/test.proto + +package proto3_proto + +import ( + fmt "fmt" + proto2_proto "github.com/golang/protobuf/internal/testprotos/proto2_proto" + proto "github.com/golang/protobuf/proto" + anypb "google.golang.org/protobuf/types/known/anypb" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type Message_Humour int32 + +const ( + Message_UNKNOWN Message_Humour = 0 + Message_PUNS Message_Humour = 1 + Message_SLAPSTICK Message_Humour = 2 + Message_BILL_BAILEY Message_Humour = 3 +) + +var Message_Humour_name = map[int32]string{ + 0: "UNKNOWN", + 1: "PUNS", + 2: "SLAPSTICK", + 3: "BILL_BAILEY", +} + +var Message_Humour_value = map[string]int32{ + "UNKNOWN": 0, + "PUNS": 1, + "SLAPSTICK": 2, + "BILL_BAILEY": 3, +} + +func (x Message_Humour) String() string { + return proto.EnumName(Message_Humour_name, int32(x)) +} + +func (Message_Humour) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_ff83f0b8d2b92afa, []int{0, 0} +} + +type Message struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Hilarity Message_Humour `protobuf:"varint,2,opt,name=hilarity,proto3,enum=proto3_test.Message_Humour" json:"hilarity,omitempty"` + HeightInCm uint32 `protobuf:"varint,3,opt,name=height_in_cm,json=heightInCm,proto3" json:"height_in_cm,omitempty"` + Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` + ResultCount int64 `protobuf:"varint,7,opt,name=result_count,json=resultCount,proto3" json:"result_count,omitempty"` + TrueScotsman bool `protobuf:"varint,8,opt,name=true_scotsman,json=trueScotsman,proto3" json:"true_scotsman,omitempty"` + Score float32 `protobuf:"fixed32,9,opt,name=score,proto3" json:"score,omitempty"` + Key []uint64 `protobuf:"varint,5,rep,packed,name=key,proto3" json:"key,omitempty"` + ShortKey []int32 `protobuf:"varint,19,rep,packed,name=short_key,json=shortKey,proto3" json:"short_key,omitempty"` + Nested *Nested `protobuf:"bytes,6,opt,name=nested,proto3" json:"nested,omitempty"` + RFunny []Message_Humour `protobuf:"varint,16,rep,packed,name=r_funny,json=rFunny,proto3,enum=proto3_test.Message_Humour" json:"r_funny,omitempty"` + Terrain map[string]*Nested `protobuf:"bytes,10,rep,name=terrain,proto3" json:"terrain,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Proto2Field *proto2_proto.SubDefaults `protobuf:"bytes,11,opt,name=proto2_field,json=proto2Field,proto3" json:"proto2_field,omitempty"` + Proto2Value map[string]*proto2_proto.SubDefaults `protobuf:"bytes,13,rep,name=proto2_value,json=proto2Value,proto3" json:"proto2_value,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Anything *anypb.Any `protobuf:"bytes,14,opt,name=anything,proto3" json:"anything,omitempty"` + ManyThings []*anypb.Any `protobuf:"bytes,15,rep,name=many_things,json=manyThings,proto3" json:"many_things,omitempty"` + Submessage *Message `protobuf:"bytes,17,opt,name=submessage,proto3" json:"submessage,omitempty"` + Children []*Message `protobuf:"bytes,18,rep,name=children,proto3" json:"children,omitempty"` + StringMap map[string]string `protobuf:"bytes,20,rep,name=string_map,json=stringMap,proto3" json:"string_map,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Message) Reset() { *m = Message{} } +func (m *Message) String() string { return proto.CompactTextString(m) } +func (*Message) ProtoMessage() {} +func (*Message) Descriptor() ([]byte, []int) { + return fileDescriptor_ff83f0b8d2b92afa, []int{0} +} + +func (m *Message) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Message.Unmarshal(m, b) +} +func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Message.Marshal(b, m, deterministic) +} +func (m *Message) XXX_Merge(src proto.Message) { + xxx_messageInfo_Message.Merge(m, src) +} +func (m *Message) XXX_Size() int { + return xxx_messageInfo_Message.Size(m) +} +func (m *Message) XXX_DiscardUnknown() { + xxx_messageInfo_Message.DiscardUnknown(m) +} + +var xxx_messageInfo_Message proto.InternalMessageInfo + +func (m *Message) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Message) GetHilarity() Message_Humour { + if m != nil { + return m.Hilarity + } + return Message_UNKNOWN +} + +func (m *Message) GetHeightInCm() uint32 { + if m != nil { + return m.HeightInCm + } + return 0 +} + +func (m *Message) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (m *Message) GetResultCount() int64 { + if m != nil { + return m.ResultCount + } + return 0 +} + +func (m *Message) GetTrueScotsman() bool { + if m != nil { + return m.TrueScotsman + } + return false +} + +func (m *Message) GetScore() float32 { + if m != nil { + return m.Score + } + return 0 +} + +func (m *Message) GetKey() []uint64 { + if m != nil { + return m.Key + } + return nil +} + +func (m *Message) GetShortKey() []int32 { + if m != nil { + return m.ShortKey + } + return nil +} + +func (m *Message) GetNested() *Nested { + if m != nil { + return m.Nested + } + return nil +} + +func (m *Message) GetRFunny() []Message_Humour { + if m != nil { + return m.RFunny + } + return nil +} + +func (m *Message) GetTerrain() map[string]*Nested { + if m != nil { + return m.Terrain + } + return nil +} + +func (m *Message) GetProto2Field() *proto2_proto.SubDefaults { + if m != nil { + return m.Proto2Field + } + return nil +} + +func (m *Message) GetProto2Value() map[string]*proto2_proto.SubDefaults { + if m != nil { + return m.Proto2Value + } + return nil +} + +func (m *Message) GetAnything() *anypb.Any { + if m != nil { + return m.Anything + } + return nil +} + +func (m *Message) GetManyThings() []*anypb.Any { + if m != nil { + return m.ManyThings + } + return nil +} + +func (m *Message) GetSubmessage() *Message { + if m != nil { + return m.Submessage + } + return nil +} + +func (m *Message) GetChildren() []*Message { + if m != nil { + return m.Children + } + return nil +} + +func (m *Message) GetStringMap() map[string]string { + if m != nil { + return m.StringMap + } + return nil +} + +type Nested struct { + Bunny string `protobuf:"bytes,1,opt,name=bunny,proto3" json:"bunny,omitempty"` + Cute bool `protobuf:"varint,2,opt,name=cute,proto3" json:"cute,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Nested) Reset() { *m = Nested{} } +func (m *Nested) String() string { return proto.CompactTextString(m) } +func (*Nested) ProtoMessage() {} +func (*Nested) Descriptor() ([]byte, []int) { + return fileDescriptor_ff83f0b8d2b92afa, []int{1} +} + +func (m *Nested) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Nested.Unmarshal(m, b) +} +func (m *Nested) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Nested.Marshal(b, m, deterministic) +} +func (m *Nested) XXX_Merge(src proto.Message) { + xxx_messageInfo_Nested.Merge(m, src) +} +func (m *Nested) XXX_Size() int { + return xxx_messageInfo_Nested.Size(m) +} +func (m *Nested) XXX_DiscardUnknown() { + xxx_messageInfo_Nested.DiscardUnknown(m) +} + +var xxx_messageInfo_Nested proto.InternalMessageInfo + +func (m *Nested) GetBunny() string { + if m != nil { + return m.Bunny + } + return "" +} + +func (m *Nested) GetCute() bool { + if m != nil { + return m.Cute + } + return false +} + +type MessageWithMap struct { + ByteMapping map[bool][]byte `protobuf:"bytes,1,rep,name=byte_mapping,json=byteMapping,proto3" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MessageWithMap) Reset() { *m = MessageWithMap{} } +func (m *MessageWithMap) String() string { return proto.CompactTextString(m) } +func (*MessageWithMap) ProtoMessage() {} +func (*MessageWithMap) Descriptor() ([]byte, []int) { + return fileDescriptor_ff83f0b8d2b92afa, []int{2} +} + +func (m *MessageWithMap) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_MessageWithMap.Unmarshal(m, b) +} +func (m *MessageWithMap) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_MessageWithMap.Marshal(b, m, deterministic) +} +func (m *MessageWithMap) XXX_Merge(src proto.Message) { + xxx_messageInfo_MessageWithMap.Merge(m, src) +} +func (m *MessageWithMap) XXX_Size() int { + return xxx_messageInfo_MessageWithMap.Size(m) +} +func (m *MessageWithMap) XXX_DiscardUnknown() { + xxx_messageInfo_MessageWithMap.DiscardUnknown(m) +} + +var xxx_messageInfo_MessageWithMap proto.InternalMessageInfo + +func (m *MessageWithMap) GetByteMapping() map[bool][]byte { + if m != nil { + return m.ByteMapping + } + return nil +} + +type IntMap struct { + Rtt map[int32]int32 `protobuf:"bytes,1,rep,name=rtt,proto3" json:"rtt,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IntMap) Reset() { *m = IntMap{} } +func (m *IntMap) String() string { return proto.CompactTextString(m) } +func (*IntMap) ProtoMessage() {} +func (*IntMap) Descriptor() ([]byte, []int) { + return fileDescriptor_ff83f0b8d2b92afa, []int{3} +} + +func (m *IntMap) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IntMap.Unmarshal(m, b) +} +func (m *IntMap) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IntMap.Marshal(b, m, deterministic) +} +func (m *IntMap) XXX_Merge(src proto.Message) { + xxx_messageInfo_IntMap.Merge(m, src) +} +func (m *IntMap) XXX_Size() int { + return xxx_messageInfo_IntMap.Size(m) +} +func (m *IntMap) XXX_DiscardUnknown() { + xxx_messageInfo_IntMap.DiscardUnknown(m) +} + +var xxx_messageInfo_IntMap proto.InternalMessageInfo + +func (m *IntMap) GetRtt() map[int32]int32 { + if m != nil { + return m.Rtt + } + return nil +} + +type IntMaps struct { + Maps []*IntMap `protobuf:"bytes,1,rep,name=maps,proto3" json:"maps,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IntMaps) Reset() { *m = IntMaps{} } +func (m *IntMaps) String() string { return proto.CompactTextString(m) } +func (*IntMaps) ProtoMessage() {} +func (*IntMaps) Descriptor() ([]byte, []int) { + return fileDescriptor_ff83f0b8d2b92afa, []int{4} +} + +func (m *IntMaps) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_IntMaps.Unmarshal(m, b) +} +func (m *IntMaps) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_IntMaps.Marshal(b, m, deterministic) +} +func (m *IntMaps) XXX_Merge(src proto.Message) { + xxx_messageInfo_IntMaps.Merge(m, src) +} +func (m *IntMaps) XXX_Size() int { + return xxx_messageInfo_IntMaps.Size(m) +} +func (m *IntMaps) XXX_DiscardUnknown() { + xxx_messageInfo_IntMaps.DiscardUnknown(m) +} + +var xxx_messageInfo_IntMaps proto.InternalMessageInfo + +func (m *IntMaps) GetMaps() []*IntMap { + if m != nil { + return m.Maps + } + return nil +} + +type TestUTF8 struct { + Scalar string `protobuf:"bytes,1,opt,name=scalar,proto3" json:"scalar,omitempty"` + Vector []string `protobuf:"bytes,2,rep,name=vector,proto3" json:"vector,omitempty"` + // Types that are valid to be assigned to Oneof: + // *TestUTF8_Field + Oneof isTestUTF8_Oneof `protobuf_oneof:"oneof"` + MapKey map[string]int64 `protobuf:"bytes,4,rep,name=map_key,json=mapKey,proto3" json:"map_key,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"` + MapValue map[int64]string `protobuf:"bytes,5,rep,name=map_value,json=mapValue,proto3" json:"map_value,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *TestUTF8) Reset() { *m = TestUTF8{} } +func (m *TestUTF8) String() string { return proto.CompactTextString(m) } +func (*TestUTF8) ProtoMessage() {} +func (*TestUTF8) Descriptor() ([]byte, []int) { + return fileDescriptor_ff83f0b8d2b92afa, []int{5} +} + +func (m *TestUTF8) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_TestUTF8.Unmarshal(m, b) +} +func (m *TestUTF8) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_TestUTF8.Marshal(b, m, deterministic) +} +func (m *TestUTF8) XXX_Merge(src proto.Message) { + xxx_messageInfo_TestUTF8.Merge(m, src) +} +func (m *TestUTF8) XXX_Size() int { + return xxx_messageInfo_TestUTF8.Size(m) +} +func (m *TestUTF8) XXX_DiscardUnknown() { + xxx_messageInfo_TestUTF8.DiscardUnknown(m) +} + +var xxx_messageInfo_TestUTF8 proto.InternalMessageInfo + +func (m *TestUTF8) GetScalar() string { + if m != nil { + return m.Scalar + } + return "" +} + +func (m *TestUTF8) GetVector() []string { + if m != nil { + return m.Vector + } + return nil +} + +type isTestUTF8_Oneof interface { + isTestUTF8_Oneof() +} + +type TestUTF8_Field struct { + Field string `protobuf:"bytes,3,opt,name=field,proto3,oneof"` +} + +func (*TestUTF8_Field) isTestUTF8_Oneof() {} + +func (m *TestUTF8) GetOneof() isTestUTF8_Oneof { + if m != nil { + return m.Oneof + } + return nil +} + +func (m *TestUTF8) GetField() string { + if x, ok := m.GetOneof().(*TestUTF8_Field); ok { + return x.Field + } + return "" +} + +func (m *TestUTF8) GetMapKey() map[string]int64 { + if m != nil { + return m.MapKey + } + return nil +} + +func (m *TestUTF8) GetMapValue() map[int64]string { + if m != nil { + return m.MapValue + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*TestUTF8) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*TestUTF8_Field)(nil), + } +} + +func init() { + proto.RegisterEnum("proto3_test.Message_Humour", Message_Humour_name, Message_Humour_value) + proto.RegisterType((*Message)(nil), "proto3_test.Message") + proto.RegisterMapType((map[string]*proto2_proto.SubDefaults)(nil), "proto3_test.Message.Proto2ValueEntry") + proto.RegisterMapType((map[string]string)(nil), "proto3_test.Message.StringMapEntry") + proto.RegisterMapType((map[string]*Nested)(nil), "proto3_test.Message.TerrainEntry") + proto.RegisterType((*Nested)(nil), "proto3_test.Nested") + proto.RegisterType((*MessageWithMap)(nil), "proto3_test.MessageWithMap") + proto.RegisterMapType((map[bool][]byte)(nil), "proto3_test.MessageWithMap.ByteMappingEntry") + proto.RegisterType((*IntMap)(nil), "proto3_test.IntMap") + proto.RegisterMapType((map[int32]int32)(nil), "proto3_test.IntMap.RttEntry") + proto.RegisterType((*IntMaps)(nil), "proto3_test.IntMaps") + proto.RegisterType((*TestUTF8)(nil), "proto3_test.TestUTF8") + proto.RegisterMapType((map[string]int64)(nil), "proto3_test.TestUTF8.MapKeyEntry") + proto.RegisterMapType((map[int64]string)(nil), "proto3_test.TestUTF8.MapValueEntry") +} + +func init() { proto.RegisterFile("proto3_proto/test.proto", fileDescriptor_ff83f0b8d2b92afa) } + +var fileDescriptor_ff83f0b8d2b92afa = []byte{ + // 926 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x55, 0x6d, 0x6f, 0xdb, 0x36, + 0x10, 0xae, 0x2c, 0xbf, 0xc8, 0x67, 0x3b, 0xf5, 0x98, 0xa0, 0xe3, 0xdc, 0x7d, 0x50, 0x5d, 0x0c, + 0xd3, 0xb0, 0x41, 0x1e, 0xbc, 0x6e, 0xeb, 0x9a, 0xbd, 0xc5, 0x59, 0x83, 0x18, 0x89, 0x9d, 0x40, + 0x76, 0xd6, 0x6d, 0x5f, 0x04, 0xda, 0xa1, 0x6d, 0x61, 0x12, 0x65, 0x88, 0x54, 0x01, 0xfd, 0x9c, + 0xfd, 0xa4, 0xfd, 0xa2, 0x0d, 0x24, 0xe5, 0x54, 0x6e, 0x15, 0xe4, 0x93, 0x79, 0x8f, 0x9f, 0xbb, + 0xe7, 0x78, 0x77, 0x3c, 0xc1, 0xc7, 0xdb, 0x24, 0x16, 0xf1, 0x37, 0xbe, 0xfa, 0x19, 0x08, 0xca, + 0x85, 0xab, 0x8e, 0xa8, 0x95, 0xff, 0x21, 0xa1, 0xde, 0x27, 0xeb, 0x38, 0x5e, 0x87, 0x74, 0xa0, + 0xb0, 0x45, 0xba, 0x1a, 0x10, 0x96, 0x69, 0x5e, 0x4f, 0x07, 0x18, 0x7e, 0x10, 0xa0, 0xff, 0x9f, + 0x05, 0x8d, 0x09, 0xe5, 0x9c, 0xac, 0x29, 0x42, 0x50, 0x65, 0x24, 0xa2, 0xd8, 0xb0, 0x0d, 0xa7, + 0xe9, 0xa9, 0x33, 0xfa, 0x1e, 0xac, 0x4d, 0x10, 0x92, 0x24, 0x10, 0x19, 0xae, 0xd8, 0x86, 0x73, + 0x30, 0x7c, 0xea, 0x16, 0x34, 0xdd, 0xdc, 0xd7, 0x3d, 0x4f, 0xa3, 0x38, 0x4d, 0xbc, 0x3b, 0x32, + 0xb2, 0xa1, 0xbd, 0xa1, 0xc1, 0x7a, 0x23, 0xfc, 0x80, 0xf9, 0xcb, 0x08, 0x9b, 0xb6, 0xe1, 0x74, + 0x3c, 0xd0, 0xd8, 0x98, 0x9d, 0x46, 0x52, 0xee, 0x96, 0x08, 0x82, 0xab, 0xb6, 0xe1, 0xb4, 0x3d, + 0x75, 0x46, 0xcf, 0xa0, 0x9d, 0x50, 0x9e, 0x86, 0xc2, 0x5f, 0xc6, 0x29, 0x13, 0xb8, 0x61, 0x1b, + 0x8e, 0xe9, 0xb5, 0x34, 0x76, 0x2a, 0x21, 0xf4, 0x1c, 0x3a, 0x22, 0x49, 0xa9, 0xcf, 0x97, 0xb1, + 0xe0, 0x11, 0x61, 0xd8, 0xb2, 0x0d, 0xc7, 0xf2, 0xda, 0x12, 0x9c, 0xe5, 0x18, 0x3a, 0x82, 0x1a, + 0x5f, 0xc6, 0x09, 0xc5, 0x4d, 0xdb, 0x70, 0x2a, 0x9e, 0x36, 0x50, 0x17, 0xcc, 0xbf, 0x69, 0x86, + 0x6b, 0xb6, 0xe9, 0x54, 0x3d, 0x79, 0x44, 0x4f, 0xa1, 0xc9, 0x37, 0x71, 0x22, 0x7c, 0x89, 0x1f, + 0xda, 0xa6, 0x53, 0xf3, 0x2c, 0x05, 0x5c, 0xd0, 0x0c, 0x7d, 0x09, 0x75, 0x46, 0xb9, 0xa0, 0xb7, + 0xb8, 0x6e, 0x1b, 0x4e, 0x6b, 0x78, 0xb8, 0x77, 0xf3, 0xa9, 0xfa, 0xcb, 0xcb, 0x29, 0xe8, 0x05, + 0x34, 0x12, 0x7f, 0x95, 0x32, 0x96, 0xe1, 0xae, 0x6d, 0x3e, 0x54, 0xa7, 0x7a, 0x72, 0x26, 0xa9, + 0xe8, 0x18, 0x1a, 0x82, 0x26, 0x09, 0x09, 0x18, 0x06, 0xdb, 0x74, 0x5a, 0xc3, 0x67, 0xa5, 0x5e, + 0x73, 0xcd, 0x79, 0xcd, 0x44, 0x92, 0x79, 0x3b, 0x0f, 0x74, 0x0c, 0xed, 0xbc, 0xad, 0xab, 0x80, + 0x86, 0xb7, 0xb8, 0xa5, 0xb2, 0xc4, 0x6e, 0x0e, 0xaa, 0x08, 0xb3, 0x74, 0xf1, 0x1b, 0x5d, 0x91, + 0x34, 0x14, 0xdc, 0xd3, 0xc3, 0x32, 0x3c, 0x93, 0x64, 0x74, 0x7e, 0xe7, 0xfc, 0x96, 0x84, 0x29, + 0xc5, 0x1d, 0x25, 0xff, 0x59, 0xa9, 0xfc, 0xb5, 0x22, 0xfe, 0x2e, 0x79, 0x3a, 0x85, 0x3c, 0x92, + 0x42, 0xd0, 0xd7, 0x60, 0x11, 0x96, 0x89, 0x4d, 0xc0, 0xd6, 0xf8, 0x40, 0xa5, 0x70, 0xe4, 0xea, + 0x49, 0x74, 0x77, 0x93, 0xe8, 0x9e, 0xb0, 0xcc, 0xbb, 0x63, 0xa1, 0x6f, 0xa1, 0x15, 0x11, 0x96, + 0xf9, 0xca, 0xe2, 0xf8, 0xb1, 0x92, 0x2e, 0x77, 0x02, 0x49, 0x9c, 0x2b, 0x1e, 0x7a, 0x01, 0xc0, + 0xd3, 0x45, 0xa4, 0x93, 0xc2, 0x1f, 0xe5, 0x52, 0x25, 0x09, 0x7b, 0x05, 0x9e, 0x4c, 0x6f, 0xb9, + 0x09, 0xc2, 0xdb, 0x84, 0x32, 0x8c, 0x72, 0xa5, 0x32, 0x9f, 0x3b, 0x16, 0x1a, 0x01, 0x70, 0x91, + 0x04, 0x6c, 0xed, 0x47, 0x64, 0x8b, 0x8f, 0x94, 0xcf, 0xf3, 0xd2, 0xc2, 0xcc, 0x14, 0x6d, 0x42, + 0xb6, 0xba, 0x2c, 0x4d, 0xbe, 0xb3, 0x7b, 0x57, 0xd0, 0x2e, 0x36, 0x6d, 0x37, 0x7a, 0xfa, 0x69, + 0xa9, 0xd1, 0xfb, 0x02, 0x6a, 0xba, 0xf2, 0x95, 0xfb, 0x87, 0x4b, 0x33, 0x5e, 0x55, 0x5e, 0x1a, + 0xbd, 0x3f, 0xa0, 0xfb, 0x7e, 0x1b, 0x4a, 0x82, 0xba, 0xfb, 0x41, 0xef, 0x9f, 0x85, 0x42, 0xe4, + 0x1f, 0xe1, 0x60, 0xff, 0x1e, 0x25, 0x71, 0x8f, 0x8a, 0x71, 0x9b, 0x05, 0xef, 0xfe, 0x2f, 0x50, + 0xd7, 0x33, 0x8d, 0x5a, 0xd0, 0xb8, 0x99, 0x5e, 0x4c, 0xaf, 0xde, 0x4c, 0xbb, 0x8f, 0x90, 0x05, + 0xd5, 0xeb, 0x9b, 0xe9, 0xac, 0x6b, 0xa0, 0x0e, 0x34, 0x67, 0x97, 0x27, 0xd7, 0xb3, 0xf9, 0xf8, + 0xf4, 0xa2, 0x5b, 0x41, 0x8f, 0xa1, 0x35, 0x1a, 0x5f, 0x5e, 0xfa, 0xa3, 0x93, 0xf1, 0xe5, 0xeb, + 0x3f, 0xbb, 0x66, 0x7f, 0x08, 0x75, 0x7d, 0x5b, 0x29, 0xb2, 0x50, 0x0f, 0x48, 0x0b, 0x6b, 0x43, + 0xae, 0x89, 0x65, 0x2a, 0xb4, 0xb2, 0xe5, 0xa9, 0x73, 0xff, 0x1f, 0x03, 0x0e, 0xf2, 0x1e, 0xbc, + 0x09, 0xc4, 0x66, 0x42, 0xb6, 0xe8, 0x0a, 0xda, 0x8b, 0x4c, 0x50, 0xd9, 0xb2, 0xad, 0x9c, 0x44, + 0x43, 0xb5, 0xed, 0xab, 0xb2, 0xb6, 0xe5, 0x2e, 0xee, 0x28, 0x13, 0x74, 0xa2, 0xe9, 0xf9, 0x58, + 0x2f, 0xde, 0x21, 0xbd, 0x9f, 0xa1, 0xfb, 0x3e, 0xa1, 0x58, 0x18, 0xab, 0xa4, 0x30, 0xed, 0x62, + 0x61, 0xb6, 0x50, 0x1f, 0x33, 0x21, 0x53, 0x73, 0xc1, 0x4c, 0x84, 0xc8, 0x33, 0xfa, 0x74, 0x2f, + 0x23, 0xcd, 0x70, 0x3d, 0x21, 0x74, 0x06, 0x92, 0xd8, 0xfb, 0x0e, 0xac, 0x1d, 0x50, 0x54, 0xac, + 0x95, 0x28, 0xd6, 0x8a, 0x8a, 0x43, 0x68, 0xe8, 0x78, 0x1c, 0x7d, 0x0e, 0xd5, 0x88, 0x6c, 0x79, + 0xae, 0x79, 0x58, 0xa2, 0xe9, 0x29, 0x42, 0xff, 0xdf, 0x0a, 0x58, 0x73, 0xca, 0xc5, 0xcd, 0xfc, + 0xec, 0x25, 0x7a, 0x02, 0x75, 0xbe, 0x24, 0x21, 0x49, 0xf2, 0x0e, 0xe4, 0x96, 0xc4, 0xdf, 0xd2, + 0xa5, 0x88, 0x13, 0x5c, 0xb1, 0x4d, 0x89, 0x6b, 0x0b, 0x3d, 0x81, 0x9a, 0xde, 0x3c, 0x72, 0xb9, + 0x37, 0xcf, 0x1f, 0x79, 0xda, 0x44, 0xaf, 0xa0, 0x11, 0x91, 0xad, 0xda, 0xa9, 0xd5, 0x92, 0xad, + 0xb6, 0xd3, 0x73, 0x27, 0x64, 0x7b, 0x41, 0x33, 0x7d, 0xf3, 0x7a, 0xa4, 0x0c, 0xf4, 0x2b, 0x34, + 0xa5, 0xaf, 0xbe, 0x62, 0xad, 0xe4, 0xed, 0x15, 0xbd, 0x0b, 0x2b, 0xc9, 0x8a, 0x72, 0xb3, 0xf7, + 0x03, 0xb4, 0x0a, 0x81, 0x1f, 0x1a, 0x66, 0xb3, 0xf8, 0x14, 0x8e, 0xa1, 0xb3, 0x17, 0xb5, 0xe8, + 0x6c, 0x3e, 0xf0, 0x12, 0x46, 0x0d, 0xa8, 0xc5, 0x8c, 0xc6, 0xab, 0xd1, 0x4f, 0x7f, 0x1d, 0xaf, + 0x03, 0xb1, 0x49, 0x17, 0xee, 0x32, 0x8e, 0x06, 0xeb, 0x38, 0x24, 0x6c, 0xfd, 0xee, 0xa3, 0x1c, + 0x30, 0x41, 0x13, 0x46, 0x42, 0xf5, 0x15, 0x56, 0x28, 0x1f, 0x14, 0x3f, 0xef, 0x8b, 0xba, 0xb6, + 0xfe, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x10, 0x03, 0x1b, 0x06, 0xf5, 0x07, 0x00, 0x00, +} diff --git a/pkg/golang-protobuf/internal/testprotos/proto3_proto/test.proto b/pkg/golang-protobuf/internal/testprotos/proto3_proto/test.proto new file mode 100644 index 000000000..b1c6749d1 --- /dev/null +++ b/pkg/golang-protobuf/internal/testprotos/proto3_proto/test.proto @@ -0,0 +1,72 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +syntax = "proto3"; + +option go_package = "github.com/golang/protobuf/internal/testprotos/proto3_proto"; + +import "google/protobuf/any.proto"; +import "proto2_proto/test.proto"; + +package proto3_test; + +message Message { + enum Humour { + UNKNOWN = 0; + PUNS = 1; + SLAPSTICK = 2; + BILL_BAILEY = 3; + } + + string name = 1; + Humour hilarity = 2; + uint32 height_in_cm = 3; + bytes data = 4; + int64 result_count = 7; + bool true_scotsman = 8; + float score = 9; + + repeated uint64 key = 5; + repeated int32 short_key = 19; + Nested nested = 6; + repeated Humour r_funny = 16; + + map terrain = 10; + proto2_test.SubDefaults proto2_field = 11; + map proto2_value = 13; + + google.protobuf.Any anything = 14; + repeated google.protobuf.Any many_things = 15; + + Message submessage = 17; + repeated Message children = 18; + + map string_map = 20; +} + +message Nested { + string bunny = 1; + bool cute = 2; +} + +message MessageWithMap { + map byte_mapping = 1; +} + + +message IntMap { + map rtt = 1; +} + +message IntMaps { + repeated IntMap maps = 1; +} + +message TestUTF8 { + string scalar = 1; + repeated string vector = 2; + oneof oneof { string field = 3; } + map map_key = 4; + map map_value = 5; +} diff --git a/pkg/golang-protobuf/internal/testprotos/regenerate.bash b/pkg/golang-protobuf/internal/testprotos/regenerate.bash new file mode 100755 index 000000000..c2eb29703 --- /dev/null +++ b/pkg/golang-protobuf/internal/testprotos/regenerate.bash @@ -0,0 +1,17 @@ +#!/bin/bash +# Copyright 2020 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +# NOTE: The integration scripts deliberately do not check to +# make sure that the test protos have been regenerated. +# It is intentional that older versions of the .pb.go files +# are checked in to ensure that they continue to function. +# +# Versions used: +# protoc: v3.9.1 +# protoc-gen-go: v1.3.2 + +for X in $(find . -name "*.proto" | sed "s|^\./||"); do + protoc -I$(pwd) --go_out=paths=source_relative:. $X +done diff --git a/pkg/golang-protobuf/jsonpb/decode.go b/pkg/golang-protobuf/jsonpb/decode.go new file mode 100644 index 000000000..6c16c255f --- /dev/null +++ b/pkg/golang-protobuf/jsonpb/decode.go @@ -0,0 +1,530 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package jsonpb + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "math" + "reflect" + "strconv" + "strings" + "time" + + "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/encoding/protojson" + protoV2 "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" +) + +const wrapJSONUnmarshalV2 = false + +// UnmarshalNext unmarshals the next JSON object from d into m. +func UnmarshalNext(d *json.Decoder, m proto.Message) error { + return new(Unmarshaler).UnmarshalNext(d, m) +} + +// Unmarshal unmarshals a JSON object from r into m. +func Unmarshal(r io.Reader, m proto.Message) error { + return new(Unmarshaler).Unmarshal(r, m) +} + +// UnmarshalString unmarshals a JSON object from s into m. +func UnmarshalString(s string, m proto.Message) error { + return new(Unmarshaler).Unmarshal(strings.NewReader(s), m) +} + +// Unmarshaler is a configurable object for converting from a JSON +// representation to a protocol buffer object. +type Unmarshaler struct { + // AllowUnknownFields specifies whether to allow messages to contain + // unknown JSON fields, as opposed to failing to unmarshal. + AllowUnknownFields bool + + // AnyResolver is used to resolve the google.protobuf.Any well-known type. + // If unset, the global registry is used by default. + AnyResolver AnyResolver +} + +// JSONPBUnmarshaler is implemented by protobuf messages that customize the way +// they are unmarshaled from JSON. Messages that implement this should also +// implement JSONPBMarshaler so that the custom format can be produced. +// +// The JSON unmarshaling must follow the JSON to proto specification: +// https://developers.google.com/protocol-buffers/docs/proto3#json +// +// Deprecated: Custom types should implement protobuf reflection instead. +type JSONPBUnmarshaler interface { + UnmarshalJSONPB(*Unmarshaler, []byte) error +} + +// Unmarshal unmarshals a JSON object from r into m. +func (u *Unmarshaler) Unmarshal(r io.Reader, m proto.Message) error { + return u.UnmarshalNext(json.NewDecoder(r), m) +} + +// UnmarshalNext unmarshals the next JSON object from d into m. +func (u *Unmarshaler) UnmarshalNext(d *json.Decoder, m proto.Message) error { + if m == nil { + return errors.New("invalid nil message") + } + + // Parse the next JSON object from the stream. + raw := json.RawMessage{} + if err := d.Decode(&raw); err != nil { + return err + } + + // Check for custom unmarshalers first since they may not properly + // implement protobuf reflection that the logic below relies on. + if jsu, ok := m.(JSONPBUnmarshaler); ok { + return jsu.UnmarshalJSONPB(u, raw) + } + + mr := proto.MessageReflect(m) + + // NOTE: For historical reasons, a top-level null is treated as a noop. + // This is incorrect, but kept for compatibility. + if string(raw) == "null" && mr.Descriptor().FullName() != "google.protobuf.Value" { + return nil + } + + if wrapJSONUnmarshalV2 { + // NOTE: If input message is non-empty, we need to preserve merge semantics + // of the old jsonpb implementation. These semantics are not supported by + // the protobuf JSON specification. + isEmpty := true + mr.Range(func(protoreflect.FieldDescriptor, protoreflect.Value) bool { + isEmpty = false // at least one iteration implies non-empty + return false + }) + if !isEmpty { + // Perform unmarshaling into a newly allocated, empty message. + mr = mr.New() + + // Use a defer to copy all unmarshaled fields into the original message. + dst := proto.MessageReflect(m) + defer mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + dst.Set(fd, v) + return true + }) + } + + // Unmarshal using the v2 JSON unmarshaler. + opts := protojson.UnmarshalOptions{ + DiscardUnknown: u.AllowUnknownFields, + } + if u.AnyResolver != nil { + opts.Resolver = anyResolver{u.AnyResolver} + } + return opts.Unmarshal(raw, mr.Interface()) + } else { + if err := u.unmarshalMessage(mr, raw); err != nil { + return err + } + return protoV2.CheckInitialized(mr.Interface()) + } +} + +func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error { + md := m.Descriptor() + fds := md.Fields() + + if jsu, ok := proto.MessageV1(m.Interface()).(JSONPBUnmarshaler); ok { + return jsu.UnmarshalJSONPB(u, in) + } + + if string(in) == "null" && md.FullName() != "google.protobuf.Value" { + return nil + } + + switch wellKnownType(md.FullName()) { + case "Any": + var jsonObject map[string]json.RawMessage + if err := json.Unmarshal(in, &jsonObject); err != nil { + return err + } + + rawTypeURL, ok := jsonObject["@type"] + if !ok { + return errors.New("Any JSON doesn't have '@type'") + } + typeURL, err := unquoteString(string(rawTypeURL)) + if err != nil { + return fmt.Errorf("can't unmarshal Any's '@type': %q", rawTypeURL) + } + m.Set(fds.ByNumber(1), protoreflect.ValueOfString(typeURL)) + + var m2 protoreflect.Message + if u.AnyResolver != nil { + mi, err := u.AnyResolver.Resolve(typeURL) + if err != nil { + return err + } + m2 = proto.MessageReflect(mi) + } else { + mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL) + if err != nil { + if err == protoregistry.NotFound { + return fmt.Errorf("could not resolve Any message type: %v", typeURL) + } + return err + } + m2 = mt.New() + } + + if wellKnownType(m2.Descriptor().FullName()) != "" { + rawValue, ok := jsonObject["value"] + if !ok { + return errors.New("Any JSON doesn't have 'value'") + } + if err := u.unmarshalMessage(m2, rawValue); err != nil { + return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err) + } + } else { + delete(jsonObject, "@type") + rawJSON, err := json.Marshal(jsonObject) + if err != nil { + return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err) + } + if err = u.unmarshalMessage(m2, rawJSON); err != nil { + return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err) + } + } + + rawWire, err := protoV2.Marshal(m2.Interface()) + if err != nil { + return fmt.Errorf("can't marshal proto %v into Any.Value: %v", typeURL, err) + } + m.Set(fds.ByNumber(2), protoreflect.ValueOfBytes(rawWire)) + return nil + case "BoolValue", "BytesValue", "StringValue", + "Int32Value", "UInt32Value", "FloatValue", + "Int64Value", "UInt64Value", "DoubleValue": + fd := fds.ByNumber(1) + v, err := u.unmarshalValue(m.NewField(fd), in, fd) + if err != nil { + return err + } + m.Set(fd, v) + return nil + case "Duration": + v, err := unquoteString(string(in)) + if err != nil { + return err + } + d, err := time.ParseDuration(v) + if err != nil { + return fmt.Errorf("bad Duration: %v", err) + } + + sec := d.Nanoseconds() / 1e9 + nsec := d.Nanoseconds() % 1e9 + m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec))) + m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec))) + return nil + case "Timestamp": + v, err := unquoteString(string(in)) + if err != nil { + return err + } + t, err := time.Parse(time.RFC3339Nano, v) + if err != nil { + return fmt.Errorf("bad Timestamp: %v", err) + } + + sec := t.Unix() + nsec := t.Nanosecond() + m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec))) + m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec))) + return nil + case "Value": + switch { + case string(in) == "null": + m.Set(fds.ByNumber(1), protoreflect.ValueOfEnum(0)) + case string(in) == "true": + m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(true)) + case string(in) == "false": + m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(false)) + case hasPrefixAndSuffix('"', in, '"'): + s, err := unquoteString(string(in)) + if err != nil { + return fmt.Errorf("unrecognized type for Value %q", in) + } + m.Set(fds.ByNumber(3), protoreflect.ValueOfString(s)) + case hasPrefixAndSuffix('[', in, ']'): + v := m.Mutable(fds.ByNumber(6)) + return u.unmarshalMessage(v.Message(), in) + case hasPrefixAndSuffix('{', in, '}'): + v := m.Mutable(fds.ByNumber(5)) + return u.unmarshalMessage(v.Message(), in) + default: + f, err := strconv.ParseFloat(string(in), 0) + if err != nil { + return fmt.Errorf("unrecognized type for Value %q", in) + } + m.Set(fds.ByNumber(2), protoreflect.ValueOfFloat64(f)) + } + return nil + case "ListValue": + var jsonArray []json.RawMessage + if err := json.Unmarshal(in, &jsonArray); err != nil { + return fmt.Errorf("bad ListValue: %v", err) + } + + lv := m.Mutable(fds.ByNumber(1)).List() + for _, raw := range jsonArray { + ve := lv.NewElement() + if err := u.unmarshalMessage(ve.Message(), raw); err != nil { + return err + } + lv.Append(ve) + } + return nil + case "Struct": + var jsonObject map[string]json.RawMessage + if err := json.Unmarshal(in, &jsonObject); err != nil { + return fmt.Errorf("bad StructValue: %v", err) + } + + mv := m.Mutable(fds.ByNumber(1)).Map() + for key, raw := range jsonObject { + kv := protoreflect.ValueOf(key).MapKey() + vv := mv.NewValue() + if err := u.unmarshalMessage(vv.Message(), raw); err != nil { + return fmt.Errorf("bad value in StructValue for key %q: %v", key, err) + } + mv.Set(kv, vv) + } + return nil + } + + var jsonObject map[string]json.RawMessage + if err := json.Unmarshal(in, &jsonObject); err != nil { + return err + } + + // Handle known fields. + for i := 0; i < fds.Len(); i++ { + fd := fds.Get(i) + if fd.IsWeak() && fd.Message().IsPlaceholder() { + continue // weak reference is not linked in + } + + // Search for any raw JSON value associated with this field. + var raw json.RawMessage + name := string(fd.Name()) + if fd.Kind() == protoreflect.GroupKind { + name = string(fd.Message().Name()) + } + if v, ok := jsonObject[name]; ok { + delete(jsonObject, name) + raw = v + } + name = string(fd.JSONName()) + if v, ok := jsonObject[name]; ok { + delete(jsonObject, name) + raw = v + } + + field := m.NewField(fd) + // Unmarshal the field value. + if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) { + continue + } + v, err := u.unmarshalValue(field, raw, fd) + if err != nil { + return err + } + m.Set(fd, v) + } + + // Handle extension fields. + for name, raw := range jsonObject { + if !strings.HasPrefix(name, "[") || !strings.HasSuffix(name, "]") { + continue + } + + // Resolve the extension field by name. + xname := protoreflect.FullName(name[len("[") : len(name)-len("]")]) + xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname) + if xt == nil && isMessageSet(md) { + xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension")) + } + if xt == nil { + continue + } + delete(jsonObject, name) + fd := xt.TypeDescriptor() + if fd.ContainingMessage().FullName() != m.Descriptor().FullName() { + return fmt.Errorf("extension field %q does not extend message %q", xname, m.Descriptor().FullName()) + } + + field := m.NewField(fd) + // Unmarshal the field value. + if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) { + continue + } + v, err := u.unmarshalValue(field, raw, fd) + if err != nil { + return err + } + m.Set(fd, v) + } + + if !u.AllowUnknownFields && len(jsonObject) > 0 { + for name := range jsonObject { + return fmt.Errorf("unknown field %q in %v", name, md.FullName()) + } + } + return nil +} + +func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool { + if fd.Cardinality() == protoreflect.Repeated { + return false + } + if md := fd.Message(); md != nil { + return md.FullName() == "google.protobuf.Value" + } + if ed := fd.Enum(); ed != nil { + return ed.FullName() == "google.protobuf.NullValue" + } + return false +} + +func isSingularJSONPBUnmarshaler(v protoreflect.Value, fd protoreflect.FieldDescriptor) bool { + if fd.Message() != nil && fd.Cardinality() != protoreflect.Repeated { + _, ok := proto.MessageV1(v.Interface()).(JSONPBUnmarshaler) + return ok + } + return false +} + +func (u *Unmarshaler) unmarshalValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { + switch { + case fd.IsList(): + var jsonArray []json.RawMessage + if err := json.Unmarshal(in, &jsonArray); err != nil { + return v, err + } + lv := v.List() + for _, raw := range jsonArray { + ve, err := u.unmarshalSingularValue(lv.NewElement(), raw, fd) + if err != nil { + return v, err + } + lv.Append(ve) + } + return v, nil + case fd.IsMap(): + var jsonObject map[string]json.RawMessage + if err := json.Unmarshal(in, &jsonObject); err != nil { + return v, err + } + kfd := fd.MapKey() + vfd := fd.MapValue() + mv := v.Map() + for key, raw := range jsonObject { + var kv protoreflect.MapKey + if kfd.Kind() == protoreflect.StringKind { + kv = protoreflect.ValueOf(key).MapKey() + } else { + v, err := u.unmarshalSingularValue(kfd.Default(), []byte(key), kfd) + if err != nil { + return v, err + } + kv = v.MapKey() + } + + vv, err := u.unmarshalSingularValue(mv.NewValue(), raw, vfd) + if err != nil { + return v, err + } + mv.Set(kv, vv) + } + return v, nil + default: + return u.unmarshalSingularValue(v, in, fd) + } +} + +var nonFinite = map[string]float64{ + `"NaN"`: math.NaN(), + `"Infinity"`: math.Inf(+1), + `"-Infinity"`: math.Inf(-1), +} + +func (u *Unmarshaler) unmarshalSingularValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { + switch fd.Kind() { + case protoreflect.BoolKind: + return unmarshalValue(in, new(bool)) + case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: + return unmarshalValue(trimQuote(in), new(int32)) + case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: + return unmarshalValue(trimQuote(in), new(int64)) + case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: + return unmarshalValue(trimQuote(in), new(uint32)) + case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: + return unmarshalValue(trimQuote(in), new(uint64)) + case protoreflect.FloatKind: + if f, ok := nonFinite[string(in)]; ok { + return protoreflect.ValueOfFloat32(float32(f)), nil + } + return unmarshalValue(trimQuote(in), new(float32)) + case protoreflect.DoubleKind: + if f, ok := nonFinite[string(in)]; ok { + return protoreflect.ValueOfFloat64(float64(f)), nil + } + return unmarshalValue(trimQuote(in), new(float64)) + case protoreflect.StringKind: + return unmarshalValue(in, new(string)) + case protoreflect.BytesKind: + return unmarshalValue(in, new([]byte)) + case protoreflect.EnumKind: + if hasPrefixAndSuffix('"', in, '"') { + vd := fd.Enum().Values().ByName(protoreflect.Name(trimQuote(in))) + if vd == nil { + return v, fmt.Errorf("unknown value %q for enum %s", in, fd.Enum().FullName()) + } + return protoreflect.ValueOfEnum(vd.Number()), nil + } + return unmarshalValue(in, new(protoreflect.EnumNumber)) + case protoreflect.MessageKind, protoreflect.GroupKind: + err := u.unmarshalMessage(v.Message(), in) + return v, err + default: + panic(fmt.Sprintf("invalid kind %v", fd.Kind())) + } +} + +func unmarshalValue(in []byte, v interface{}) (protoreflect.Value, error) { + err := json.Unmarshal(in, v) + return protoreflect.ValueOf(reflect.ValueOf(v).Elem().Interface()), err +} + +func unquoteString(in string) (out string, err error) { + err = json.Unmarshal([]byte(in), &out) + return out, err +} + +func hasPrefixAndSuffix(prefix byte, in []byte, suffix byte) bool { + if len(in) >= 2 && in[0] == prefix && in[len(in)-1] == suffix { + return true + } + return false +} + +// trimQuote is like unquoteString but simply strips surrounding quotes. +// This is incorrect, but is behavior done by the legacy implementation. +func trimQuote(in []byte) []byte { + if len(in) >= 2 && in[0] == '"' && in[len(in)-1] == '"' { + in = in[1 : len(in)-1] + } + return in +} diff --git a/pkg/golang-protobuf/jsonpb/encode.go b/pkg/golang-protobuf/jsonpb/encode.go new file mode 100644 index 000000000..685c80a62 --- /dev/null +++ b/pkg/golang-protobuf/jsonpb/encode.go @@ -0,0 +1,559 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package jsonpb + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "math" + "reflect" + "sort" + "strconv" + "strings" + "time" + + "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/encoding/protojson" + protoV2 "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" +) + +const wrapJSONMarshalV2 = false + +// Marshaler is a configurable object for marshaling protocol buffer messages +// to the specified JSON representation. +type Marshaler struct { + // OrigName specifies whether to use the original protobuf name for fields. + OrigName bool + + // EnumsAsInts specifies whether to render enum values as integers, + // as opposed to string values. + EnumsAsInts bool + + // EmitDefaults specifies whether to render fields with zero values. + EmitDefaults bool + + // Indent controls whether the output is compact or not. + // If empty, the output is compact JSON. Otherwise, every JSON object + // entry and JSON array value will be on its own line. + // Each line will be preceded by repeated copies of Indent, where the + // number of copies is the current indentation depth. + Indent string + + // AnyResolver is used to resolve the google.protobuf.Any well-known type. + // If unset, the global registry is used by default. + AnyResolver AnyResolver +} + +// JSONPBMarshaler is implemented by protobuf messages that customize the +// way they are marshaled to JSON. Messages that implement this should also +// implement JSONPBUnmarshaler so that the custom format can be parsed. +// +// The JSON marshaling must follow the proto to JSON specification: +// https://developers.google.com/protocol-buffers/docs/proto3#json +// +// Deprecated: Custom types should implement protobuf reflection instead. +type JSONPBMarshaler interface { + MarshalJSONPB(*Marshaler) ([]byte, error) +} + +// Marshal serializes a protobuf message as JSON into w. +func (jm *Marshaler) Marshal(w io.Writer, m proto.Message) error { + b, err := jm.marshal(m) + if len(b) > 0 { + if _, err := w.Write(b); err != nil { + return err + } + } + return err +} + +// MarshalToString serializes a protobuf message as JSON in string form. +func (jm *Marshaler) MarshalToString(m proto.Message) (string, error) { + b, err := jm.marshal(m) + if err != nil { + return "", err + } + return string(b), nil +} + +func (jm *Marshaler) marshal(m proto.Message) ([]byte, error) { + v := reflect.ValueOf(m) + if m == nil || (v.Kind() == reflect.Ptr && v.IsNil()) { + return nil, errors.New("Marshal called with nil") + } + + // Check for custom marshalers first since they may not properly + // implement protobuf reflection that the logic below relies on. + if jsm, ok := m.(JSONPBMarshaler); ok { + return jsm.MarshalJSONPB(jm) + } + + if wrapJSONMarshalV2 { + opts := protojson.MarshalOptions{ + UseProtoNames: jm.OrigName, + UseEnumNumbers: jm.EnumsAsInts, + EmitUnpopulated: jm.EmitDefaults, + Indent: jm.Indent, + } + if jm.AnyResolver != nil { + opts.Resolver = anyResolver{jm.AnyResolver} + } + return opts.Marshal(proto.MessageReflect(m).Interface()) + } else { + // Check for unpopulated required fields first. + m2 := proto.MessageReflect(m) + if err := protoV2.CheckInitialized(m2.Interface()); err != nil { + return nil, err + } + + w := jsonWriter{Marshaler: jm} + err := w.marshalMessage(m2, "", "") + return w.buf, err + } +} + +type jsonWriter struct { + *Marshaler + buf []byte +} + +func (w *jsonWriter) write(s string) { + w.buf = append(w.buf, s...) +} + +func (w *jsonWriter) marshalMessage(m protoreflect.Message, indent, typeURL string) error { + if jsm, ok := proto.MessageV1(m.Interface()).(JSONPBMarshaler); ok { + b, err := jsm.MarshalJSONPB(w.Marshaler) + if err != nil { + return err + } + if typeURL != "" { + // we are marshaling this object to an Any type + var js map[string]*json.RawMessage + if err = json.Unmarshal(b, &js); err != nil { + return fmt.Errorf("type %T produced invalid JSON: %v", m.Interface(), err) + } + turl, err := json.Marshal(typeURL) + if err != nil { + return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err) + } + js["@type"] = (*json.RawMessage)(&turl) + if b, err = json.Marshal(js); err != nil { + return err + } + } + w.write(string(b)) + return nil + } + + md := m.Descriptor() + fds := md.Fields() + + // Handle well-known types. + const secondInNanos = int64(time.Second / time.Nanosecond) + switch wellKnownType(md.FullName()) { + case "Any": + return w.marshalAny(m, indent) + case "BoolValue", "BytesValue", "StringValue", + "Int32Value", "UInt32Value", "FloatValue", + "Int64Value", "UInt64Value", "DoubleValue": + fd := fds.ByNumber(1) + return w.marshalValue(fd, m.Get(fd), indent) + case "Duration": + const maxSecondsInDuration = 315576000000 + // "Generated output always contains 0, 3, 6, or 9 fractional digits, + // depending on required precision." + s := m.Get(fds.ByNumber(1)).Int() + ns := m.Get(fds.ByNumber(2)).Int() + if s < -maxSecondsInDuration || s > maxSecondsInDuration { + return fmt.Errorf("seconds out of range %v", s) + } + if ns <= -secondInNanos || ns >= secondInNanos { + return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos) + } + if (s > 0 && ns < 0) || (s < 0 && ns > 0) { + return errors.New("signs of seconds and nanos do not match") + } + var sign string + if s < 0 || ns < 0 { + sign, s, ns = "-", -1*s, -1*ns + } + x := fmt.Sprintf("%s%d.%09d", sign, s, ns) + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, ".000") + w.write(fmt.Sprintf(`"%vs"`, x)) + return nil + case "Timestamp": + // "RFC 3339, where generated output will always be Z-normalized + // and uses 0, 3, 6 or 9 fractional digits." + s := m.Get(fds.ByNumber(1)).Int() + ns := m.Get(fds.ByNumber(2)).Int() + if ns < 0 || ns >= secondInNanos { + return fmt.Errorf("ns out of range [0, %v)", secondInNanos) + } + t := time.Unix(s, ns).UTC() + // time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits). + x := t.Format("2006-01-02T15:04:05.000000000") + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, ".000") + w.write(fmt.Sprintf(`"%vZ"`, x)) + return nil + case "Value": + // JSON value; which is a null, number, string, bool, object, or array. + od := md.Oneofs().Get(0) + fd := m.WhichOneof(od) + if fd == nil { + return errors.New("nil Value") + } + return w.marshalValue(fd, m.Get(fd), indent) + case "Struct", "ListValue": + // JSON object or array. + fd := fds.ByNumber(1) + return w.marshalValue(fd, m.Get(fd), indent) + } + + w.write("{") + if w.Indent != "" { + w.write("\n") + } + + firstField := true + if typeURL != "" { + if err := w.marshalTypeURL(indent, typeURL); err != nil { + return err + } + firstField = false + } + + for i := 0; i < fds.Len(); { + fd := fds.Get(i) + if od := fd.ContainingOneof(); od != nil { + fd = m.WhichOneof(od) + i += od.Fields().Len() + if fd == nil { + continue + } + } else { + i++ + } + + v := m.Get(fd) + + if !m.Has(fd) { + if !w.EmitDefaults || fd.ContainingOneof() != nil { + continue + } + if fd.Cardinality() != protoreflect.Repeated && (fd.Message() != nil || fd.Syntax() == protoreflect.Proto2) { + v = protoreflect.Value{} // use "null" for singular messages or proto2 scalars + } + } + + if !firstField { + w.writeComma() + } + if err := w.marshalField(fd, v, indent); err != nil { + return err + } + firstField = false + } + + // Handle proto2 extensions. + if md.ExtensionRanges().Len() > 0 { + // Collect a sorted list of all extension descriptor and values. + type ext struct { + desc protoreflect.FieldDescriptor + val protoreflect.Value + } + var exts []ext + m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + if fd.IsExtension() { + exts = append(exts, ext{fd, v}) + } + return true + }) + sort.Slice(exts, func(i, j int) bool { + return exts[i].desc.Number() < exts[j].desc.Number() + }) + + for _, ext := range exts { + if !firstField { + w.writeComma() + } + if err := w.marshalField(ext.desc, ext.val, indent); err != nil { + return err + } + firstField = false + } + } + + if w.Indent != "" { + w.write("\n") + w.write(indent) + } + w.write("}") + return nil +} + +func (w *jsonWriter) writeComma() { + if w.Indent != "" { + w.write(",\n") + } else { + w.write(",") + } +} + +func (w *jsonWriter) marshalAny(m protoreflect.Message, indent string) error { + // "If the Any contains a value that has a special JSON mapping, + // it will be converted as follows: {"@type": xxx, "value": yyy}. + // Otherwise, the value will be converted into a JSON object, + // and the "@type" field will be inserted to indicate the actual data type." + md := m.Descriptor() + typeURL := m.Get(md.Fields().ByNumber(1)).String() + rawVal := m.Get(md.Fields().ByNumber(2)).Bytes() + + var m2 protoreflect.Message + if w.AnyResolver != nil { + mi, err := w.AnyResolver.Resolve(typeURL) + if err != nil { + return err + } + m2 = proto.MessageReflect(mi) + } else { + mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL) + if err != nil { + return err + } + m2 = mt.New() + } + + if err := protoV2.Unmarshal(rawVal, m2.Interface()); err != nil { + return err + } + + if wellKnownType(m2.Descriptor().FullName()) == "" { + return w.marshalMessage(m2, indent, typeURL) + } + + w.write("{") + if w.Indent != "" { + w.write("\n") + } + if err := w.marshalTypeURL(indent, typeURL); err != nil { + return err + } + w.writeComma() + if w.Indent != "" { + w.write(indent) + w.write(w.Indent) + w.write(`"value": `) + } else { + w.write(`"value":`) + } + if err := w.marshalMessage(m2, indent+w.Indent, ""); err != nil { + return err + } + if w.Indent != "" { + w.write("\n") + w.write(indent) + } + w.write("}") + return nil +} + +func (w *jsonWriter) marshalTypeURL(indent, typeURL string) error { + if w.Indent != "" { + w.write(indent) + w.write(w.Indent) + } + w.write(`"@type":`) + if w.Indent != "" { + w.write(" ") + } + b, err := json.Marshal(typeURL) + if err != nil { + return err + } + w.write(string(b)) + return nil +} + +// marshalField writes field description and value to the Writer. +func (w *jsonWriter) marshalField(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error { + if w.Indent != "" { + w.write(indent) + w.write(w.Indent) + } + w.write(`"`) + switch { + case fd.IsExtension(): + // For message set, use the fname of the message as the extension name. + name := string(fd.FullName()) + if isMessageSet(fd.ContainingMessage()) { + name = strings.TrimSuffix(name, ".message_set_extension") + } + + w.write("[" + name + "]") + case w.OrigName: + name := string(fd.Name()) + if fd.Kind() == protoreflect.GroupKind { + name = string(fd.Message().Name()) + } + w.write(name) + default: + w.write(string(fd.JSONName())) + } + w.write(`":`) + if w.Indent != "" { + w.write(" ") + } + return w.marshalValue(fd, v, indent) +} + +func (w *jsonWriter) marshalValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error { + switch { + case fd.IsList(): + w.write("[") + comma := "" + lv := v.List() + for i := 0; i < lv.Len(); i++ { + w.write(comma) + if w.Indent != "" { + w.write("\n") + w.write(indent) + w.write(w.Indent) + w.write(w.Indent) + } + if err := w.marshalSingularValue(fd, lv.Get(i), indent+w.Indent); err != nil { + return err + } + comma = "," + } + if w.Indent != "" { + w.write("\n") + w.write(indent) + w.write(w.Indent) + } + w.write("]") + return nil + case fd.IsMap(): + kfd := fd.MapKey() + vfd := fd.MapValue() + mv := v.Map() + + // Collect a sorted list of all map keys and values. + type entry struct{ key, val protoreflect.Value } + var entries []entry + mv.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { + entries = append(entries, entry{k.Value(), v}) + return true + }) + sort.Slice(entries, func(i, j int) bool { + switch kfd.Kind() { + case protoreflect.BoolKind: + return !entries[i].key.Bool() && entries[j].key.Bool() + case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: + return entries[i].key.Int() < entries[j].key.Int() + case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind: + return entries[i].key.Uint() < entries[j].key.Uint() + case protoreflect.StringKind: + return entries[i].key.String() < entries[j].key.String() + default: + panic("invalid kind") + } + }) + + w.write(`{`) + comma := "" + for _, entry := range entries { + w.write(comma) + if w.Indent != "" { + w.write("\n") + w.write(indent) + w.write(w.Indent) + w.write(w.Indent) + } + + s := fmt.Sprint(entry.key.Interface()) + b, err := json.Marshal(s) + if err != nil { + return err + } + w.write(string(b)) + + w.write(`:`) + if w.Indent != "" { + w.write(` `) + } + + if err := w.marshalSingularValue(vfd, entry.val, indent+w.Indent); err != nil { + return err + } + comma = "," + } + if w.Indent != "" { + w.write("\n") + w.write(indent) + w.write(w.Indent) + } + w.write(`}`) + return nil + default: + return w.marshalSingularValue(fd, v, indent) + } +} + +func (w *jsonWriter) marshalSingularValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error { + switch { + case !v.IsValid(): + w.write("null") + return nil + case fd.Message() != nil: + return w.marshalMessage(v.Message(), indent+w.Indent, "") + case fd.Enum() != nil: + if fd.Enum().FullName() == "google.protobuf.NullValue" { + w.write("null") + return nil + } + + vd := fd.Enum().Values().ByNumber(v.Enum()) + if vd == nil || w.EnumsAsInts { + w.write(strconv.Itoa(int(v.Enum()))) + } else { + w.write(`"` + string(vd.Name()) + `"`) + } + return nil + default: + switch v.Interface().(type) { + case float32, float64: + switch { + case math.IsInf(v.Float(), +1): + w.write(`"Infinity"`) + return nil + case math.IsInf(v.Float(), -1): + w.write(`"-Infinity"`) + return nil + case math.IsNaN(v.Float()): + w.write(`"NaN"`) + return nil + } + case int64, uint64: + w.write(fmt.Sprintf(`"%d"`, v.Interface())) + return nil + } + + b, err := json.Marshal(v.Interface()) + if err != nil { + return err + } + w.write(string(b)) + return nil + } +} diff --git a/pkg/golang-protobuf/jsonpb/json.go b/pkg/golang-protobuf/jsonpb/json.go new file mode 100644 index 000000000..480e2448d --- /dev/null +++ b/pkg/golang-protobuf/jsonpb/json.go @@ -0,0 +1,69 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package jsonpb provides functionality to marshal and unmarshal between a +// protocol buffer message and JSON. It follows the specification at +// https://developers.google.com/protocol-buffers/docs/proto3#json. +// +// Do not rely on the default behavior of the standard encoding/json package +// when called on generated message types as it does not operate correctly. +// +// Deprecated: Use the "google.golang.org/protobuf/encoding/protojson" +// package instead. +package jsonpb + +import ( + "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/runtime/protoimpl" +) + +// AnyResolver takes a type URL, present in an Any message, +// and resolves it into an instance of the associated message. +type AnyResolver interface { + Resolve(typeURL string) (proto.Message, error) +} + +type anyResolver struct{ AnyResolver } + +func (r anyResolver) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) { + return r.FindMessageByURL(string(message)) +} + +func (r anyResolver) FindMessageByURL(url string) (protoreflect.MessageType, error) { + m, err := r.Resolve(url) + if err != nil { + return nil, err + } + return protoimpl.X.MessageTypeOf(m), nil +} + +func (r anyResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) { + return protoregistry.GlobalTypes.FindExtensionByName(field) +} + +func (r anyResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) { + return protoregistry.GlobalTypes.FindExtensionByNumber(message, field) +} + +func wellKnownType(s protoreflect.FullName) string { + if s.Parent() == "google.protobuf" { + switch s.Name() { + case "Empty", "Any", + "BoolValue", "BytesValue", "StringValue", + "Int32Value", "UInt32Value", "FloatValue", + "Int64Value", "UInt64Value", "DoubleValue", + "Duration", "Timestamp", + "NullValue", "Struct", "Value", "ListValue": + return string(s.Name()) + } + } + return "" +} + +func isMessageSet(md protoreflect.MessageDescriptor) bool { + ms, ok := md.(interface{ IsMessageSet() bool }) + return ok && ms.IsMessageSet() +} diff --git a/pkg/golang-protobuf/jsonpb/json_test.go b/pkg/golang-protobuf/jsonpb/json_test.go new file mode 100644 index 000000000..39427734e --- /dev/null +++ b/pkg/golang-protobuf/jsonpb/json_test.go @@ -0,0 +1,1264 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package jsonpb + +import ( + "bytes" + "compress/gzip" + "encoding/json" + "io" + "math" + "reflect" + "strings" + "testing" + + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes" + + pb2 "github.com/golang/protobuf/internal/testprotos/jsonpb_proto" + pb3 "github.com/golang/protobuf/internal/testprotos/proto3_proto" + descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" + anypb "github.com/golang/protobuf/ptypes/any" + durpb "github.com/golang/protobuf/ptypes/duration" + stpb "github.com/golang/protobuf/ptypes/struct" + tspb "github.com/golang/protobuf/ptypes/timestamp" + wpb "github.com/golang/protobuf/ptypes/wrappers" +) + +var ( + marshaler = Marshaler{} + + marshalerAllOptions = Marshaler{ + Indent: " ", + } + + simpleObject = &pb2.Simple{ + OInt32: proto.Int32(-32), + OInt32Str: proto.Int32(-32), + OInt64: proto.Int64(-6400000000), + OInt64Str: proto.Int64(-6400000000), + OUint32: proto.Uint32(32), + OUint32Str: proto.Uint32(32), + OUint64: proto.Uint64(6400000000), + OUint64Str: proto.Uint64(6400000000), + OSint32: proto.Int32(-13), + OSint32Str: proto.Int32(-13), + OSint64: proto.Int64(-2600000000), + OSint64Str: proto.Int64(-2600000000), + OFloat: proto.Float32(3.14), + OFloatStr: proto.Float32(3.14), + ODouble: proto.Float64(6.02214179e23), + ODoubleStr: proto.Float64(6.02214179e23), + OBool: proto.Bool(true), + OString: proto.String("hello \"there\""), + OBytes: []byte("beep boop"), + } + + simpleObjectInputJSON = `{` + + `"oBool":true,` + + `"oInt32":-32,` + + `"oInt32Str":"-32",` + + `"oInt64":-6400000000,` + + `"oInt64Str":"-6400000000",` + + `"oUint32":32,` + + `"oUint32Str":"32",` + + `"oUint64":6400000000,` + + `"oUint64Str":"6400000000",` + + `"oSint32":-13,` + + `"oSint32Str":"-13",` + + `"oSint64":-2600000000,` + + `"oSint64Str":"-2600000000",` + + `"oFloat":3.14,` + + `"oFloatStr":"3.14",` + + `"oDouble":6.02214179e+23,` + + `"oDoubleStr":"6.02214179e+23",` + + `"oString":"hello \"there\"",` + + `"oBytes":"YmVlcCBib29w"` + + `}` + + simpleObjectOutputJSON = `{` + + `"oBool":true,` + + `"oInt32":-32,` + + `"oInt32Str":-32,` + + `"oInt64":"-6400000000",` + + `"oInt64Str":"-6400000000",` + + `"oUint32":32,` + + `"oUint32Str":32,` + + `"oUint64":"6400000000",` + + `"oUint64Str":"6400000000",` + + `"oSint32":-13,` + + `"oSint32Str":-13,` + + `"oSint64":"-2600000000",` + + `"oSint64Str":"-2600000000",` + + `"oFloat":3.14,` + + `"oFloatStr":3.14,` + + `"oDouble":6.02214179e+23,` + + `"oDoubleStr":6.02214179e+23,` + + `"oString":"hello \"there\"",` + + `"oBytes":"YmVlcCBib29w"` + + `}` + + simpleObjectInputPrettyJSON = `{ + "oBool": true, + "oInt32": -32, + "oInt32Str": "-32", + "oInt64": -6400000000, + "oInt64Str": "-6400000000", + "oUint32": 32, + "oUint32Str": "32", + "oUint64": 6400000000, + "oUint64Str": "6400000000", + "oSint32": -13, + "oSint32Str": "-13", + "oSint64": -2600000000, + "oSint64Str": "-2600000000", + "oFloat": 3.14, + "oFloatStr": "3.14", + "oDouble": 6.02214179e+23, + "oDoubleStr": "6.02214179e+23", + "oString": "hello \"there\"", + "oBytes": "YmVlcCBib29w" +}` + + simpleObjectOutputPrettyJSON = `{ + "oBool": true, + "oInt32": -32, + "oInt32Str": -32, + "oInt64": "-6400000000", + "oInt64Str": "-6400000000", + "oUint32": 32, + "oUint32Str": 32, + "oUint64": "6400000000", + "oUint64Str": "6400000000", + "oSint32": -13, + "oSint32Str": -13, + "oSint64": "-2600000000", + "oSint64Str": "-2600000000", + "oFloat": 3.14, + "oFloatStr": 3.14, + "oDouble": 6.02214179e+23, + "oDoubleStr": 6.02214179e+23, + "oString": "hello \"there\"", + "oBytes": "YmVlcCBib29w" +}` + + repeatsObject = &pb2.Repeats{ + RBool: []bool{true, false, true}, + RInt32: []int32{-3, -4, -5}, + RInt64: []int64{-123456789, -987654321}, + RUint32: []uint32{1, 2, 3}, + RUint64: []uint64{6789012345, 3456789012}, + RSint32: []int32{-1, -2, -3}, + RSint64: []int64{-6789012345, -3456789012}, + RFloat: []float32{3.14, 6.28}, + RDouble: []float64{299792458 * 1e20, 6.62606957e-34}, + RString: []string{"happy", "days"}, + RBytes: [][]byte{[]byte("skittles"), []byte("m&m's")}, + } + + repeatsObjectJSON = `{` + + `"rBool":[true,false,true],` + + `"rInt32":[-3,-4,-5],` + + `"rInt64":["-123456789","-987654321"],` + + `"rUint32":[1,2,3],` + + `"rUint64":["6789012345","3456789012"],` + + `"rSint32":[-1,-2,-3],` + + `"rSint64":["-6789012345","-3456789012"],` + + `"rFloat":[3.14,6.28],` + + `"rDouble":[2.99792458e+28,6.62606957e-34],` + + `"rString":["happy","days"],` + + `"rBytes":["c2tpdHRsZXM=","bSZtJ3M="]` + + `}` + + repeatsObjectPrettyJSON = `{ + "rBool": [ + true, + false, + true + ], + "rInt32": [ + -3, + -4, + -5 + ], + "rInt64": [ + "-123456789", + "-987654321" + ], + "rUint32": [ + 1, + 2, + 3 + ], + "rUint64": [ + "6789012345", + "3456789012" + ], + "rSint32": [ + -1, + -2, + -3 + ], + "rSint64": [ + "-6789012345", + "-3456789012" + ], + "rFloat": [ + 3.14, + 6.28 + ], + "rDouble": [ + 2.99792458e+28, + 6.62606957e-34 + ], + "rString": [ + "happy", + "days" + ], + "rBytes": [ + "c2tpdHRsZXM=", + "bSZtJ3M=" + ] +}` + + innerSimple = &pb2.Simple{OInt32: proto.Int32(-32)} + innerSimple2 = &pb2.Simple{OInt64: proto.Int64(25)} + innerRepeats = &pb2.Repeats{RString: []string{"roses", "red"}} + innerRepeats2 = &pb2.Repeats{RString: []string{"violets", "blue"}} + complexObject = &pb2.Widget{ + Color: pb2.Widget_GREEN.Enum(), + RColor: []pb2.Widget_Color{pb2.Widget_RED, pb2.Widget_GREEN, pb2.Widget_BLUE}, + Simple: innerSimple, + RSimple: []*pb2.Simple{innerSimple, innerSimple2}, + Repeats: innerRepeats, + RRepeats: []*pb2.Repeats{innerRepeats, innerRepeats2}, + } + + complexObjectJSON = `{"color":"GREEN",` + + `"rColor":["RED","GREEN","BLUE"],` + + `"simple":{"oInt32":-32},` + + `"rSimple":[{"oInt32":-32},{"oInt64":"25"}],` + + `"repeats":{"rString":["roses","red"]},` + + `"rRepeats":[{"rString":["roses","red"]},{"rString":["violets","blue"]}]` + + `}` + + complexObjectPrettyJSON = `{ + "color": "GREEN", + "rColor": [ + "RED", + "GREEN", + "BLUE" + ], + "simple": { + "oInt32": -32 + }, + "rSimple": [ + { + "oInt32": -32 + }, + { + "oInt64": "25" + } + ], + "repeats": { + "rString": [ + "roses", + "red" + ] + }, + "rRepeats": [ + { + "rString": [ + "roses", + "red" + ] + }, + { + "rString": [ + "violets", + "blue" + ] + } + ] +}` + + colorPrettyJSON = `{ + "color": 2 +}` + + colorListPrettyJSON = `{ + "color": 1000, + "rColor": [ + "RED" + ] +}` + + nummyPrettyJSON = `{ + "nummy": { + "1": 2, + "3": 4 + } +}` + + objjyPrettyJSON = `{ + "objjy": { + "1": { + "dub": 1 + } + } +}` + realNumber = &pb2.Real{Value: proto.Float64(3.14159265359)} + realNumberName = "Pi" + complexNumber = &pb2.Complex{Imaginary: proto.Float64(0.5772156649)} + realNumberJSON = `{` + + `"value":3.14159265359,` + + `"[jsonpb_test.Complex.real_extension]":{"imaginary":0.5772156649},` + + `"[jsonpb_test.name]":"Pi"` + + `}` + + anySimple = &pb2.KnownTypes{ + An: &anypb.Any{ + TypeUrl: "something.example.com/jsonpb_test.Simple", + Value: []byte{ + // &pb2.Simple{OBool:true} + 1 << 3, 1, + }, + }, + } + anySimpleJSON = `{"an":{"@type":"something.example.com/jsonpb_test.Simple","oBool":true}}` + anySimplePrettyJSON = `{ + "an": { + "@type": "something.example.com/jsonpb_test.Simple", + "oBool": true + } +}` + + anyWellKnown = &pb2.KnownTypes{ + An: &anypb.Any{ + TypeUrl: "type.googleapis.com/google.protobuf.Duration", + Value: []byte{ + // &durpb.Duration{Seconds: 1, Nanos: 212000000 } + 1 << 3, 1, // seconds + 2 << 3, 0x80, 0xba, 0x8b, 0x65, // nanos + }, + }, + } + anyWellKnownJSON = `{"an":{"@type":"type.googleapis.com/google.protobuf.Duration","value":"1.212s"}}` + anyWellKnownPrettyJSON = `{ + "an": { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } +}` + + nonFinites = &pb2.NonFinites{ + FNan: proto.Float32(float32(math.NaN())), + FPinf: proto.Float32(float32(math.Inf(1))), + FNinf: proto.Float32(float32(math.Inf(-1))), + DNan: proto.Float64(float64(math.NaN())), + DPinf: proto.Float64(float64(math.Inf(1))), + DNinf: proto.Float64(float64(math.Inf(-1))), + } + nonFinitesJSON = `{` + + `"fNan":"NaN",` + + `"fPinf":"Infinity",` + + `"fNinf":"-Infinity",` + + `"dNan":"NaN",` + + `"dPinf":"Infinity",` + + `"dNinf":"-Infinity"` + + `}` +) + +func init() { + if err := proto.SetExtension(realNumber, pb2.E_Name, &realNumberName); err != nil { + panic(err) + } + if err := proto.SetExtension(realNumber, pb2.E_Complex_RealExtension, complexNumber); err != nil { + panic(err) + } +} + +var marshalingTests = []struct { + desc string + marshaler Marshaler + pb proto.Message + json string +}{ + {"simple flat object", marshaler, simpleObject, simpleObjectOutputJSON}, + {"simple pretty object", marshalerAllOptions, simpleObject, simpleObjectOutputPrettyJSON}, + {"non-finite floats fields object", marshaler, nonFinites, nonFinitesJSON}, + {"repeated fields flat object", marshaler, repeatsObject, repeatsObjectJSON}, + {"repeated fields pretty object", marshalerAllOptions, repeatsObject, repeatsObjectPrettyJSON}, + {"nested message/enum flat object", marshaler, complexObject, complexObjectJSON}, + {"nested message/enum pretty object", marshalerAllOptions, complexObject, complexObjectPrettyJSON}, + {"enum-string flat object", Marshaler{}, + &pb2.Widget{Color: pb2.Widget_BLUE.Enum()}, `{"color":"BLUE"}`}, + {"enum-value pretty object", Marshaler{EnumsAsInts: true, Indent: " "}, + &pb2.Widget{Color: pb2.Widget_BLUE.Enum()}, colorPrettyJSON}, + {"unknown enum value object", marshalerAllOptions, + &pb2.Widget{Color: pb2.Widget_Color(1000).Enum(), RColor: []pb2.Widget_Color{pb2.Widget_RED}}, colorListPrettyJSON}, + {"repeated proto3 enum", Marshaler{}, + &pb3.Message{RFunny: []pb3.Message_Humour{ + pb3.Message_PUNS, + pb3.Message_SLAPSTICK, + }}, + `{"rFunny":["PUNS","SLAPSTICK"]}`}, + {"repeated proto3 enum as int", Marshaler{EnumsAsInts: true}, + &pb3.Message{RFunny: []pb3.Message_Humour{ + pb3.Message_PUNS, + pb3.Message_SLAPSTICK, + }}, + `{"rFunny":[1,2]}`}, + {"empty value", marshaler, &pb2.Simple3{}, `{}`}, + {"empty value emitted", Marshaler{EmitDefaults: true}, &pb2.Simple3{}, `{"dub":0}`}, + {"empty repeated emitted", Marshaler{EmitDefaults: true}, &pb2.SimpleSlice3{}, `{"slices":[]}`}, + {"empty map emitted", Marshaler{EmitDefaults: true}, &pb2.SimpleMap3{}, `{"stringy":{}}`}, + {"nested struct null", Marshaler{EmitDefaults: true}, &pb2.SimpleNull3{}, `{"simple":null}`}, + {"map", marshaler, &pb2.Mappy{Nummy: map[int64]int32{1: 2, 3: 4}}, `{"nummy":{"1":2,"3":4}}`}, + {"map", marshalerAllOptions, &pb2.Mappy{Nummy: map[int64]int32{1: 2, 3: 4}}, nummyPrettyJSON}, + {"map", marshaler, + &pb2.Mappy{Strry: map[string]string{`"one"`: "two", "three": "four"}}, + `{"strry":{"\"one\"":"two","three":"four"}}`}, + {"map", marshaler, + &pb2.Mappy{Objjy: map[int32]*pb2.Simple3{1: {Dub: 1}}}, `{"objjy":{"1":{"dub":1}}}`}, + {"map", marshalerAllOptions, + &pb2.Mappy{Objjy: map[int32]*pb2.Simple3{1: {Dub: 1}}}, objjyPrettyJSON}, + {"map", marshaler, &pb2.Mappy{Buggy: map[int64]string{1234: "yup"}}, + `{"buggy":{"1234":"yup"}}`}, + {"map", marshaler, &pb2.Mappy{Booly: map[bool]bool{false: true}}, `{"booly":{"false":true}}`}, + {"map", marshaler, &pb2.Mappy{Enumy: map[string]pb2.Numeral{"XIV": pb2.Numeral_ROMAN}}, `{"enumy":{"XIV":"ROMAN"}}`}, + {"map", Marshaler{EnumsAsInts: true}, &pb2.Mappy{Enumy: map[string]pb2.Numeral{"XIV": pb2.Numeral_ROMAN}}, `{"enumy":{"XIV":2}}`}, + {"map", marshaler, &pb2.Mappy{S32Booly: map[int32]bool{1: true, 3: false, 10: true, 12: false}}, `{"s32booly":{"1":true,"3":false,"10":true,"12":false}}`}, + {"map", marshaler, &pb2.Mappy{S64Booly: map[int64]bool{1: true, 3: false, 10: true, 12: false}}, `{"s64booly":{"1":true,"3":false,"10":true,"12":false}}`}, + {"map", marshaler, &pb2.Mappy{U32Booly: map[uint32]bool{1: true, 3: false, 10: true, 12: false}}, `{"u32booly":{"1":true,"3":false,"10":true,"12":false}}`}, + {"map", marshaler, &pb2.Mappy{U64Booly: map[uint64]bool{1: true, 3: false, 10: true, 12: false}}, `{"u64booly":{"1":true,"3":false,"10":true,"12":false}}`}, + {"proto2 map", marshaler, &pb2.Maps{MInt64Str: map[int64]string{213: "cat"}}, + `{"mInt64Str":{"213":"cat"}}`}, + {"proto2 map", marshaler, + &pb2.Maps{MBoolSimple: map[bool]*pb2.Simple{true: {OInt32: proto.Int32(1)}}}, + `{"mBoolSimple":{"true":{"oInt32":1}}}`}, + {"oneof, not set", marshaler, &pb2.MsgWithOneof{}, `{}`}, + {"oneof, set", marshaler, &pb2.MsgWithOneof{Union: &pb2.MsgWithOneof_Title{"Grand Poobah"}}, `{"title":"Grand Poobah"}`}, + {"oneof NullValue", marshaler, &pb2.MsgWithOneof{Union: &pb2.MsgWithOneof_NullValue{stpb.NullValue_NULL_VALUE}}, `{"nullValue":null}`}, + {"force orig_name", Marshaler{OrigName: true}, &pb2.Simple{OInt32: proto.Int32(4)}, + `{"o_int32":4}`}, + {"proto2 extension", marshaler, realNumber, realNumberJSON}, + {"Any with message", marshaler, anySimple, anySimpleJSON}, + {"Any with message and indent", marshalerAllOptions, anySimple, anySimplePrettyJSON}, + {"Any with WKT", marshaler, anyWellKnown, anyWellKnownJSON}, + {"Any with WKT and indent", marshalerAllOptions, anyWellKnown, anyWellKnownPrettyJSON}, + {"Duration empty", marshaler, &durpb.Duration{}, `"0s"`}, + {"Duration with secs", marshaler, &durpb.Duration{Seconds: 3}, `"3s"`}, + {"Duration with -secs", marshaler, &durpb.Duration{Seconds: -3}, `"-3s"`}, + {"Duration with nanos", marshaler, &durpb.Duration{Nanos: 1e6}, `"0.001s"`}, + {"Duration with -nanos", marshaler, &durpb.Duration{Nanos: -1e6}, `"-0.001s"`}, + {"Duration with large secs", marshaler, &durpb.Duration{Seconds: 1e10, Nanos: 1}, `"10000000000.000000001s"`}, + {"Duration with 6-digit nanos", marshaler, &durpb.Duration{Nanos: 1e4}, `"0.000010s"`}, + {"Duration with 3-digit nanos", marshaler, &durpb.Duration{Nanos: 1e6}, `"0.001s"`}, + {"Duration with -secs -nanos", marshaler, &durpb.Duration{Seconds: -123, Nanos: -450}, `"-123.000000450s"`}, + {"Duration max value", marshaler, &durpb.Duration{Seconds: 315576000000, Nanos: 999999999}, `"315576000000.999999999s"`}, + {"Duration min value", marshaler, &durpb.Duration{Seconds: -315576000000, Nanos: -999999999}, `"-315576000000.999999999s"`}, + {"Struct", marshaler, &pb2.KnownTypes{St: &stpb.Struct{ + Fields: map[string]*stpb.Value{ + "one": {Kind: &stpb.Value_StringValue{"loneliest number"}}, + "two": {Kind: &stpb.Value_NullValue{stpb.NullValue_NULL_VALUE}}, + }, + }}, `{"st":{"one":"loneliest number","two":null}}`}, + {"empty ListValue", marshaler, &pb2.KnownTypes{Lv: &stpb.ListValue{}}, `{"lv":[]}`}, + {"basic ListValue", marshaler, &pb2.KnownTypes{Lv: &stpb.ListValue{Values: []*stpb.Value{ + {Kind: &stpb.Value_StringValue{"x"}}, + {Kind: &stpb.Value_NullValue{}}, + {Kind: &stpb.Value_NumberValue{3}}, + {Kind: &stpb.Value_BoolValue{true}}, + }}}, `{"lv":["x",null,3,true]}`}, + {"Timestamp", marshaler, &pb2.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 21e6}}, `{"ts":"2014-05-13T16:53:20.021Z"}`}, + {"Timestamp", marshaler, &pb2.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 0}}, `{"ts":"2014-05-13T16:53:20Z"}`}, + {"number Value", marshaler, &pb2.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_NumberValue{1}}}, `{"val":1}`}, + {"null Value", marshaler, &pb2.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_NullValue{stpb.NullValue_NULL_VALUE}}}, `{"val":null}`}, + {"string number value", marshaler, &pb2.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_StringValue{"9223372036854775807"}}}, `{"val":"9223372036854775807"}`}, + {"list of lists Value", marshaler, &pb2.KnownTypes{Val: &stpb.Value{ + Kind: &stpb.Value_ListValue{&stpb.ListValue{ + Values: []*stpb.Value{ + {Kind: &stpb.Value_StringValue{"x"}}, + {Kind: &stpb.Value_ListValue{&stpb.ListValue{ + Values: []*stpb.Value{ + {Kind: &stpb.Value_ListValue{&stpb.ListValue{ + Values: []*stpb.Value{{Kind: &stpb.Value_StringValue{"y"}}}, + }}}, + {Kind: &stpb.Value_StringValue{"z"}}, + }, + }}}, + }, + }}, + }}, `{"val":["x",[["y"],"z"]]}`}, + + {"DoubleValue", marshaler, &pb2.KnownTypes{Dbl: &wpb.DoubleValue{Value: 1.2}}, `{"dbl":1.2}`}, + {"FloatValue", marshaler, &pb2.KnownTypes{Flt: &wpb.FloatValue{Value: 1.2}}, `{"flt":1.2}`}, + {"Int64Value", marshaler, &pb2.KnownTypes{I64: &wpb.Int64Value{Value: -3}}, `{"i64":"-3"}`}, + {"UInt64Value", marshaler, &pb2.KnownTypes{U64: &wpb.UInt64Value{Value: 3}}, `{"u64":"3"}`}, + {"Int32Value", marshaler, &pb2.KnownTypes{I32: &wpb.Int32Value{Value: -4}}, `{"i32":-4}`}, + {"UInt32Value", marshaler, &pb2.KnownTypes{U32: &wpb.UInt32Value{Value: 4}}, `{"u32":4}`}, + {"BoolValue", marshaler, &pb2.KnownTypes{Bool: &wpb.BoolValue{Value: true}}, `{"bool":true}`}, + {"StringValue", marshaler, &pb2.KnownTypes{Str: &wpb.StringValue{Value: "plush"}}, `{"str":"plush"}`}, + {"BytesValue", marshaler, &pb2.KnownTypes{Bytes: &wpb.BytesValue{Value: []byte("wow")}}, `{"bytes":"d293"}`}, + + {"required", marshaler, &pb2.MsgWithRequired{Str: proto.String("hello")}, `{"str":"hello"}`}, + {"required bytes", marshaler, &pb2.MsgWithRequiredBytes{Byts: []byte{}}, `{"byts":""}`}, +} + +func TestMarshaling(t *testing.T) { + for _, tt := range marshalingTests { + json, err := tt.marshaler.MarshalToString(tt.pb) + if err != nil { + t.Errorf("%s: marshaling error: %v", tt.desc, err) + } else if tt.json != json { + t.Errorf("%s:\ngot: %v\nwant: %v", tt.desc, json, tt.json) + } + } +} + +func TestMarshalingNil(t *testing.T) { + var msg *pb2.Simple + m := &Marshaler{} + if _, err := m.MarshalToString(msg); err == nil { + t.Errorf("mashaling nil returned no error") + } +} + +func TestMarshalIllegalTime(t *testing.T) { + tests := []struct { + pb proto.Message + fail bool + }{ + {&durpb.Duration{Seconds: 1, Nanos: 0}, false}, + {&durpb.Duration{Seconds: -1, Nanos: 0}, false}, + {&durpb.Duration{Seconds: 1, Nanos: -1}, true}, + {&durpb.Duration{Seconds: -1, Nanos: 1}, true}, + {&durpb.Duration{Seconds: 315576000001}, true}, + {&durpb.Duration{Seconds: -315576000001}, true}, + {&durpb.Duration{Seconds: 1, Nanos: 1000000000}, true}, + {&durpb.Duration{Seconds: -1, Nanos: -1000000000}, true}, + {&tspb.Timestamp{Seconds: 1, Nanos: 1}, false}, + {&tspb.Timestamp{Seconds: 1, Nanos: -1}, true}, + {&tspb.Timestamp{Seconds: 1, Nanos: 1000000000}, true}, + } + for _, tt := range tests { + _, err := marshaler.MarshalToString(tt.pb) + if err == nil && tt.fail { + t.Errorf("marshaler.MarshalToString(%v) = _, ; want _, ", tt.pb) + } + if err != nil && !tt.fail { + t.Errorf("marshaler.MarshalToString(%v) = _, %v; want _, ", tt.pb, err) + } + } +} + +func TestMarshalJSONPBMarshaler(t *testing.T) { + rawJson := `{ "foo": "bar", "baz": [0, 1, 2, 3] }` + msg := dynamicMessage{RawJson: rawJson} + str, err := new(Marshaler).MarshalToString(&msg) + if err != nil { + t.Errorf("an unexpected error while marshaling JSONPBMarshaler: %v", err) + } + if str != rawJson { + t.Errorf("marshaling JSON produced incorrect output: got %s, wanted %s", str, rawJson) + } +} + +func TestMarshalAnyJSONPBMarshaler(t *testing.T) { + msg := dynamicMessage{RawJson: `{ "foo": "bar", "baz": [0, 1, 2, 3] }`} + a, err := ptypes.MarshalAny(&msg) + if err != nil { + t.Errorf("an unexpected error while marshaling to Any: %v", err) + } + str, err := new(Marshaler).MarshalToString(a) + if err != nil { + t.Errorf("an unexpected error while marshaling Any to JSON: %v", err) + } + // after custom marshaling, it's round-tripped through JSON decoding/encoding already, + // so the keys are sorted, whitespace is compacted, and "@type" key has been added + want := `{"@type":"type.googleapis.com/` + dynamicMessageName + `","baz":[0,1,2,3],"foo":"bar"}` + if str != want { + t.Errorf("marshaling JSON produced incorrect output: got %s, wanted %s", str, want) + } +} + +func TestMarshalWithCustomValidation(t *testing.T) { + msg := dynamicMessage{RawJson: `{ "foo": "bar", "baz": [0, 1, 2, 3] }`, Dummy: &dynamicMessage{}} + + js, err := new(Marshaler).MarshalToString(&msg) + if err != nil { + t.Errorf("an unexpected error while marshaling to json: %v", err) + } + err = Unmarshal(strings.NewReader(js), &msg) + if err != nil { + t.Errorf("an unexpected error while unmarshaling from json: %v", err) + } +} + +// Test marshaling message containing unset required fields should produce error. +func TestMarshalUnsetRequiredFields(t *testing.T) { + msgExt := &pb2.Real{} + proto.SetExtension(msgExt, pb2.E_Extm, &pb2.MsgWithRequired{}) + + tests := []struct { + desc string + marshaler *Marshaler + pb proto.Message + }{ + { + desc: "direct required field", + marshaler: &Marshaler{}, + pb: &pb2.MsgWithRequired{}, + }, + { + desc: "direct required field + emit defaults", + marshaler: &Marshaler{EmitDefaults: true}, + pb: &pb2.MsgWithRequired{}, + }, + { + desc: "indirect required field", + marshaler: &Marshaler{}, + pb: &pb2.MsgWithIndirectRequired{Subm: &pb2.MsgWithRequired{}}, + }, + { + desc: "indirect required field + emit defaults", + marshaler: &Marshaler{EmitDefaults: true}, + pb: &pb2.MsgWithIndirectRequired{Subm: &pb2.MsgWithRequired{}}, + }, + { + desc: "direct required wkt field", + marshaler: &Marshaler{}, + pb: &pb2.MsgWithRequiredWKT{}, + }, + { + desc: "direct required wkt field + emit defaults", + marshaler: &Marshaler{EmitDefaults: true}, + pb: &pb2.MsgWithRequiredWKT{}, + }, + { + desc: "direct required bytes field", + marshaler: &Marshaler{}, + pb: &pb2.MsgWithRequiredBytes{}, + }, + { + desc: "required in map value", + marshaler: &Marshaler{}, + pb: &pb2.MsgWithIndirectRequired{ + MapField: map[string]*pb2.MsgWithRequired{ + "key": {}, + }, + }, + }, + { + desc: "required in repeated item", + marshaler: &Marshaler{}, + pb: &pb2.MsgWithIndirectRequired{ + SliceField: []*pb2.MsgWithRequired{ + {Str: proto.String("hello")}, + {}, + }, + }, + }, + { + desc: "required inside oneof", + marshaler: &Marshaler{}, + pb: &pb2.MsgWithOneof{ + Union: &pb2.MsgWithOneof_MsgWithRequired{&pb2.MsgWithRequired{}}, + }, + }, + { + desc: "required inside extension", + marshaler: &Marshaler{}, + pb: msgExt, + }, + } + + for _, tc := range tests { + if _, err := tc.marshaler.MarshalToString(tc.pb); err == nil { + t.Errorf("%s: expected error while marshaling with unset required fields %+v", tc.desc, tc.pb) + } + } +} + +var unmarshalingTests = []struct { + desc string + unmarshaler Unmarshaler + json string + pb proto.Message +}{ + {"simple flat object", Unmarshaler{}, simpleObjectInputJSON, simpleObject}, + {"simple pretty object", Unmarshaler{}, simpleObjectInputPrettyJSON, simpleObject}, + {"repeated fields flat object", Unmarshaler{}, repeatsObjectJSON, repeatsObject}, + {"repeated fields pretty object", Unmarshaler{}, repeatsObjectPrettyJSON, repeatsObject}, + {"nested message/enum flat object", Unmarshaler{}, complexObjectJSON, complexObject}, + {"nested message/enum pretty object", Unmarshaler{}, complexObjectPrettyJSON, complexObject}, + {"enum-string object", Unmarshaler{}, `{"color":"BLUE"}`, &pb2.Widget{Color: pb2.Widget_BLUE.Enum()}}, + {"enum-value object", Unmarshaler{}, "{\n \"color\": 2\n}", &pb2.Widget{Color: pb2.Widget_BLUE.Enum()}}, + {"unknown field with allowed option", Unmarshaler{AllowUnknownFields: true}, `{"unknown": "foo"}`, new(pb2.Simple)}, + {"proto3 enum string", Unmarshaler{}, `{"hilarity":"PUNS"}`, &pb3.Message{Hilarity: pb3.Message_PUNS}}, + {"proto3 enum value", Unmarshaler{}, `{"hilarity":1}`, &pb3.Message{Hilarity: pb3.Message_PUNS}}, + {"unknown enum value object", + Unmarshaler{}, + "{\n \"color\": 1000,\n \"r_color\": [\n \"RED\"\n ]\n}", + &pb2.Widget{Color: pb2.Widget_Color(1000).Enum(), RColor: []pb2.Widget_Color{pb2.Widget_RED}}}, + {"repeated proto3 enum", Unmarshaler{}, `{"rFunny":["PUNS","SLAPSTICK"]}`, + &pb3.Message{RFunny: []pb3.Message_Humour{ + pb3.Message_PUNS, + pb3.Message_SLAPSTICK, + }}}, + {"repeated proto3 enum as int", Unmarshaler{}, `{"rFunny":[1,2]}`, + &pb3.Message{RFunny: []pb3.Message_Humour{ + pb3.Message_PUNS, + pb3.Message_SLAPSTICK, + }}}, + {"repeated proto3 enum as mix of strings and ints", Unmarshaler{}, `{"rFunny":["PUNS",2]}`, + &pb3.Message{RFunny: []pb3.Message_Humour{ + pb3.Message_PUNS, + pb3.Message_SLAPSTICK, + }}}, + {"unquoted int64 object", Unmarshaler{}, `{"oInt64":-314}`, &pb2.Simple{OInt64: proto.Int64(-314)}}, + {"unquoted uint64 object", Unmarshaler{}, `{"oUint64":123}`, &pb2.Simple{OUint64: proto.Uint64(123)}}, + {"NaN", Unmarshaler{}, `{"oDouble":"NaN"}`, &pb2.Simple{ODouble: proto.Float64(math.NaN())}}, + {"Inf", Unmarshaler{}, `{"oFloat":"Infinity"}`, &pb2.Simple{OFloat: proto.Float32(float32(math.Inf(1)))}}, + {"-Inf", Unmarshaler{}, `{"oDouble":"-Infinity"}`, &pb2.Simple{ODouble: proto.Float64(math.Inf(-1))}}, + {"map", Unmarshaler{}, `{"nummy":{"1":2,"3":4}}`, &pb2.Mappy{Nummy: map[int64]int32{1: 2, 3: 4}}}, + {"map", Unmarshaler{}, `{"strry":{"\"one\"":"two","three":"four"}}`, &pb2.Mappy{Strry: map[string]string{`"one"`: "two", "three": "four"}}}, + {"map", Unmarshaler{}, `{"objjy":{"1":{"dub":1}}}`, &pb2.Mappy{Objjy: map[int32]*pb2.Simple3{1: {Dub: 1}}}}, + {"proto2 extension", Unmarshaler{}, realNumberJSON, realNumber}, + {"Any with message", Unmarshaler{}, anySimpleJSON, anySimple}, + {"Any with message and indent", Unmarshaler{}, anySimplePrettyJSON, anySimple}, + {"Any with WKT", Unmarshaler{}, anyWellKnownJSON, anyWellKnown}, + {"Any with WKT and indent", Unmarshaler{}, anyWellKnownPrettyJSON, anyWellKnown}, + {"map", Unmarshaler{}, `{"enumy":{"XIV":"ROMAN"}}`, &pb2.Mappy{Enumy: map[string]pb2.Numeral{"XIV": pb2.Numeral_ROMAN}}}, + {"map", Unmarshaler{}, `{"enumy":{"XIV":2}}`, &pb2.Mappy{Enumy: map[string]pb2.Numeral{"XIV": pb2.Numeral_ROMAN}}}, + {"oneof", Unmarshaler{}, `{"salary":31000}`, &pb2.MsgWithOneof{Union: &pb2.MsgWithOneof_Salary{31000}}}, + {"oneof spec name", Unmarshaler{}, `{"Country":"Australia"}`, &pb2.MsgWithOneof{Union: &pb2.MsgWithOneof_Country{"Australia"}}}, + {"oneof orig_name", Unmarshaler{}, `{"Country":"Australia"}`, &pb2.MsgWithOneof{Union: &pb2.MsgWithOneof_Country{"Australia"}}}, + {"oneof spec name2", Unmarshaler{}, `{"homeAddress":"Australia"}`, &pb2.MsgWithOneof{Union: &pb2.MsgWithOneof_HomeAddress{"Australia"}}}, + {"oneof orig_name2", Unmarshaler{}, `{"home_address":"Australia"}`, &pb2.MsgWithOneof{Union: &pb2.MsgWithOneof_HomeAddress{"Australia"}}}, + {"oneof NullValue", Unmarshaler{}, `{"nullValue":null}`, &pb2.MsgWithOneof{Union: &pb2.MsgWithOneof_NullValue{stpb.NullValue_NULL_VALUE}}}, + {"orig_name input", Unmarshaler{}, `{"o_bool":true}`, &pb2.Simple{OBool: proto.Bool(true)}}, + {"camelName input", Unmarshaler{}, `{"oBool":true}`, &pb2.Simple{OBool: proto.Bool(true)}}, + + {"Duration", Unmarshaler{}, `{"dur":"3.000s"}`, &pb2.KnownTypes{Dur: &durpb.Duration{Seconds: 3}}}, + {"Duration", Unmarshaler{}, `{"dur":"4s"}`, &pb2.KnownTypes{Dur: &durpb.Duration{Seconds: 4}}}, + {"Duration with unicode", Unmarshaler{}, `{"dur": "3\u0073"}`, &pb2.KnownTypes{Dur: &durpb.Duration{Seconds: 3}}}, + {"null Duration", Unmarshaler{}, `{"dur":null}`, &pb2.KnownTypes{Dur: nil}}, + {"Timestamp", Unmarshaler{}, `{"ts":"2014-05-13T16:53:20.021Z"}`, &pb2.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 21e6}}}, + {"Timestamp", Unmarshaler{}, `{"ts":"2014-05-13T16:53:20Z"}`, &pb2.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 0}}}, + {"Timestamp with unicode", Unmarshaler{}, `{"ts": "2014-05-13T16:53:20\u005a"}`, &pb2.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 0}}}, + {"PreEpochTimestamp", Unmarshaler{}, `{"ts":"1969-12-31T23:59:58.999999995Z"}`, &pb2.KnownTypes{Ts: &tspb.Timestamp{Seconds: -2, Nanos: 999999995}}}, + {"ZeroTimeTimestamp", Unmarshaler{}, `{"ts":"0001-01-01T00:00:00Z"}`, &pb2.KnownTypes{Ts: &tspb.Timestamp{Seconds: -62135596800, Nanos: 0}}}, + {"null Timestamp", Unmarshaler{}, `{"ts":null}`, &pb2.KnownTypes{Ts: nil}}, + {"null Struct", Unmarshaler{}, `{"st": null}`, &pb2.KnownTypes{St: nil}}, + {"empty Struct", Unmarshaler{}, `{"st": {}}`, &pb2.KnownTypes{St: &stpb.Struct{}}}, + {"basic Struct", Unmarshaler{}, `{"st": {"a": "x", "b": null, "c": 3, "d": true}}`, &pb2.KnownTypes{St: &stpb.Struct{Fields: map[string]*stpb.Value{ + "a": {Kind: &stpb.Value_StringValue{"x"}}, + "b": {Kind: &stpb.Value_NullValue{}}, + "c": {Kind: &stpb.Value_NumberValue{3}}, + "d": {Kind: &stpb.Value_BoolValue{true}}, + }}}}, + {"nested Struct", Unmarshaler{}, `{"st": {"a": {"b": 1, "c": [{"d": true}, "f"]}}}`, &pb2.KnownTypes{St: &stpb.Struct{Fields: map[string]*stpb.Value{ + "a": {Kind: &stpb.Value_StructValue{&stpb.Struct{Fields: map[string]*stpb.Value{ + "b": {Kind: &stpb.Value_NumberValue{1}}, + "c": {Kind: &stpb.Value_ListValue{&stpb.ListValue{Values: []*stpb.Value{ + {Kind: &stpb.Value_StructValue{&stpb.Struct{Fields: map[string]*stpb.Value{"d": {Kind: &stpb.Value_BoolValue{true}}}}}}, + {Kind: &stpb.Value_StringValue{"f"}}, + }}}}, + }}}}, + }}}}, + {"null ListValue", Unmarshaler{}, `{"lv": null}`, &pb2.KnownTypes{Lv: nil}}, + {"empty ListValue", Unmarshaler{}, `{"lv": []}`, &pb2.KnownTypes{Lv: &stpb.ListValue{}}}, + {"basic ListValue", Unmarshaler{}, `{"lv": ["x", null, 3, true]}`, &pb2.KnownTypes{Lv: &stpb.ListValue{Values: []*stpb.Value{ + {Kind: &stpb.Value_StringValue{"x"}}, + {Kind: &stpb.Value_NullValue{}}, + {Kind: &stpb.Value_NumberValue{3}}, + {Kind: &stpb.Value_BoolValue{true}}, + }}}}, + {"number Value", Unmarshaler{}, `{"val":1}`, &pb2.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_NumberValue{1}}}}, + {"null Value", Unmarshaler{}, `{"val":null}`, &pb2.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_NullValue{stpb.NullValue_NULL_VALUE}}}}, + {"bool Value", Unmarshaler{}, `{"val":true}`, &pb2.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_BoolValue{true}}}}, + {"string Value", Unmarshaler{}, `{"val":"x"}`, &pb2.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_StringValue{"x"}}}}, + {"string number value", Unmarshaler{}, `{"val":"9223372036854775807"}`, &pb2.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_StringValue{"9223372036854775807"}}}}, + {"list of lists Value", Unmarshaler{}, `{"val":["x", [["y"], "z"]]}`, &pb2.KnownTypes{Val: &stpb.Value{ + Kind: &stpb.Value_ListValue{&stpb.ListValue{ + Values: []*stpb.Value{ + {Kind: &stpb.Value_StringValue{"x"}}, + {Kind: &stpb.Value_ListValue{&stpb.ListValue{ + Values: []*stpb.Value{ + {Kind: &stpb.Value_ListValue{&stpb.ListValue{ + Values: []*stpb.Value{{Kind: &stpb.Value_StringValue{"y"}}}, + }}}, + {Kind: &stpb.Value_StringValue{"z"}}, + }, + }}}, + }, + }}}}}, + + {"DoubleValue", Unmarshaler{}, `{"dbl":1.2}`, &pb2.KnownTypes{Dbl: &wpb.DoubleValue{Value: 1.2}}}, + {"FloatValue", Unmarshaler{}, `{"flt":1.2}`, &pb2.KnownTypes{Flt: &wpb.FloatValue{Value: 1.2}}}, + {"Int64Value", Unmarshaler{}, `{"i64":"-3"}`, &pb2.KnownTypes{I64: &wpb.Int64Value{Value: -3}}}, + {"UInt64Value", Unmarshaler{}, `{"u64":"3"}`, &pb2.KnownTypes{U64: &wpb.UInt64Value{Value: 3}}}, + {"Int32Value", Unmarshaler{}, `{"i32":-4}`, &pb2.KnownTypes{I32: &wpb.Int32Value{Value: -4}}}, + {"UInt32Value", Unmarshaler{}, `{"u32":4}`, &pb2.KnownTypes{U32: &wpb.UInt32Value{Value: 4}}}, + {"BoolValue", Unmarshaler{}, `{"bool":true}`, &pb2.KnownTypes{Bool: &wpb.BoolValue{Value: true}}}, + {"StringValue", Unmarshaler{}, `{"str":"plush"}`, &pb2.KnownTypes{Str: &wpb.StringValue{Value: "plush"}}}, + {"StringValue containing escaped character", Unmarshaler{}, `{"str":"a\/b"}`, &pb2.KnownTypes{Str: &wpb.StringValue{Value: "a/b"}}}, + {"StructValue containing StringValue's", Unmarshaler{}, `{"escaped": "a\/b", "unicode": "\u00004E16\u0000754C"}`, + &stpb.Struct{ + Fields: map[string]*stpb.Value{ + "escaped": {Kind: &stpb.Value_StringValue{"a/b"}}, + "unicode": {Kind: &stpb.Value_StringValue{"\u00004E16\u0000754C"}}, + }, + }}, + {"BytesValue", Unmarshaler{}, `{"bytes":"d293"}`, &pb2.KnownTypes{Bytes: &wpb.BytesValue{Value: []byte("wow")}}}, + + // Ensure that `null` as a value ends up with a nil pointer instead of a [type]Value struct. + {"null DoubleValue", Unmarshaler{}, `{"dbl":null}`, &pb2.KnownTypes{Dbl: nil}}, + {"null FloatValue", Unmarshaler{}, `{"flt":null}`, &pb2.KnownTypes{Flt: nil}}, + {"null Int64Value", Unmarshaler{}, `{"i64":null}`, &pb2.KnownTypes{I64: nil}}, + {"null UInt64Value", Unmarshaler{}, `{"u64":null}`, &pb2.KnownTypes{U64: nil}}, + {"null Int32Value", Unmarshaler{}, `{"i32":null}`, &pb2.KnownTypes{I32: nil}}, + {"null UInt32Value", Unmarshaler{}, `{"u32":null}`, &pb2.KnownTypes{U32: nil}}, + {"null BoolValue", Unmarshaler{}, `{"bool":null}`, &pb2.KnownTypes{Bool: nil}}, + {"null StringValue", Unmarshaler{}, `{"str":null}`, &pb2.KnownTypes{Str: nil}}, + {"null BytesValue", Unmarshaler{}, `{"bytes":null}`, &pb2.KnownTypes{Bytes: nil}}, + + {"required", Unmarshaler{}, `{"str":"hello"}`, &pb2.MsgWithRequired{Str: proto.String("hello")}}, + {"required bytes", Unmarshaler{}, `{"byts": []}`, &pb2.MsgWithRequiredBytes{Byts: []byte{}}}, +} + +func TestUnmarshaling(t *testing.T) { + for _, tt := range unmarshalingTests { + // Make a new instance of the type of our wanted object. + p := reflect.New(reflect.TypeOf(tt.pb).Elem()).Interface().(proto.Message) + + err := tt.unmarshaler.Unmarshal(strings.NewReader(tt.json), p) + if err != nil { + t.Errorf("unmarshaling %s: %v", tt.desc, err) + continue + } + + // For easier diffs, compare text strings of the protos. + exp := proto.MarshalTextString(tt.pb) + act := proto.MarshalTextString(p) + if string(exp) != string(act) { + t.Errorf("%s: got [%s] want [%s]", tt.desc, act, exp) + } + } +} + +func TestUnmarshalNullArray(t *testing.T) { + var repeats pb2.Repeats + if err := UnmarshalString(`{"rBool":null}`, &repeats); err != nil { + t.Fatal(err) + } + if !proto.Equal(&repeats, &pb2.Repeats{}) { + t.Errorf("got non-nil fields in [%#v]", repeats) + } +} + +func TestUnmarshalNullObject(t *testing.T) { + var maps pb2.Maps + if err := UnmarshalString(`{"mInt64Str":null}`, &maps); err != nil { + t.Fatal(err) + } + if !proto.Equal(&maps, &pb2.Maps{}) { + t.Errorf("got non-nil fields in [%#v]", maps) + } +} + +func TestUnmarshalNext(t *testing.T) { + // We only need to check against a few, not all of them. + tests := unmarshalingTests[:5] + + // Create a buffer with many concatenated JSON objects. + var b bytes.Buffer + for _, tt := range tests { + b.WriteString(tt.json) + } + + dec := json.NewDecoder(&b) + for _, tt := range tests { + // Make a new instance of the type of our wanted object. + p := reflect.New(reflect.TypeOf(tt.pb).Elem()).Interface().(proto.Message) + + err := tt.unmarshaler.UnmarshalNext(dec, p) + if err != nil { + t.Errorf("%s: %v", tt.desc, err) + continue + } + + // For easier diffs, compare text strings of the protos. + exp := proto.MarshalTextString(tt.pb) + act := proto.MarshalTextString(p) + if string(exp) != string(act) { + t.Errorf("%s: got [%s] want [%s]", tt.desc, act, exp) + } + } + + p := &pb2.Simple{} + err := new(Unmarshaler).UnmarshalNext(dec, p) + if err != io.EOF { + t.Errorf("eof: got %v, want io.EOF", err) + } +} + +var unmarshalingShouldError = []struct { + desc string + in string + pb proto.Message +}{ + {"a value", "666", new(pb2.Simple)}, + {"gibberish", "{adskja123;l23=-=", new(pb2.Simple)}, + {"unknown field", `{"unknown": "foo"}`, new(pb2.Simple)}, + {"unknown enum name", `{"hilarity":"DAVE"}`, new(pb3.Message)}, + {"Duration containing invalid character", `{"dur": "3\U0073"}`, &pb2.KnownTypes{}}, + {"Timestamp containing invalid character", `{"ts": "2014-05-13T16:53:20\U005a"}`, &pb2.KnownTypes{}}, + {"StringValue containing invalid character", `{"str": "\U00004E16\U0000754C"}`, &pb2.KnownTypes{}}, + {"StructValue containing invalid character", `{"str": "\U00004E16\U0000754C"}`, &stpb.Struct{}}, + {"repeated proto3 enum with non array input", `{"rFunny":"PUNS"}`, &pb3.Message{RFunny: []pb3.Message_Humour{}}}, + {"unknown extension field", `{"[ext_unknown]": "value"}`, &pb2.Real{}}, + {"extension field for wrong message", `{"[jsonpb_test.name]": "value"}`, &pb2.Complex{}}, +} + +func TestUnmarshalingBadInput(t *testing.T) { + for _, tt := range unmarshalingShouldError { + err := UnmarshalString(tt.in, tt.pb) + if err == nil { + t.Errorf("expected error while parsing %q", tt.desc) + } + } +} + +type funcResolver func(turl string) (proto.Message, error) + +func (fn funcResolver) Resolve(turl string) (proto.Message, error) { + return fn(turl) +} + +func TestAnyWithCustomResolver(t *testing.T) { + var resolvedTypeUrls []string + resolver := funcResolver(func(turl string) (proto.Message, error) { + resolvedTypeUrls = append(resolvedTypeUrls, turl) + return new(pb2.Simple), nil + }) + msg := &pb2.Simple{ + OBytes: []byte{1, 2, 3, 4}, + OBool: proto.Bool(true), + OString: proto.String("foobar"), + OInt64: proto.Int64(1020304), + } + msgBytes, err := proto.Marshal(msg) + if err != nil { + t.Errorf("an unexpected error while marshaling message: %v", err) + } + // make an Any with a type URL that won't resolve w/out custom resolver + any := &anypb.Any{ + TypeUrl: "https://foobar.com/some.random.MessageKind", + Value: msgBytes, + } + + m := Marshaler{AnyResolver: resolver} + js, err := m.MarshalToString(any) + if err != nil { + t.Errorf("an unexpected error while marshaling any to JSON: %v", err) + } + if len(resolvedTypeUrls) != 1 { + t.Errorf("custom resolver was not invoked during marshaling") + } else if resolvedTypeUrls[0] != "https://foobar.com/some.random.MessageKind" { + t.Errorf("custom resolver was invoked with wrong URL: got %q, wanted %q", resolvedTypeUrls[0], "https://foobar.com/some.random.MessageKind") + } + wanted := `{"@type":"https://foobar.com/some.random.MessageKind","oBool":true,"oInt64":"1020304","oString":"foobar","oBytes":"AQIDBA=="}` + if js != wanted { + t.Errorf("marshaling JSON produced incorrect output: got %s, wanted %s", js, wanted) + } + + u := Unmarshaler{AnyResolver: resolver} + roundTrip := &anypb.Any{} + err = u.Unmarshal(bytes.NewReader([]byte(js)), roundTrip) + if err != nil { + t.Errorf("an unexpected error while unmarshaling any from JSON: %v", err) + } + if len(resolvedTypeUrls) != 2 { + t.Errorf("custom resolver was not invoked during marshaling") + } else if resolvedTypeUrls[1] != "https://foobar.com/some.random.MessageKind" { + t.Errorf("custom resolver was invoked with wrong URL: got %q, wanted %q", resolvedTypeUrls[1], "https://foobar.com/some.random.MessageKind") + } + if !proto.Equal(any, roundTrip) { + t.Errorf("message contents not set correctly after unmarshaling JSON: got %s, wanted %s", roundTrip, any) + } +} + +func TestUnmarshalJSONPBUnmarshaler(t *testing.T) { + rawJson := `{ "foo": "bar", "baz": [0, 1, 2, 3] }` + var msg dynamicMessage + if err := Unmarshal(strings.NewReader(rawJson), &msg); err != nil { + t.Errorf("an unexpected error while parsing into JSONPBUnmarshaler: %v", err) + } + if msg.RawJson != rawJson { + t.Errorf("message contents not set correctly after unmarshaling JSON: got %s, wanted %s", msg.RawJson, rawJson) + } +} + +func TestUnmarshalNullWithJSONPBUnmarshaler(t *testing.T) { + rawJson := `{"stringField":null}` + var ptrFieldMsg ptrFieldMessage + if err := Unmarshal(strings.NewReader(rawJson), &ptrFieldMsg); err != nil { + t.Errorf("unmarshal error: %v", err) + } + + want := ptrFieldMessage{StringField: &stringField{IsSet: true, StringValue: "null"}} + if !proto.Equal(&ptrFieldMsg, &want) { + t.Errorf("unmarshal result StringField: got %v, want %v", ptrFieldMsg, want) + } +} + +func TestUnmarshalAnyJSONPBUnmarshaler(t *testing.T) { + rawJson := `{ "@type": "blah.com/` + dynamicMessageName + `", "foo": "bar", "baz": [0, 1, 2, 3] }` + var got anypb.Any + if err := Unmarshal(strings.NewReader(rawJson), &got); err != nil { + t.Errorf("an unexpected error while parsing into JSONPBUnmarshaler: %v", err) + } + + dm := &dynamicMessage{RawJson: `{"baz":[0,1,2,3],"foo":"bar"}`} + var want anypb.Any + if b, err := proto.Marshal(dm); err != nil { + t.Errorf("an unexpected error while marshaling message: %v", err) + } else { + want.TypeUrl = "blah.com/" + dynamicMessageName + want.Value = b + } + + if !proto.Equal(&got, &want) { + t.Errorf("message contents not set correctly after unmarshaling JSON: got %v, wanted %v", &got, &want) + } +} + +const ( + dynamicMessageName = "github_com.golang.protobuf.jsonpb.dynamicMessage" +) + +func init() { + // we register the custom type below so that we can use it in Any types + proto.RegisterType((*dynamicMessage)(nil), dynamicMessageName) +} + +type ptrFieldMessage struct { + StringField *stringField `protobuf:"bytes,1,opt,name=stringField"` +} + +func (m *ptrFieldMessage) Reset() { +} + +func (m *ptrFieldMessage) String() string { + return m.StringField.StringValue +} + +func (m *ptrFieldMessage) ProtoMessage() { +} + +func (m *ptrFieldMessage) Descriptor() ([]byte, []int) { + return testMessageFD, []int{0} +} + +type stringField struct { + IsSet bool `protobuf:"varint,1,opt,name=isSet"` + StringValue string `protobuf:"bytes,2,opt,name=stringValue"` +} + +func (s *stringField) Reset() { +} + +func (s *stringField) String() string { + return s.StringValue +} + +func (s *stringField) ProtoMessage() { +} + +func (s *stringField) Descriptor() ([]byte, []int) { + return testMessageFD, []int{1} +} + +func (s *stringField) UnmarshalJSONPB(jum *Unmarshaler, js []byte) error { + s.IsSet = true + s.StringValue = string(js) + return nil +} + +// dynamicMessage implements protobuf.Message but is not a normal generated message type. +// It provides implementations of JSONPBMarshaler and JSONPBUnmarshaler for JSON support. +type dynamicMessage struct { + RawJson string `protobuf:"bytes,1,opt,name=rawJson"` + + // an unexported nested message is present just to ensure that it + // won't result in a panic (see issue #509) + Dummy *dynamicMessage `protobuf:"bytes,2,opt,name=dummy"` +} + +func (m *dynamicMessage) Reset() { + m.RawJson = "{}" +} + +func (m *dynamicMessage) String() string { + return m.RawJson +} + +func (m *dynamicMessage) ProtoMessage() { +} + +func (m *dynamicMessage) Descriptor() ([]byte, []int) { + return testMessageFD, []int{2} +} + +func (m *dynamicMessage) MarshalJSONPB(jm *Marshaler) ([]byte, error) { + return []byte(m.RawJson), nil +} + +func (m *dynamicMessage) UnmarshalJSONPB(jum *Unmarshaler, js []byte) error { + m.RawJson = string(js) + return nil +} + +var testMessageFD = func() []byte { + fd := new(descpb.FileDescriptorProto) + proto.UnmarshalText(` + name: "jsonpb.proto" + package: "github_com.golang.protobuf.jsonpb" + syntax: "proto3" + message_type: [{ + name: "ptrFieldMessage" + field: [ + {name:"stringField" number:1 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".github_com.golang.protobuf.jsonpb.stringField"} + ] + }, { + name: "stringField" + field: [ + {name:"isSet" number:1 label:LABEL_OPTIONAL type:TYPE_BOOL}, + {name:"stringValue" number:2 label:LABEL_OPTIONAL type:TYPE_STRING} + ] + }, { + name: "dynamicMessage" + field: [ + {name:"rawJson" number:1 label:LABEL_OPTIONAL type:TYPE_BYTES}, + {name:"dummy" number:2 label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".github_com.golang.protobuf.jsonpb.dynamicMessage"} + ] + }] + `, fd) + b, _ := proto.Marshal(fd) + var buf bytes.Buffer + zw := gzip.NewWriter(&buf) + zw.Write(b) + zw.Close() + return buf.Bytes() +}() + +// Test unmarshaling message containing unset required fields should produce error. +func TestUnmarshalUnsetRequiredFields(t *testing.T) { + tests := []struct { + desc string + pb proto.Message + json string + }{ + { + desc: "direct required field missing", + pb: &pb2.MsgWithRequired{}, + json: `{}`, + }, + { + desc: "direct required field set to null", + pb: &pb2.MsgWithRequired{}, + json: `{"str": null}`, + }, + { + desc: "indirect required field missing", + pb: &pb2.MsgWithIndirectRequired{}, + json: `{"subm": {}}`, + }, + { + desc: "indirect required field set to null", + pb: &pb2.MsgWithIndirectRequired{}, + json: `{"subm": {"str": null}}`, + }, + { + desc: "direct required bytes field missing", + pb: &pb2.MsgWithRequiredBytes{}, + json: `{}`, + }, + { + desc: "direct required bytes field set to null", + pb: &pb2.MsgWithRequiredBytes{}, + json: `{"byts": null}`, + }, + { + desc: "direct required wkt field missing", + pb: &pb2.MsgWithRequiredWKT{}, + json: `{}`, + }, + { + desc: "direct required wkt field set to null", + pb: &pb2.MsgWithRequiredWKT{}, + json: `{"str": null}`, + }, + { + desc: "any containing message with required field set to null", + pb: &pb2.KnownTypes{}, + json: `{"an": {"@type": "example.com/jsonpb.MsgWithRequired", "str": null}}`, + }, + { + desc: "any containing message with missing required field", + pb: &pb2.KnownTypes{}, + json: `{"an": {"@type": "example.com/jsonpb.MsgWithRequired"}}`, + }, + { + desc: "missing required in map value", + pb: &pb2.MsgWithIndirectRequired{}, + json: `{"map_field": {"a": {}, "b": {"str": "hi"}}}`, + }, + { + desc: "required in map value set to null", + pb: &pb2.MsgWithIndirectRequired{}, + json: `{"map_field": {"a": {"str": "hello"}, "b": {"str": null}}}`, + }, + { + desc: "missing required in slice item", + pb: &pb2.MsgWithIndirectRequired{}, + json: `{"slice_field": [{}, {"str": "hi"}]}`, + }, + { + desc: "required in slice item set to null", + pb: &pb2.MsgWithIndirectRequired{}, + json: `{"slice_field": [{"str": "hello"}, {"str": null}]}`, + }, + { + desc: "required inside oneof missing", + pb: &pb2.MsgWithOneof{}, + json: `{"msgWithRequired": {}}`, + }, + { + desc: "required inside oneof set to null", + pb: &pb2.MsgWithOneof{}, + json: `{"msgWithRequired": {"str": null}}`, + }, + { + desc: "required field in extension missing", + pb: &pb2.Real{}, + json: `{"[jsonpb.extm]":{}}`, + }, + { + desc: "required field in extension set to null", + pb: &pb2.Real{}, + json: `{"[jsonpb.extm]":{"str": null}}`, + }, + } + + for _, tc := range tests { + if err := UnmarshalString(tc.json, tc.pb); err == nil { + t.Errorf("%s: expected error while unmarshaling with unset required fields %s", tc.desc, tc.json) + } + } +} diff --git a/pkg/golang-protobuf/proto/buffer.go b/pkg/golang-protobuf/proto/buffer.go new file mode 100644 index 000000000..e810e6fea --- /dev/null +++ b/pkg/golang-protobuf/proto/buffer.go @@ -0,0 +1,324 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +import ( + "errors" + "fmt" + + "google.golang.org/protobuf/encoding/prototext" + "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + WireVarint = 0 + WireFixed32 = 5 + WireFixed64 = 1 + WireBytes = 2 + WireStartGroup = 3 + WireEndGroup = 4 +) + +// EncodeVarint returns the varint encoded bytes of v. +func EncodeVarint(v uint64) []byte { + return protowire.AppendVarint(nil, v) +} + +// SizeVarint returns the length of the varint encoded bytes of v. +// This is equal to len(EncodeVarint(v)). +func SizeVarint(v uint64) int { + return protowire.SizeVarint(v) +} + +// DecodeVarint parses a varint encoded integer from b, +// returning the integer value and the length of the varint. +// It returns (0, 0) if there is a parse error. +func DecodeVarint(b []byte) (uint64, int) { + v, n := protowire.ConsumeVarint(b) + if n < 0 { + return 0, 0 + } + return v, n +} + +// Buffer is a buffer for encoding and decoding the protobuf wire format. +// It may be reused between invocations to reduce memory usage. +type Buffer struct { + buf []byte + idx int + deterministic bool +} + +// NewBuffer allocates a new Buffer initialized with buf, +// where the contents of buf are considered the unread portion of the buffer. +func NewBuffer(buf []byte) *Buffer { + return &Buffer{buf: buf} +} + +// SetDeterministic specifies whether to use deterministic serialization. +// +// Deterministic serialization guarantees that for a given binary, equal +// messages will always be serialized to the same bytes. This implies: +// +// - Repeated serialization of a message will return the same bytes. +// - Different processes of the same binary (which may be executing on +// different machines) will serialize equal messages to the same bytes. +// +// Note that the deterministic serialization is NOT canonical across +// languages. It is not guaranteed to remain stable over time. It is unstable +// across different builds with schema changes due to unknown fields. +// Users who need canonical serialization (e.g., persistent storage in a +// canonical form, fingerprinting, etc.) should define their own +// canonicalization specification and implement their own serializer rather +// than relying on this API. +// +// If deterministic serialization is requested, map entries will be sorted +// by keys in lexographical order. This is an implementation detail and +// subject to change. +func (b *Buffer) SetDeterministic(deterministic bool) { + b.deterministic = deterministic +} + +// SetBuf sets buf as the internal buffer, +// where the contents of buf are considered the unread portion of the buffer. +func (b *Buffer) SetBuf(buf []byte) { + b.buf = buf + b.idx = 0 +} + +// Reset clears the internal buffer of all written and unread data. +func (b *Buffer) Reset() { + b.buf = b.buf[:0] + b.idx = 0 +} + +// Bytes returns the internal buffer. +func (b *Buffer) Bytes() []byte { + return b.buf +} + +// Unread returns the unread portion of the buffer. +func (b *Buffer) Unread() []byte { + return b.buf[b.idx:] +} + +// Marshal appends the wire-format encoding of m to the buffer. +func (b *Buffer) Marshal(m Message) error { + var err error + b.buf, err = marshalAppend(b.buf, m, b.deterministic) + return err +} + +// Unmarshal parses the wire-format message in the buffer and +// places the decoded results in m. +// It does not reset m before unmarshaling. +func (b *Buffer) Unmarshal(m Message) error { + err := UnmarshalMerge(b.Unread(), m) + b.idx = len(b.buf) + return err +} + +type unknownFields struct{ XXX_unrecognized protoimpl.UnknownFields } + +func (m *unknownFields) String() string { panic("not implemented") } +func (m *unknownFields) Reset() { panic("not implemented") } +func (m *unknownFields) ProtoMessage() { panic("not implemented") } + +// DebugPrint dumps the encoded bytes of b with a header and footer including s +// to stdout. This is only intended for debugging. +func (*Buffer) DebugPrint(s string, b []byte) { + m := MessageReflect(new(unknownFields)) + m.SetUnknown(b) + b, _ = prototext.MarshalOptions{AllowPartial: true, Indent: "\t"}.Marshal(m.Interface()) + fmt.Printf("==== %s ====\n%s==== %s ====\n", s, b, s) +} + +// EncodeVarint appends an unsigned varint encoding to the buffer. +func (b *Buffer) EncodeVarint(v uint64) error { + b.buf = protowire.AppendVarint(b.buf, v) + return nil +} + +// EncodeZigzag32 appends a 32-bit zig-zag varint encoding to the buffer. +func (b *Buffer) EncodeZigzag32(v uint64) error { + return b.EncodeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) +} + +// EncodeZigzag64 appends a 64-bit zig-zag varint encoding to the buffer. +func (b *Buffer) EncodeZigzag64(v uint64) error { + return b.EncodeVarint(uint64((uint64(v) << 1) ^ uint64((int64(v) >> 63)))) +} + +// EncodeFixed32 appends a 32-bit little-endian integer to the buffer. +func (b *Buffer) EncodeFixed32(v uint64) error { + b.buf = protowire.AppendFixed32(b.buf, uint32(v)) + return nil +} + +// EncodeFixed64 appends a 64-bit little-endian integer to the buffer. +func (b *Buffer) EncodeFixed64(v uint64) error { + b.buf = protowire.AppendFixed64(b.buf, uint64(v)) + return nil +} + +// EncodeRawBytes appends a length-prefixed raw bytes to the buffer. +func (b *Buffer) EncodeRawBytes(v []byte) error { + b.buf = protowire.AppendBytes(b.buf, v) + return nil +} + +// EncodeStringBytes appends a length-prefixed raw bytes to the buffer. +// It does not validate whether v contains valid UTF-8. +func (b *Buffer) EncodeStringBytes(v string) error { + b.buf = protowire.AppendString(b.buf, v) + return nil +} + +// EncodeMessage appends a length-prefixed encoded message to the buffer. +func (b *Buffer) EncodeMessage(m Message) error { + var err error + b.buf = protowire.AppendVarint(b.buf, uint64(Size(m))) + b.buf, err = marshalAppend(b.buf, m, b.deterministic) + return err +} + +// DecodeVarint consumes an encoded unsigned varint from the buffer. +func (b *Buffer) DecodeVarint() (uint64, error) { + v, n := protowire.ConsumeVarint(b.buf[b.idx:]) + if n < 0 { + return 0, protowire.ParseError(n) + } + b.idx += n + return uint64(v), nil +} + +// DecodeZigzag32 consumes an encoded 32-bit zig-zag varint from the buffer. +func (b *Buffer) DecodeZigzag32() (uint64, error) { + v, err := b.DecodeVarint() + if err != nil { + return 0, err + } + return uint64((uint32(v) >> 1) ^ uint32((int32(v&1)<<31)>>31)), nil +} + +// DecodeZigzag64 consumes an encoded 64-bit zig-zag varint from the buffer. +func (b *Buffer) DecodeZigzag64() (uint64, error) { + v, err := b.DecodeVarint() + if err != nil { + return 0, err + } + return uint64((uint64(v) >> 1) ^ uint64((int64(v&1)<<63)>>63)), nil +} + +// DecodeFixed32 consumes a 32-bit little-endian integer from the buffer. +func (b *Buffer) DecodeFixed32() (uint64, error) { + v, n := protowire.ConsumeFixed32(b.buf[b.idx:]) + if n < 0 { + return 0, protowire.ParseError(n) + } + b.idx += n + return uint64(v), nil +} + +// DecodeFixed64 consumes a 64-bit little-endian integer from the buffer. +func (b *Buffer) DecodeFixed64() (uint64, error) { + v, n := protowire.ConsumeFixed64(b.buf[b.idx:]) + if n < 0 { + return 0, protowire.ParseError(n) + } + b.idx += n + return uint64(v), nil +} + +// DecodeRawBytes consumes a length-prefixed raw bytes from the buffer. +// If alloc is specified, it returns a copy the raw bytes +// rather than a sub-slice of the buffer. +func (b *Buffer) DecodeRawBytes(alloc bool) ([]byte, error) { + v, n := protowire.ConsumeBytes(b.buf[b.idx:]) + if n < 0 { + return nil, protowire.ParseError(n) + } + b.idx += n + if alloc { + v = append([]byte(nil), v...) + } + return v, nil +} + +// DecodeStringBytes consumes a length-prefixed raw bytes from the buffer. +// It does not validate whether the raw bytes contain valid UTF-8. +func (b *Buffer) DecodeStringBytes() (string, error) { + v, n := protowire.ConsumeString(b.buf[b.idx:]) + if n < 0 { + return "", protowire.ParseError(n) + } + b.idx += n + return v, nil +} + +// DecodeMessage consumes a length-prefixed message from the buffer. +// It does not reset m before unmarshaling. +func (b *Buffer) DecodeMessage(m Message) error { + v, err := b.DecodeRawBytes(false) + if err != nil { + return err + } + return UnmarshalMerge(v, m) +} + +// DecodeGroup consumes a message group from the buffer. +// It assumes that the start group marker has already been consumed and +// consumes all bytes until (and including the end group marker). +// It does not reset m before unmarshaling. +func (b *Buffer) DecodeGroup(m Message) error { + v, n, err := consumeGroup(b.buf[b.idx:]) + if err != nil { + return err + } + b.idx += n + return UnmarshalMerge(v, m) +} + +// consumeGroup parses b until it finds an end group marker, returning +// the raw bytes of the message (excluding the end group marker) and the +// the total length of the message (including the end group marker). +func consumeGroup(b []byte) ([]byte, int, error) { + b0 := b + depth := 1 // assume this follows a start group marker + for { + _, wtyp, tagLen := protowire.ConsumeTag(b) + if tagLen < 0 { + return nil, 0, protowire.ParseError(tagLen) + } + b = b[tagLen:] + + var valLen int + switch wtyp { + case protowire.VarintType: + _, valLen = protowire.ConsumeVarint(b) + case protowire.Fixed32Type: + _, valLen = protowire.ConsumeFixed32(b) + case protowire.Fixed64Type: + _, valLen = protowire.ConsumeFixed64(b) + case protowire.BytesType: + _, valLen = protowire.ConsumeBytes(b) + case protowire.StartGroupType: + depth++ + case protowire.EndGroupType: + depth-- + default: + return nil, 0, errors.New("proto: cannot parse reserved wire type") + } + if valLen < 0 { + return nil, 0, protowire.ParseError(valLen) + } + b = b[valLen:] + + if depth == 0 { + return b0[:len(b0)-len(b)-tagLen], len(b0) - len(b), nil + } + } +} diff --git a/pkg/golang-protobuf/proto/defaults.go b/pkg/golang-protobuf/proto/defaults.go new file mode 100644 index 000000000..d399bf069 --- /dev/null +++ b/pkg/golang-protobuf/proto/defaults.go @@ -0,0 +1,63 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +import ( + "google.golang.org/protobuf/reflect/protoreflect" +) + +// SetDefaults sets unpopulated scalar fields to their default values. +// Fields within a oneof are not set even if they have a default value. +// SetDefaults is recursively called upon any populated message fields. +func SetDefaults(m Message) { + if m != nil { + setDefaults(MessageReflect(m)) + } +} + +func setDefaults(m protoreflect.Message) { + fds := m.Descriptor().Fields() + for i := 0; i < fds.Len(); i++ { + fd := fds.Get(i) + if !m.Has(fd) { + if fd.HasDefault() && fd.ContainingOneof() == nil { + v := fd.Default() + if fd.Kind() == protoreflect.BytesKind { + v = protoreflect.ValueOf(append([]byte(nil), v.Bytes()...)) // copy the default bytes + } + m.Set(fd, v) + } + continue + } + } + + m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + switch { + // Handle singular message. + case fd.Cardinality() != protoreflect.Repeated: + if fd.Message() != nil { + setDefaults(m.Get(fd).Message()) + } + // Handle list of messages. + case fd.IsList(): + if fd.Message() != nil { + ls := m.Get(fd).List() + for i := 0; i < ls.Len(); i++ { + setDefaults(ls.Get(i).Message()) + } + } + // Handle map of messages. + case fd.IsMap(): + if fd.MapValue().Message() != nil { + ms := m.Get(fd).Map() + ms.Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool { + setDefaults(v.Message()) + return true + }) + } + } + return true + }) +} diff --git a/pkg/golang-protobuf/proto/deprecated.go b/pkg/golang-protobuf/proto/deprecated.go new file mode 100644 index 000000000..e8db57e09 --- /dev/null +++ b/pkg/golang-protobuf/proto/deprecated.go @@ -0,0 +1,113 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +import ( + "encoding/json" + "errors" + "fmt" + "strconv" + + protoV2 "google.golang.org/protobuf/proto" +) + +var ( + // Deprecated: No longer returned. + ErrNil = errors.New("proto: Marshal called with nil") + + // Deprecated: No longer returned. + ErrTooLarge = errors.New("proto: message encodes to over 2 GB") + + // Deprecated: No longer returned. + ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") +) + +// Deprecated: Do not use. +type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 } + +// Deprecated: Do not use. +func GetStats() Stats { return Stats{} } + +// Deprecated: Do not use. +func MarshalMessageSet(interface{}) ([]byte, error) { + return nil, errors.New("proto: not implemented") +} + +// Deprecated: Do not use. +func UnmarshalMessageSet([]byte, interface{}) error { + return errors.New("proto: not implemented") +} + +// Deprecated: Do not use. +func MarshalMessageSetJSON(interface{}) ([]byte, error) { + return nil, errors.New("proto: not implemented") +} + +// Deprecated: Do not use. +func UnmarshalMessageSetJSON([]byte, interface{}) error { + return errors.New("proto: not implemented") +} + +// Deprecated: Do not use. +func RegisterMessageSetType(Message, int32, string) {} + +// Deprecated: Do not use. +func EnumName(m map[int32]string, v int32) string { + s, ok := m[v] + if ok { + return s + } + return strconv.Itoa(int(v)) +} + +// Deprecated: Do not use. +func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) { + if data[0] == '"' { + // New style: enums are strings. + var repr string + if err := json.Unmarshal(data, &repr); err != nil { + return -1, err + } + val, ok := m[repr] + if !ok { + return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr) + } + return val, nil + } + // Old style: enums are ints. + var val int32 + if err := json.Unmarshal(data, &val); err != nil { + return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName) + } + return val, nil +} + +// Deprecated: Do not use; this type existed for intenal-use only. +type InternalMessageInfo struct{} + +// Deprecated: Do not use; this method existed for intenal-use only. +func (*InternalMessageInfo) DiscardUnknown(m Message) { + DiscardUnknown(m) +} + +// Deprecated: Do not use; this method existed for intenal-use only. +func (*InternalMessageInfo) Marshal(b []byte, m Message, deterministic bool) ([]byte, error) { + return protoV2.MarshalOptions{Deterministic: deterministic}.MarshalAppend(b, MessageV2(m)) +} + +// Deprecated: Do not use; this method existed for intenal-use only. +func (*InternalMessageInfo) Merge(dst, src Message) { + protoV2.Merge(MessageV2(dst), MessageV2(src)) +} + +// Deprecated: Do not use; this method existed for intenal-use only. +func (*InternalMessageInfo) Size(m Message) int { + return protoV2.Size(MessageV2(m)) +} + +// Deprecated: Do not use; this method existed for intenal-use only. +func (*InternalMessageInfo) Unmarshal(m Message, b []byte) error { + return protoV2.UnmarshalOptions{Merge: true}.Unmarshal(b, MessageV2(m)) +} diff --git a/pkg/golang-protobuf/proto/discard.go b/pkg/golang-protobuf/proto/discard.go new file mode 100644 index 000000000..2187e877f --- /dev/null +++ b/pkg/golang-protobuf/proto/discard.go @@ -0,0 +1,58 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +import ( + "google.golang.org/protobuf/reflect/protoreflect" +) + +// DiscardUnknown recursively discards all unknown fields from this message +// and all embedded messages. +// +// When unmarshaling a message with unrecognized fields, the tags and values +// of such fields are preserved in the Message. This allows a later call to +// marshal to be able to produce a message that continues to have those +// unrecognized fields. To avoid this, DiscardUnknown is used to +// explicitly clear the unknown fields after unmarshaling. +func DiscardUnknown(m Message) { + if m != nil { + discardUnknown(MessageReflect(m)) + } +} + +func discardUnknown(m protoreflect.Message) { + m.Range(func(fd protoreflect.FieldDescriptor, val protoreflect.Value) bool { + switch { + // Handle singular message. + case fd.Cardinality() != protoreflect.Repeated: + if fd.Message() != nil { + discardUnknown(m.Get(fd).Message()) + } + // Handle list of messages. + case fd.IsList(): + if fd.Message() != nil { + ls := m.Get(fd).List() + for i := 0; i < ls.Len(); i++ { + discardUnknown(ls.Get(i).Message()) + } + } + // Handle map of messages. + case fd.IsMap(): + if fd.MapValue().Message() != nil { + ms := m.Get(fd).Map() + ms.Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool { + discardUnknown(v.Message()) + return true + }) + } + } + return true + }) + + // Discard unknown fields. + if len(m.GetUnknown()) > 0 { + m.SetUnknown(nil) + } +} diff --git a/pkg/golang-protobuf/proto/discard_test.go b/pkg/golang-protobuf/proto/discard_test.go new file mode 100644 index 000000000..f850d9dec --- /dev/null +++ b/pkg/golang-protobuf/proto/discard_test.go @@ -0,0 +1,115 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto_test + +import ( + "testing" + + "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/testing/protopack" + + pb2 "github.com/golang/protobuf/internal/testprotos/proto2_proto" + pb3 "github.com/golang/protobuf/internal/testprotos/proto3_proto" +) + +var rawFields = protopack.Message{ + protopack.Tag{5, protopack.Fixed32Type}, protopack.Uint32(4041331395), +}.Marshal() + +func TestDiscardUnknown(t *testing.T) { + tests := []struct { + desc string + in, want proto.Message + }{{ + desc: "Nil", + in: nil, want: nil, // Should not panic + }, { + desc: "NilPtr", + in: (*pb3.Message)(nil), want: (*pb3.Message)(nil), // Should not panic + }, { + desc: "Nested", + in: &pb3.Message{ + Name: "Aaron", + Nested: &pb3.Nested{Cute: true, XXX_unrecognized: []byte(rawFields)}, + XXX_unrecognized: []byte(rawFields), + }, + want: &pb3.Message{ + Name: "Aaron", + Nested: &pb3.Nested{Cute: true}, + }, + }, { + desc: "Slice", + in: &pb3.Message{ + Name: "Aaron", + Children: []*pb3.Message{ + {Name: "Sarah", XXX_unrecognized: []byte(rawFields)}, + {Name: "Abraham", XXX_unrecognized: []byte(rawFields)}, + }, + XXX_unrecognized: []byte(rawFields), + }, + want: &pb3.Message{ + Name: "Aaron", + Children: []*pb3.Message{ + {Name: "Sarah"}, + {Name: "Abraham"}, + }, + }, + }, { + desc: "OneOf", + in: &pb2.Communique{ + Union: &pb2.Communique_Msg{&pb2.Strings{ + StringField: proto.String("123"), + XXX_unrecognized: []byte(rawFields), + }}, + XXX_unrecognized: []byte(rawFields), + }, + want: &pb2.Communique{ + Union: &pb2.Communique_Msg{&pb2.Strings{StringField: proto.String("123")}}, + }, + }, { + desc: "Map", + in: &pb2.MessageWithMap{MsgMapping: map[int64]*pb2.FloatingPoint{ + 0x4002: &pb2.FloatingPoint{ + Exact: proto.Bool(true), + XXX_unrecognized: []byte(rawFields), + }, + }}, + want: &pb2.MessageWithMap{MsgMapping: map[int64]*pb2.FloatingPoint{ + 0x4002: &pb2.FloatingPoint{Exact: proto.Bool(true)}, + }}, + }, { + desc: "Extension", + in: func() proto.Message { + m := &pb2.MyMessage{ + Count: proto.Int32(42), + Somegroup: &pb2.MyMessage_SomeGroup{ + GroupField: proto.Int32(6), + XXX_unrecognized: []byte(rawFields), + }, + XXX_unrecognized: []byte(rawFields), + } + proto.SetExtension(m, pb2.E_Ext_More, &pb2.Ext{ + Data: proto.String("extension"), + XXX_unrecognized: []byte(rawFields), + }) + return m + }(), + want: func() proto.Message { + m := &pb2.MyMessage{ + Count: proto.Int32(42), + Somegroup: &pb2.MyMessage_SomeGroup{GroupField: proto.Int32(6)}, + } + proto.SetExtension(m, pb2.E_Ext_More, &pb2.Ext{Data: proto.String("extension")}) + return m + }(), + }} + + for _, tt := range tests { + proto.DiscardUnknown(tt.in) + if !proto.Equal(tt.in, tt.want) { + t.Errorf("test %s, expected unknown fields to be discarded\ngot %v\nwant %v", tt.desc, tt.in, tt.want) + } + } +} diff --git a/pkg/golang-protobuf/proto/extensions.go b/pkg/golang-protobuf/proto/extensions.go new file mode 100644 index 000000000..42fc120c9 --- /dev/null +++ b/pkg/golang-protobuf/proto/extensions.go @@ -0,0 +1,356 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +import ( + "errors" + "fmt" + "reflect" + + "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/runtime/protoiface" + "google.golang.org/protobuf/runtime/protoimpl" +) + +type ( + // ExtensionDesc represents an extension descriptor and + // is used to interact with an extension field in a message. + // + // Variables of this type are generated in code by protoc-gen-go. + ExtensionDesc = protoimpl.ExtensionInfo + + // ExtensionRange represents a range of message extensions. + // Used in code generated by protoc-gen-go. + ExtensionRange = protoiface.ExtensionRangeV1 + + // Deprecated: Do not use; this is an internal type. + Extension = protoimpl.ExtensionFieldV1 + + // Deprecated: Do not use; this is an internal type. + XXX_InternalExtensions = protoimpl.ExtensionFields +) + +// ErrMissingExtension reports whether the extension was not present. +var ErrMissingExtension = errors.New("proto: missing extension") + +var errNotExtendable = errors.New("proto: not an extendable proto.Message") + +// HasExtension reports whether the extension field is present in m +// either as an explicitly populated field or as an unknown field. +func HasExtension(m Message, xt *ExtensionDesc) (has bool) { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() { + return false + } + + // Check whether any populated known field matches the field number. + xtd := xt.TypeDescriptor() + if isValidExtension(mr.Descriptor(), xtd) { + has = mr.Has(xtd) + } else { + mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool { + has = int32(fd.Number()) == xt.Field + return !has + }) + } + + // Check whether any unknown field matches the field number. + for b := mr.GetUnknown(); !has && len(b) > 0; { + num, _, n := protowire.ConsumeField(b) + has = int32(num) == xt.Field + b = b[n:] + } + return has +} + +// ClearExtension removes the extension field from m +// either as an explicitly populated field or as an unknown field. +func ClearExtension(m Message, xt *ExtensionDesc) { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() { + return + } + + xtd := xt.TypeDescriptor() + if isValidExtension(mr.Descriptor(), xtd) { + mr.Clear(xtd) + } else { + mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool { + if int32(fd.Number()) == xt.Field { + mr.Clear(fd) + return false + } + return true + }) + } + clearUnknown(mr, fieldNum(xt.Field)) +} + +// ClearAllExtensions clears all extensions from m. +// This includes populated fields and unknown fields in the extension range. +func ClearAllExtensions(m Message) { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() { + return + } + + mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool { + if fd.IsExtension() { + mr.Clear(fd) + } + return true + }) + clearUnknown(mr, mr.Descriptor().ExtensionRanges()) +} + +// GetExtension retrieves a proto2 extended field from m. +// +// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil), +// then GetExtension parses the encoded field and returns a Go value of the specified type. +// If the field is not present, then the default value is returned (if one is specified), +// otherwise ErrMissingExtension is reported. +// +// If the descriptor is type incomplete (i.e., ExtensionDesc.ExtensionType is nil), +// then GetExtension returns the raw encoded bytes for the extension field. +func GetExtension(m Message, xt *ExtensionDesc) (interface{}, error) { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { + return nil, errNotExtendable + } + + // Retrieve the unknown fields for this extension field. + var bo protoreflect.RawFields + for bi := mr.GetUnknown(); len(bi) > 0; { + num, _, n := protowire.ConsumeField(bi) + if int32(num) == xt.Field { + bo = append(bo, bi[:n]...) + } + bi = bi[n:] + } + + // For type incomplete descriptors, only retrieve the unknown fields. + if xt.ExtensionType == nil { + return []byte(bo), nil + } + + // If the extension field only exists as unknown fields, unmarshal it. + // This is rarely done since proto.Unmarshal eagerly unmarshals extensions. + xtd := xt.TypeDescriptor() + if !isValidExtension(mr.Descriptor(), xtd) { + return nil, fmt.Errorf("proto: bad extended type; %T does not extend %T", xt.ExtendedType, m) + } + if !mr.Has(xtd) && len(bo) > 0 { + m2 := mr.New() + if err := (proto.UnmarshalOptions{ + Resolver: extensionResolver{xt}, + }.Unmarshal(bo, m2.Interface())); err != nil { + return nil, err + } + if m2.Has(xtd) { + mr.Set(xtd, m2.Get(xtd)) + clearUnknown(mr, fieldNum(xt.Field)) + } + } + + // Check whether the message has the extension field set or a default. + var pv protoreflect.Value + switch { + case mr.Has(xtd): + pv = mr.Get(xtd) + case xtd.HasDefault(): + pv = xtd.Default() + default: + return nil, ErrMissingExtension + } + + v := xt.InterfaceOf(pv) + rv := reflect.ValueOf(v) + if isScalarKind(rv.Kind()) { + rv2 := reflect.New(rv.Type()) + rv2.Elem().Set(rv) + v = rv2.Interface() + } + return v, nil +} + +// extensionResolver is a custom extension resolver that stores a single +// extension type that takes precedence over the global registry. +type extensionResolver struct{ xt protoreflect.ExtensionType } + +func (r extensionResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) { + if xtd := r.xt.TypeDescriptor(); xtd.FullName() == field { + return r.xt, nil + } + return protoregistry.GlobalTypes.FindExtensionByName(field) +} + +func (r extensionResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) { + if xtd := r.xt.TypeDescriptor(); xtd.ContainingMessage().FullName() == message && xtd.Number() == field { + return r.xt, nil + } + return protoregistry.GlobalTypes.FindExtensionByNumber(message, field) +} + +// GetExtensions returns a list of the extensions values present in m, +// corresponding with the provided list of extension descriptors, xts. +// If an extension is missing in m, the corresponding value is nil. +func GetExtensions(m Message, xts []*ExtensionDesc) ([]interface{}, error) { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() { + return nil, errNotExtendable + } + + vs := make([]interface{}, len(xts)) + for i, xt := range xts { + v, err := GetExtension(m, xt) + if err != nil { + if err == ErrMissingExtension { + continue + } + return vs, err + } + vs[i] = v + } + return vs, nil +} + +// SetExtension sets an extension field in m to the provided value. +func SetExtension(m Message, xt *ExtensionDesc, v interface{}) error { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { + return errNotExtendable + } + + rv := reflect.ValueOf(v) + if reflect.TypeOf(v) != reflect.TypeOf(xt.ExtensionType) { + return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", v, xt.ExtensionType) + } + if rv.Kind() == reflect.Ptr { + if rv.IsNil() { + return fmt.Errorf("proto: SetExtension called with nil value of type %T", v) + } + if isScalarKind(rv.Elem().Kind()) { + v = rv.Elem().Interface() + } + } + + xtd := xt.TypeDescriptor() + if !isValidExtension(mr.Descriptor(), xtd) { + return fmt.Errorf("proto: bad extended type; %T does not extend %T", xt.ExtendedType, m) + } + mr.Set(xtd, xt.ValueOf(v)) + clearUnknown(mr, fieldNum(xt.Field)) + return nil +} + +// SetRawExtension inserts b into the unknown fields of m. +// +// Deprecated: Use Message.ProtoReflect.SetUnknown instead. +func SetRawExtension(m Message, fnum int32, b []byte) { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() { + return + } + + // Verify that the raw field is valid. + for b0 := b; len(b0) > 0; { + num, _, n := protowire.ConsumeField(b0) + if int32(num) != fnum { + panic(fmt.Sprintf("mismatching field number: got %d, want %d", num, fnum)) + } + b0 = b0[n:] + } + + ClearExtension(m, &ExtensionDesc{Field: fnum}) + mr.SetUnknown(append(mr.GetUnknown(), b...)) +} + +// ExtensionDescs returns a list of extension descriptors found in m, +// containing descriptors for both populated extension fields in m and +// also unknown fields of m that are in the extension range. +// For the later case, an type incomplete descriptor is provided where only +// the ExtensionDesc.Field field is populated. +// The order of the extension descriptors is undefined. +func ExtensionDescs(m Message) ([]*ExtensionDesc, error) { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { + return nil, errNotExtendable + } + + // Collect a set of known extension descriptors. + extDescs := make(map[protoreflect.FieldNumber]*ExtensionDesc) + mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + if fd.IsExtension() { + xt := fd.(protoreflect.ExtensionTypeDescriptor) + if xd, ok := xt.Type().(*ExtensionDesc); ok { + extDescs[fd.Number()] = xd + } + } + return true + }) + + // Collect a set of unknown extension descriptors. + extRanges := mr.Descriptor().ExtensionRanges() + for b := mr.GetUnknown(); len(b) > 0; { + num, _, n := protowire.ConsumeField(b) + if extRanges.Has(num) && extDescs[num] == nil { + extDescs[num] = nil + } + b = b[n:] + } + + // Transpose the set of descriptors into a list. + var xts []*ExtensionDesc + for num, xt := range extDescs { + if xt == nil { + xt = &ExtensionDesc{Field: int32(num)} + } + xts = append(xts, xt) + } + return xts, nil +} + +// isValidExtension reports whether xtd is a valid extension descriptor for md. +func isValidExtension(md protoreflect.MessageDescriptor, xtd protoreflect.ExtensionTypeDescriptor) bool { + return xtd.ContainingMessage() == md && md.ExtensionRanges().Has(xtd.Number()) +} + +// isScalarKind reports whether k is a protobuf scalar kind (except bytes). +// This function exists for historical reasons since the representation of +// scalars differs between v1 and v2, where v1 uses *T and v2 uses T. +func isScalarKind(k reflect.Kind) bool { + switch k { + case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String: + return true + default: + return false + } +} + +// clearUnknown removes unknown fields from m where remover.Has reports true. +func clearUnknown(m protoreflect.Message, remover interface { + Has(protoreflect.FieldNumber) bool +}) { + var bo protoreflect.RawFields + for bi := m.GetUnknown(); len(bi) > 0; { + num, _, n := protowire.ConsumeField(bi) + if !remover.Has(num) { + bo = append(bo, bi[:n]...) + } + bi = bi[n:] + } + if bi := m.GetUnknown(); len(bi) != len(bo) { + m.SetUnknown(bo) + } +} + +type fieldNum protoreflect.FieldNumber + +func (n1 fieldNum) Has(n2 protoreflect.FieldNumber) bool { + return protoreflect.FieldNumber(n1) == n2 +} diff --git a/pkg/golang-protobuf/proto/extensions_test.go b/pkg/golang-protobuf/proto/extensions_test.go new file mode 100644 index 000000000..597815942 --- /dev/null +++ b/pkg/golang-protobuf/proto/extensions_test.go @@ -0,0 +1,645 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto_test + +import ( + "bytes" + "fmt" + "reflect" + "sort" + "strings" + "sync" + "testing" + + "github.com/golang/protobuf/proto" + + pb2 "github.com/golang/protobuf/internal/testprotos/proto2_proto" +) + +func TestGetExtensionsWithMissingExtensions(t *testing.T) { + msg := &pb2.MyMessage{} + ext1 := &pb2.Ext{} + if err := proto.SetExtension(msg, pb2.E_Ext_More, ext1); err != nil { + t.Fatalf("Could not set ext1: %s", err) + } + exts, err := proto.GetExtensions(msg, []*proto.ExtensionDesc{ + pb2.E_Ext_More, + pb2.E_Ext_Text, + }) + if err != nil { + t.Fatalf("GetExtensions() failed: %s", err) + } + if exts[0] != ext1 { + t.Errorf("ext1 not in returned extensions: %T %v", exts[0], exts[0]) + } + if exts[1] != nil { + t.Errorf("ext2 in returned extensions: %T %v", exts[1], exts[1]) + } +} + +func TestGetExtensionForIncompleteDesc(t *testing.T) { + msg := &pb2.MyMessage{Count: proto.Int32(0)} + extdesc1 := &proto.ExtensionDesc{ + ExtendedType: (*pb2.MyMessage)(nil), + ExtensionType: (*bool)(nil), + Field: 123456789, + Name: "a.b", + Tag: "varint,123456789,opt", + } + ext1 := proto.Bool(true) + if err := proto.SetExtension(msg, extdesc1, ext1); err != nil { + t.Fatalf("Could not set ext1: %s", err) + } + extdesc2 := &proto.ExtensionDesc{ + ExtendedType: (*pb2.MyMessage)(nil), + ExtensionType: ([]byte)(nil), + Field: 123456790, + Name: "a.c", + Tag: "bytes,123456790,opt", + } + ext2 := []byte{0, 1, 2, 3, 4, 5, 6, 7} + if err := proto.SetExtension(msg, extdesc2, ext2); err != nil { + t.Fatalf("Could not set ext2: %s", err) + } + extdesc3 := &proto.ExtensionDesc{ + ExtendedType: (*pb2.MyMessage)(nil), + ExtensionType: (*pb2.Ext)(nil), + Field: 123456791, + Name: "a.d", + Tag: "bytes,123456791,opt", + } + ext3 := &pb2.Ext{Data: proto.String("foo")} + if err := proto.SetExtension(msg, extdesc3, ext3); err != nil { + t.Fatalf("Could not set ext3: %s", err) + } + + b, err := proto.Marshal(msg) + if err != nil { + t.Fatalf("Could not marshal msg: %v", err) + } + if err := proto.Unmarshal(b, msg); err != nil { + t.Fatalf("Could not unmarshal into msg: %v", err) + } + + var expected proto.Buffer + if err := expected.EncodeVarint(uint64((extdesc1.Field << 3) | proto.WireVarint)); err != nil { + t.Fatalf("failed to compute expected prefix for ext1: %s", err) + } + if err := expected.EncodeVarint(1 /* bool true */); err != nil { + t.Fatalf("failed to compute expected value for ext1: %s", err) + } + + if b, err := proto.GetExtension(msg, &proto.ExtensionDesc{Field: extdesc1.Field}); err != nil { + t.Fatalf("Failed to get raw value for ext1: %s", err) + } else if !reflect.DeepEqual(b, expected.Bytes()) { + t.Fatalf("Raw value for ext1: got %v, want %v", b, expected.Bytes()) + } + + expected = proto.Buffer{} // reset + if err := expected.EncodeVarint(uint64((extdesc2.Field << 3) | proto.WireBytes)); err != nil { + t.Fatalf("failed to compute expected prefix for ext2: %s", err) + } + if err := expected.EncodeRawBytes(ext2); err != nil { + t.Fatalf("failed to compute expected value for ext2: %s", err) + } + + if b, err := proto.GetExtension(msg, &proto.ExtensionDesc{Field: extdesc2.Field}); err != nil { + t.Fatalf("Failed to get raw value for ext2: %s", err) + } else if !reflect.DeepEqual(b, expected.Bytes()) { + t.Fatalf("Raw value for ext2: got %v, want %v", b, expected.Bytes()) + } + + expected = proto.Buffer{} // reset + if err := expected.EncodeVarint(uint64((extdesc3.Field << 3) | proto.WireBytes)); err != nil { + t.Fatalf("failed to compute expected prefix for ext3: %s", err) + } + if b, err := proto.Marshal(ext3); err != nil { + t.Fatalf("failed to compute expected value for ext3: %s", err) + } else if err := expected.EncodeRawBytes(b); err != nil { + t.Fatalf("failed to compute expected value for ext3: %s", err) + } + + if b, err := proto.GetExtension(msg, &proto.ExtensionDesc{Field: extdesc3.Field}); err != nil { + t.Fatalf("Failed to get raw value for ext3: %s", err) + } else if !reflect.DeepEqual(b, expected.Bytes()) { + t.Fatalf("Raw value for ext3: got %v, want %v", b, expected.Bytes()) + } +} + +func TestExtensionDescsWithUnregisteredExtensions(t *testing.T) { + msg := &pb2.MyMessage{Count: proto.Int32(0)} + extdesc1 := pb2.E_Ext_More + if descs, err := proto.ExtensionDescs(msg); len(descs) != 0 || err != nil { + t.Errorf("proto.ExtensionDescs: got %d descs, error %v; want 0, nil", len(descs), err) + } + + ext1 := &pb2.Ext{} + if err := proto.SetExtension(msg, extdesc1, ext1); err != nil { + t.Fatalf("Could not set ext1: %s", err) + } + extdesc2 := &proto.ExtensionDesc{ + ExtendedType: (*pb2.MyMessage)(nil), + ExtensionType: (*bool)(nil), + Field: 123456789, + Name: "a.b", + Tag: "varint,123456789,opt", + } + ext2 := proto.Bool(false) + if err := proto.SetExtension(msg, extdesc2, ext2); err != nil { + t.Fatalf("Could not set ext2: %s", err) + } + + b, err := proto.Marshal(msg) + if err != nil { + t.Fatalf("Could not marshal msg: %v", err) + } + if err := proto.Unmarshal(b, msg); err != nil { + t.Fatalf("Could not unmarshal into msg: %v", err) + } + + descs, err := proto.ExtensionDescs(msg) + if err != nil { + t.Fatalf("proto.ExtensionDescs: got error %v", err) + } + sortExtDescs(descs) + wantDescs := []*proto.ExtensionDesc{extdesc1, {Field: extdesc2.Field}} + if !reflect.DeepEqual(descs, wantDescs) { + t.Errorf("proto.ExtensionDescs(msg) sorted extension ids: got %+v, want %+v", descs, wantDescs) + } +} + +type ExtensionDescSlice []*proto.ExtensionDesc + +func (s ExtensionDescSlice) Len() int { return len(s) } +func (s ExtensionDescSlice) Less(i, j int) bool { return s[i].Field < s[j].Field } +func (s ExtensionDescSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +func sortExtDescs(s []*proto.ExtensionDesc) { + sort.Sort(ExtensionDescSlice(s)) +} + +func TestGetExtensionStability(t *testing.T) { + check := func(m *pb2.MyMessage) bool { + ext1, err := proto.GetExtension(m, pb2.E_Ext_More) + if err != nil { + t.Fatalf("GetExtension() failed: %s", err) + } + ext2, err := proto.GetExtension(m, pb2.E_Ext_More) + if err != nil { + t.Fatalf("GetExtension() failed: %s", err) + } + return ext1 == ext2 + } + msg := &pb2.MyMessage{Count: proto.Int32(4)} + ext0 := &pb2.Ext{} + if err := proto.SetExtension(msg, pb2.E_Ext_More, ext0); err != nil { + t.Fatalf("Could not set ext1: %s", ext0) + } + if !check(msg) { + t.Errorf("GetExtension() not stable before marshaling") + } + bb, err := proto.Marshal(msg) + if err != nil { + t.Fatalf("Marshal() failed: %s", err) + } + msg1 := &pb2.MyMessage{} + err = proto.Unmarshal(bb, msg1) + if err != nil { + t.Fatalf("Unmarshal() failed: %s", err) + } + if !check(msg1) { + t.Errorf("GetExtension() not stable after unmarshaling") + } +} + +func TestGetExtensionDefaults(t *testing.T) { + var setFloat64 float64 = 1 + var setFloat32 float32 = 2 + var setInt32 int32 = 3 + var setInt64 int64 = 4 + var setUint32 uint32 = 5 + var setUint64 uint64 = 6 + var setBool = true + var setBool2 = false + var setString = "Goodnight string" + var setBytes = []byte("Goodnight bytes") + var setEnum = pb2.DefaultsMessage_TWO + + type testcase struct { + ext *proto.ExtensionDesc // Extension we are testing. + want interface{} // Expected value of extension, or nil (meaning that GetExtension will fail). + def interface{} // Expected value of extension after ClearExtension(). + } + tests := []testcase{ + {pb2.E_NoDefaultDouble, setFloat64, nil}, + {pb2.E_NoDefaultFloat, setFloat32, nil}, + {pb2.E_NoDefaultInt32, setInt32, nil}, + {pb2.E_NoDefaultInt64, setInt64, nil}, + {pb2.E_NoDefaultUint32, setUint32, nil}, + {pb2.E_NoDefaultUint64, setUint64, nil}, + {pb2.E_NoDefaultSint32, setInt32, nil}, + {pb2.E_NoDefaultSint64, setInt64, nil}, + {pb2.E_NoDefaultFixed32, setUint32, nil}, + {pb2.E_NoDefaultFixed64, setUint64, nil}, + {pb2.E_NoDefaultSfixed32, setInt32, nil}, + {pb2.E_NoDefaultSfixed64, setInt64, nil}, + {pb2.E_NoDefaultBool, setBool, nil}, + {pb2.E_NoDefaultBool, setBool2, nil}, + {pb2.E_NoDefaultString, setString, nil}, + {pb2.E_NoDefaultBytes, setBytes, nil}, + {pb2.E_NoDefaultEnum, setEnum, nil}, + {pb2.E_DefaultDouble, setFloat64, float64(3.1415)}, + {pb2.E_DefaultFloat, setFloat32, float32(3.14)}, + {pb2.E_DefaultInt32, setInt32, int32(42)}, + {pb2.E_DefaultInt64, setInt64, int64(43)}, + {pb2.E_DefaultUint32, setUint32, uint32(44)}, + {pb2.E_DefaultUint64, setUint64, uint64(45)}, + {pb2.E_DefaultSint32, setInt32, int32(46)}, + {pb2.E_DefaultSint64, setInt64, int64(47)}, + {pb2.E_DefaultFixed32, setUint32, uint32(48)}, + {pb2.E_DefaultFixed64, setUint64, uint64(49)}, + {pb2.E_DefaultSfixed32, setInt32, int32(50)}, + {pb2.E_DefaultSfixed64, setInt64, int64(51)}, + {pb2.E_DefaultBool, setBool, true}, + {pb2.E_DefaultBool, setBool2, true}, + {pb2.E_DefaultString, setString, "Hello, string,def=foo"}, + {pb2.E_DefaultBytes, setBytes, []byte("Hello, bytes")}, + {pb2.E_DefaultEnum, setEnum, pb2.DefaultsMessage_ONE}, + } + + checkVal := func(t *testing.T, name string, test testcase, msg *pb2.DefaultsMessage, valWant interface{}) { + t.Run(name, func(t *testing.T) { + val, err := proto.GetExtension(msg, test.ext) + if err != nil { + if valWant != nil { + t.Errorf("GetExtension(): %s", err) + return + } + if want := proto.ErrMissingExtension; err != want { + t.Errorf("Unexpected error: got %v, want %v", err, want) + return + } + return + } + + // All proto2 extension values are either a pointer to a value or a slice of values. + ty := reflect.TypeOf(val) + tyWant := reflect.TypeOf(test.ext.ExtensionType) + if got, want := ty, tyWant; got != want { + t.Errorf("unexpected reflect.TypeOf(): got %v want %v", got, want) + return + } + tye := ty.Elem() + tyeWant := tyWant.Elem() + if got, want := tye, tyeWant; got != want { + t.Errorf("unexpected reflect.TypeOf().Elem(): got %v want %v", got, want) + return + } + + // Check the name of the type of the value. + // If it is an enum it will be type int32 with the name of the enum. + if got, want := tye.Name(), tye.Name(); got != want { + t.Errorf("unexpected reflect.TypeOf().Elem().Name(): got %v want %v", got, want) + return + } + + // Check that value is what we expect. + // If we have a pointer in val, get the value it points to. + valExp := val + if ty.Kind() == reflect.Ptr { + valExp = reflect.ValueOf(val).Elem().Interface() + } + if got, want := valExp, valWant; !reflect.DeepEqual(got, want) { + t.Errorf("unexpected reflect.DeepEqual(): got %v want %v", got, want) + return + } + }) + } + + setTo := func(test testcase) interface{} { + setTo := reflect.ValueOf(test.want) + if typ := reflect.TypeOf(test.ext.ExtensionType); typ.Kind() == reflect.Ptr { + setTo = reflect.New(typ).Elem() + setTo.Set(reflect.New(setTo.Type().Elem())) + setTo.Elem().Set(reflect.ValueOf(test.want)) + } + return setTo.Interface() + } + + for _, test := range tests { + msg := &pb2.DefaultsMessage{} + name := test.ext.Name + + // Check the initial value. + checkVal(t, name+"/initial", test, msg, test.def) + + // Set the per-type value and check value. + if err := proto.SetExtension(msg, test.ext, setTo(test)); err != nil { + t.Errorf("%s: SetExtension(): %v", name, err) + continue + } + checkVal(t, name+"/set", test, msg, test.want) + + // Set and check the value. + proto.ClearExtension(msg, test.ext) + checkVal(t, name+"/cleared", test, msg, test.def) + } +} + +func TestNilMessage(t *testing.T) { + name := "nil interface" + if got, err := proto.GetExtension(nil, pb2.E_Ext_More); err == nil { + t.Errorf("%s: got %T %v, expected to fail", name, got, got) + } else if !strings.Contains(err.Error(), "extendable") { + t.Errorf("%s: got error %v, expected not-extendable error", name, err) + } + + // Regression tests: all functions of the Extension API + // used to panic when passed (*M)(nil), where M is a concrete message + // type. Now they handle this gracefully as a no-op or reported error. + var nilMsg *pb2.MyMessage + desc := pb2.E_Ext_More + + isNotExtendable := func(err error) bool { + return strings.Contains(fmt.Sprint(err), "not an extendable") + } + + if proto.HasExtension(nilMsg, desc) { + t.Error("HasExtension(nil) = true") + } + + if _, err := proto.GetExtensions(nilMsg, []*proto.ExtensionDesc{desc}); !isNotExtendable(err) { + t.Errorf("GetExtensions(nil) = %q (wrong error)", err) + } + + if _, err := proto.ExtensionDescs(nilMsg); !isNotExtendable(err) { + t.Errorf("ExtensionDescs(nil) = %q (wrong error)", err) + } + + if err := proto.SetExtension(nilMsg, desc, nil); !isNotExtendable(err) { + t.Errorf("SetExtension(nil) = %q (wrong error)", err) + } + + proto.ClearExtension(nilMsg, desc) // no-op + proto.ClearAllExtensions(nilMsg) // no-op +} + +func TestExtensionsRoundTrip(t *testing.T) { + msg := &pb2.MyMessage{} + ext1 := &pb2.Ext{ + Data: proto.String("hi"), + } + ext2 := &pb2.Ext{ + Data: proto.String("there"), + } + exists := proto.HasExtension(msg, pb2.E_Ext_More) + if exists { + t.Error("Extension More present unexpectedly") + } + if err := proto.SetExtension(msg, pb2.E_Ext_More, ext1); err != nil { + t.Error(err) + } + if err := proto.SetExtension(msg, pb2.E_Ext_More, ext2); err != nil { + t.Error(err) + } + e, err := proto.GetExtension(msg, pb2.E_Ext_More) + if err != nil { + t.Error(err) + } + x, ok := e.(*pb2.Ext) + if !ok { + t.Errorf("e has type %T, expected test_proto.Ext", e) + } else if *x.Data != "there" { + t.Errorf("SetExtension failed to overwrite, got %+v, not 'there'", x) + } + proto.ClearExtension(msg, pb2.E_Ext_More) + if _, err = proto.GetExtension(msg, pb2.E_Ext_More); err != proto.ErrMissingExtension { + t.Errorf("got %v, expected ErrMissingExtension", e) + } + if err := proto.SetExtension(msg, pb2.E_Ext_More, 12); err == nil { + t.Error("expected some sort of type mismatch error, got nil") + } +} + +func TestNilExtension(t *testing.T) { + msg := &pb2.MyMessage{ + Count: proto.Int32(1), + } + if err := proto.SetExtension(msg, pb2.E_Ext_Text, proto.String("hello")); err != nil { + t.Fatal(err) + } + if err := proto.SetExtension(msg, pb2.E_Ext_More, (*pb2.Ext)(nil)); err == nil { + t.Error("expected SetExtension to fail due to a nil extension") + } else if want := fmt.Sprintf("proto: SetExtension called with nil value of type %T", new(pb2.Ext)); err.Error() != want { + t.Errorf("expected error %v, got %v", want, err) + } + // Note: if the behavior of Marshal is ever changed to ignore nil extensions, update + // this test to verify that E_Ext_Text is properly propagated through marshal->unmarshal. +} + +func TestMarshalUnmarshalRepeatedExtension(t *testing.T) { + // Add a repeated extension to the result. + tests := []struct { + name string + ext []*pb2.ComplexExtension + }{ + { + "two fields", + []*pb2.ComplexExtension{ + {First: proto.Int32(7)}, + {Second: proto.Int32(11)}, + }, + }, + { + "repeated field", + []*pb2.ComplexExtension{ + {Third: []int32{1000}}, + {Third: []int32{2000}}, + }, + }, + { + "two fields and repeated field", + []*pb2.ComplexExtension{ + {Third: []int32{1000}}, + {First: proto.Int32(9)}, + {Second: proto.Int32(21)}, + {Third: []int32{2000}}, + }, + }, + } + for _, test := range tests { + // Marshal message with a repeated extension. + msg1 := new(pb2.OtherMessage) + err := proto.SetExtension(msg1, pb2.E_RComplex, test.ext) + if err != nil { + t.Fatalf("[%s] Error setting extension: %v", test.name, err) + } + b, err := proto.Marshal(msg1) + if err != nil { + t.Fatalf("[%s] Error marshaling message: %v", test.name, err) + } + + // Unmarshal and read the merged proto. + msg2 := new(pb2.OtherMessage) + err = proto.Unmarshal(b, msg2) + if err != nil { + t.Fatalf("[%s] Error unmarshaling message: %v", test.name, err) + } + e, err := proto.GetExtension(msg2, pb2.E_RComplex) + if err != nil { + t.Fatalf("[%s] Error getting extension: %v", test.name, err) + } + ext := e.([]*pb2.ComplexExtension) + if ext == nil { + t.Fatalf("[%s] Invalid extension", test.name) + } + if len(ext) != len(test.ext) { + t.Errorf("[%s] Wrong length of ComplexExtension: got: %v want: %v\n", test.name, len(ext), len(test.ext)) + } + for i := range test.ext { + if !proto.Equal(ext[i], test.ext[i]) { + t.Errorf("[%s] Wrong value for ComplexExtension[%d]: got: %v want: %v\n", test.name, i, ext[i], test.ext[i]) + } + } + } +} + +func TestUnmarshalRepeatingNonRepeatedExtension(t *testing.T) { + // We may see multiple instances of the same extension in the wire + // format. For example, the proto compiler may encode custom options in + // this way. Here, we verify that we merge the extensions together. + tests := []struct { + name string + ext []*pb2.ComplexExtension + }{ + { + "two fields", + []*pb2.ComplexExtension{ + {First: proto.Int32(7)}, + {Second: proto.Int32(11)}, + }, + }, + { + "repeated field", + []*pb2.ComplexExtension{ + {Third: []int32{1000}}, + {Third: []int32{2000}}, + }, + }, + { + "two fields and repeated field", + []*pb2.ComplexExtension{ + {Third: []int32{1000}}, + {First: proto.Int32(9)}, + {Second: proto.Int32(21)}, + {Third: []int32{2000}}, + }, + }, + } + for _, test := range tests { + var buf bytes.Buffer + var want pb2.ComplexExtension + + // Generate a serialized representation of a repeated extension + // by catenating bytes together. + for i, e := range test.ext { + // Merge to create the wanted proto. + proto.Merge(&want, e) + + // serialize the message + msg := new(pb2.OtherMessage) + err := proto.SetExtension(msg, pb2.E_Complex, e) + if err != nil { + t.Fatalf("[%s] Error setting extension %d: %v", test.name, i, err) + } + b, err := proto.Marshal(msg) + if err != nil { + t.Fatalf("[%s] Error marshaling message %d: %v", test.name, i, err) + } + buf.Write(b) + } + + // Unmarshal and read the merged proto. + msg2 := new(pb2.OtherMessage) + err := proto.Unmarshal(buf.Bytes(), msg2) + if err != nil { + t.Fatalf("[%s] Error unmarshaling message: %v", test.name, err) + } + e, err := proto.GetExtension(msg2, pb2.E_Complex) + if err != nil { + t.Fatalf("[%s] Error getting extension: %v", test.name, err) + } + ext := e.(*pb2.ComplexExtension) + if ext == nil { + t.Fatalf("[%s] Invalid extension", test.name) + } + if !proto.Equal(ext, &want) { + t.Errorf("[%s] Wrong value for ComplexExtension: got: %s want: %s\n", test.name, ext, &want) + } + } +} + +func TestClearAllExtensions(t *testing.T) { + // unregistered extension + desc := &proto.ExtensionDesc{ + ExtendedType: (*pb2.MyMessage)(nil), + ExtensionType: (*bool)(nil), + Field: 101010100, + Name: "emptyextension", + Tag: "varint,0,opt", + } + m := &pb2.MyMessage{} + if proto.HasExtension(m, desc) { + t.Errorf("proto.HasExtension(%s): got true, want false", proto.MarshalTextString(m)) + } + if err := proto.SetExtension(m, desc, proto.Bool(true)); err != nil { + t.Errorf("proto.SetExtension(m, desc, true): got error %q, want nil", err) + } + if !proto.HasExtension(m, desc) { + t.Errorf("proto.HasExtension(%s): got false, want true", proto.MarshalTextString(m)) + } + proto.ClearAllExtensions(m) + if proto.HasExtension(m, desc) { + t.Errorf("proto.HasExtension(%s): got true, want false", proto.MarshalTextString(m)) + } +} + +func TestMarshalRace(t *testing.T) { + ext := &pb2.Ext{} + m := &pb2.MyMessage{Count: proto.Int32(4)} + if err := proto.SetExtension(m, pb2.E_Ext_More, ext); err != nil { + t.Fatalf("proto.SetExtension(m, desc, true): got error %q, want nil", err) + } + + b, err := proto.Marshal(m) + if err != nil { + t.Fatalf("Could not marshal message: %v", err) + } + if err := proto.Unmarshal(b, m); err != nil { + t.Fatalf("Could not unmarshal message: %v", err) + } + // after Unmarshal, the extension is in undecoded form. + // GetExtension will decode it lazily. Make sure this does + // not race against Marshal. + + wg := sync.WaitGroup{} + errs := make(chan error, 3) + for n := 3; n > 0; n-- { + wg.Add(1) + go func() { + defer wg.Done() + _, err := proto.Marshal(m) + errs <- err + }() + } + wg.Wait() + close(errs) + + for err = range errs { + if err != nil { + t.Fatal(err) + } + } +} diff --git a/pkg/golang-protobuf/proto/properties.go b/pkg/golang-protobuf/proto/properties.go new file mode 100644 index 000000000..dcdc2202f --- /dev/null +++ b/pkg/golang-protobuf/proto/properties.go @@ -0,0 +1,306 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +import ( + "fmt" + "reflect" + "strconv" + "strings" + "sync" + + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/runtime/protoimpl" +) + +// StructProperties represents protocol buffer type information for a +// generated protobuf message in the open-struct API. +// +// Deprecated: Do not use. +type StructProperties struct { + // Prop are the properties for each field. + // + // Fields belonging to a oneof are stored in OneofTypes instead, with a + // single Properties representing the parent oneof held here. + // + // The order of Prop matches the order of fields in the Go struct. + // Struct fields that are not related to protobufs have a "XXX_" prefix + // in the Properties.Name and must be ignored by the user. + Prop []*Properties + + // OneofTypes contains information about the oneof fields in this message. + // It is keyed by the protobuf field name. + OneofTypes map[string]*OneofProperties +} + +// Properties represents the type information for a protobuf message field. +// +// Deprecated: Do not use. +type Properties struct { + // Name is a placeholder name with little meaningful semantic value. + // If the name has an "XXX_" prefix, the entire Properties must be ignored. + Name string + // OrigName is the protobuf field name or oneof name. + OrigName string + // JSONName is the JSON name for the protobuf field. + JSONName string + // Enum is a placeholder name for enums. + // For historical reasons, this is neither the Go name for the enum, + // nor the protobuf name for the enum. + Enum string // Deprecated: Do not use. + // Weak contains the full name of the weakly referenced message. + Weak string + // Wire is a string representation of the wire type. + Wire string + // WireType is the protobuf wire type for the field. + WireType int + // Tag is the protobuf field number. + Tag int + // Required reports whether this is a required field. + Required bool + // Optional reports whether this is a optional field. + Optional bool + // Repeated reports whether this is a repeated field. + Repeated bool + // Packed reports whether this is a packed repeated field of scalars. + Packed bool + // Proto3 reports whether this field operates under the proto3 syntax. + Proto3 bool + // Oneof reports whether this field belongs within a oneof. + Oneof bool + + // Default is the default value in string form. + Default string + // HasDefault reports whether the field has a default value. + HasDefault bool + + // MapKeyProp is the properties for the key field for a map field. + MapKeyProp *Properties + // MapValProp is the properties for the value field for a map field. + MapValProp *Properties +} + +// OneofProperties represents the type information for a protobuf oneof. +// +// Deprecated: Do not use. +type OneofProperties struct { + // Type is a pointer to the generated wrapper type for the field value. + // This is nil for messages that are not in the open-struct API. + Type reflect.Type + // Field is the index into StructProperties.Prop for the containing oneof. + Field int + // Prop is the properties for the field. + Prop *Properties +} + +// String formats the properties in the protobuf struct field tag style. +func (p *Properties) String() string { + s := p.Wire + s += "," + strconv.Itoa(p.Tag) + if p.Required { + s += ",req" + } + if p.Optional { + s += ",opt" + } + if p.Repeated { + s += ",rep" + } + if p.Packed { + s += ",packed" + } + s += ",name=" + p.OrigName + if p.JSONName != "" { + s += ",json=" + p.JSONName + } + if len(p.Enum) > 0 { + s += ",enum=" + p.Enum + } + if len(p.Weak) > 0 { + s += ",weak=" + p.Weak + } + if p.Proto3 { + s += ",proto3" + } + if p.Oneof { + s += ",oneof" + } + if p.HasDefault { + s += ",def=" + p.Default + } + return s +} + +// Parse populates p by parsing a string in the protobuf struct field tag style. +func (p *Properties) Parse(tag string) { + // For example: "bytes,49,opt,name=foo,def=hello!" + for len(tag) > 0 { + i := strings.IndexByte(tag, ',') + if i < 0 { + i = len(tag) + } + switch s := tag[:i]; { + case strings.HasPrefix(s, "name="): + p.OrigName = s[len("name="):] + case strings.HasPrefix(s, "json="): + p.JSONName = s[len("json="):] + case strings.HasPrefix(s, "enum="): + p.Enum = s[len("enum="):] + case strings.HasPrefix(s, "weak="): + p.Weak = s[len("weak="):] + case strings.Trim(s, "0123456789") == "": + n, _ := strconv.ParseUint(s, 10, 32) + p.Tag = int(n) + case s == "opt": + p.Optional = true + case s == "req": + p.Required = true + case s == "rep": + p.Repeated = true + case s == "varint" || s == "zigzag32" || s == "zigzag64": + p.Wire = s + p.WireType = WireVarint + case s == "fixed32": + p.Wire = s + p.WireType = WireFixed32 + case s == "fixed64": + p.Wire = s + p.WireType = WireFixed64 + case s == "bytes": + p.Wire = s + p.WireType = WireBytes + case s == "group": + p.Wire = s + p.WireType = WireStartGroup + case s == "packed": + p.Packed = true + case s == "proto3": + p.Proto3 = true + case s == "oneof": + p.Oneof = true + case strings.HasPrefix(s, "def="): + // The default tag is special in that everything afterwards is the + // default regardless of the presence of commas. + p.HasDefault = true + p.Default, i = tag[len("def="):], len(tag) + } + tag = strings.TrimPrefix(tag[i:], ",") + } +} + +// Init populates the properties from a protocol buffer struct tag. +// +// Deprecated: Do not use. +func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { + p.Name = name + p.OrigName = name + if tag == "" { + return + } + p.Parse(tag) + + if typ != nil && typ.Kind() == reflect.Map { + p.MapKeyProp = new(Properties) + p.MapKeyProp.Init(nil, "Key", f.Tag.Get("protobuf_key"), nil) + p.MapValProp = new(Properties) + p.MapValProp.Init(nil, "Value", f.Tag.Get("protobuf_val"), nil) + } +} + +var propertiesCache sync.Map // map[reflect.Type]*StructProperties + +// GetProperties returns the list of properties for the type represented by t, +// which must be a generated protocol buffer message in the open-struct API, +// where protobuf message fields are represented by exported Go struct fields. +// +// Deprecated: Use protobuf reflection instead. +func GetProperties(t reflect.Type) *StructProperties { + if p, ok := propertiesCache.Load(t); ok { + return p.(*StructProperties) + } + p, _ := propertiesCache.LoadOrStore(t, newProperties(t)) + return p.(*StructProperties) +} + +func newProperties(t reflect.Type) *StructProperties { + if t.Kind() != reflect.Struct { + panic(fmt.Sprintf("%v is not a generated message in the open-struct API", t)) + } + + var hasOneof bool + prop := new(StructProperties) + + // Construct a list of properties for each field in the struct. + for i := 0; i < t.NumField(); i++ { + p := new(Properties) + f := t.Field(i) + tagField := f.Tag.Get("protobuf") + p.Init(f.Type, f.Name, tagField, &f) + + tagOneof := f.Tag.Get("protobuf_oneof") + if tagOneof != "" { + hasOneof = true + p.OrigName = tagOneof + } + + // Rename unrelated struct fields with the "XXX_" prefix since so much + // user code simply checks for this to exclude special fields. + if tagField == "" && tagOneof == "" && !strings.HasPrefix(p.Name, "XXX_") { + p.Name = "XXX_" + p.Name + p.OrigName = "XXX_" + p.OrigName + } else if p.Weak != "" { + p.Name = p.OrigName // avoid possible "XXX_" prefix on weak field + } + + prop.Prop = append(prop.Prop, p) + } + + // Construct a mapping of oneof field names to properties. + if hasOneof { + var oneofWrappers []interface{} + if fn, ok := reflect.PtrTo(t).MethodByName("XXX_OneofFuncs"); ok { + oneofWrappers = fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[3].Interface().([]interface{}) + } + if fn, ok := reflect.PtrTo(t).MethodByName("XXX_OneofWrappers"); ok { + oneofWrappers = fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0].Interface().([]interface{}) + } + if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(protoreflect.ProtoMessage); ok { + if m, ok := m.ProtoReflect().(interface{ ProtoMessageInfo() *protoimpl.MessageInfo }); ok { + oneofWrappers = m.ProtoMessageInfo().OneofWrappers + } + } + + prop.OneofTypes = make(map[string]*OneofProperties) + for _, wrapper := range oneofWrappers { + p := &OneofProperties{ + Type: reflect.ValueOf(wrapper).Type(), // *T + Prop: new(Properties), + } + f := p.Type.Elem().Field(0) + p.Prop.Name = f.Name + p.Prop.Parse(f.Tag.Get("protobuf")) + + // Determine the struct field that contains this oneof. + // Each wrapper is assignable to exactly one parent field. + var foundOneof bool + for i := 0; i < t.NumField() && !foundOneof; i++ { + if p.Type.AssignableTo(t.Field(i).Type) { + p.Field = i + foundOneof = true + } + } + if !foundOneof { + panic(fmt.Sprintf("%v is not a generated message in the open-struct API", t)) + } + prop.OneofTypes[p.Prop.OrigName] = p + } + } + + return prop +} + +func (sp *StructProperties) Len() int { return len(sp.Prop) } +func (sp *StructProperties) Less(i, j int) bool { return false } +func (sp *StructProperties) Swap(i, j int) { return } diff --git a/pkg/golang-protobuf/proto/proto.go b/pkg/golang-protobuf/proto/proto.go new file mode 100644 index 000000000..5aee89c32 --- /dev/null +++ b/pkg/golang-protobuf/proto/proto.go @@ -0,0 +1,167 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package proto provides functionality for handling protocol buffer messages. +// In particular, it provides marshaling and unmarshaling between a protobuf +// message and the binary wire format. +// +// See https://developers.google.com/protocol-buffers/docs/gotutorial for +// more information. +// +// Deprecated: Use the "google.golang.org/protobuf/proto" package instead. +package proto + +import ( + protoV2 "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/runtime/protoiface" + "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + ProtoPackageIsVersion1 = true + ProtoPackageIsVersion2 = true + ProtoPackageIsVersion3 = true + ProtoPackageIsVersion4 = true +) + +// GeneratedEnum is any enum type generated by protoc-gen-go +// which is a named int32 kind. +// This type exists for documentation purposes. +type GeneratedEnum interface{} + +// GeneratedMessage is any message type generated by protoc-gen-go +// which is a pointer to a named struct kind. +// This type exists for documentation purposes. +type GeneratedMessage interface{} + +// Message is a protocol buffer message. +// +// This is the v1 version of the message interface and is marginally better +// than an empty interface as it lacks any method to programatically interact +// with the contents of the message. +// +// A v2 message is declared in "google.golang.org/protobuf/proto".Message and +// exposes protobuf reflection as a first-class feature of the interface. +// +// To convert a v1 message to a v2 message, use the MessageV2 function. +// To convert a v2 message to a v1 message, use the MessageV1 function. +type Message = protoiface.MessageV1 + +// MessageV1 converts either a v1 or v2 message to a v1 message. +// It returns nil if m is nil. +func MessageV1(m GeneratedMessage) protoiface.MessageV1 { + return protoimpl.X.ProtoMessageV1Of(m) +} + +// MessageV2 converts either a v1 or v2 message to a v2 message. +// It returns nil if m is nil. +func MessageV2(m GeneratedMessage) protoV2.Message { + return protoimpl.X.ProtoMessageV2Of(m) +} + +// MessageReflect returns a reflective view for a message. +// It returns nil if m is nil. +func MessageReflect(m Message) protoreflect.Message { + return protoimpl.X.MessageOf(m) +} + +// Marshaler is implemented by messages that can marshal themselves. +// This interface is used by the following functions: Size, Marshal, +// Buffer.Marshal, and Buffer.EncodeMessage. +// +// Deprecated: Do not implement. +type Marshaler interface { + // Marshal formats the encoded bytes of the message. + // It should be deterministic and emit valid protobuf wire data. + // The caller takes ownership of the returned buffer. + Marshal() ([]byte, error) +} + +// Unmarshaler is implemented by messages that can unmarshal themselves. +// This interface is used by the following functions: Unmarshal, UnmarshalMerge, +// Buffer.Unmarshal, Buffer.DecodeMessage, and Buffer.DecodeGroup. +// +// Deprecated: Do not implement. +type Unmarshaler interface { + // Unmarshal parses the encoded bytes of the protobuf wire input. + // The provided buffer is only valid for during method call. + // It should not reset the receiver message. + Unmarshal([]byte) error +} + +// Merger is implemented by messages that can merge themselves. +// This interface is used by the following functions: Clone and Merge. +// +// Deprecated: Do not implement. +type Merger interface { + // Merge merges the contents of src into the receiver message. + // It clones all data structures in src such that it aliases no mutable + // memory referenced by src. + Merge(src Message) +} + +// RequiredNotSetError is an error type returned when +// marshaling or unmarshaling a message with missing required fields. +type RequiredNotSetError struct { + err error +} + +func (e *RequiredNotSetError) Error() string { + if e.err != nil { + return e.err.Error() + } + return "proto: required field not set" +} +func (e *RequiredNotSetError) RequiredNotSet() bool { + return true +} + +func checkRequiredNotSet(m protoV2.Message) error { + if err := protoV2.CheckInitialized(m); err != nil { + return &RequiredNotSetError{err: err} + } + return nil +} + +// Clone returns a deep copy of src. +func Clone(src Message) Message { + return MessageV1(protoV2.Clone(MessageV2(src))) +} + +// Merge merges src into dst, which must be messages of the same type. +// +// Populated scalar fields in src are copied to dst, while populated +// singular messages in src are merged into dst by recursively calling Merge. +// The elements of every list field in src is appended to the corresponded +// list fields in dst. The entries of every map field in src is copied into +// the corresponding map field in dst, possibly replacing existing entries. +// The unknown fields of src are appended to the unknown fields of dst. +func Merge(dst, src Message) { + protoV2.Merge(MessageV2(dst), MessageV2(src)) +} + +// Equal reports whether two messages are equal. +// If two messages marshal to the same bytes under deterministic serialization, +// then Equal is guaranteed to report true. +// +// Two messages are equal if they are the same protobuf message type, +// have the same set of populated known and extension field values, +// and the same set of unknown fields values. +// +// Scalar values are compared with the equivalent of the == operator in Go, +// except bytes values which are compared using bytes.Equal and +// floating point values which specially treat NaNs as equal. +// Message values are compared by recursively calling Equal. +// Lists are equal if each element value is also equal. +// Maps are equal if they have the same set of keys, where the pair of values +// for each key is also equal. +func Equal(x, y Message) bool { + return protoV2.Equal(MessageV2(x), MessageV2(y)) +} + +func isMessageSet(md protoreflect.MessageDescriptor) bool { + ms, ok := md.(interface{ IsMessageSet() bool }) + return ok && ms.IsMessageSet() +} diff --git a/pkg/golang-protobuf/proto/proto_clone_test.go b/pkg/golang-protobuf/proto/proto_clone_test.go new file mode 100644 index 000000000..d9ae24f1b --- /dev/null +++ b/pkg/golang-protobuf/proto/proto_clone_test.go @@ -0,0 +1,379 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto_test + +import ( + "testing" + + "github.com/golang/protobuf/proto" + + pb2 "github.com/golang/protobuf/internal/testprotos/proto2_proto" + pb3 "github.com/golang/protobuf/internal/testprotos/proto3_proto" +) + +var cloneTestMessage = &pb2.MyMessage{ + Count: proto.Int32(42), + Name: proto.String("Dave"), + Pet: []string{"bunny", "kitty", "horsey"}, + Inner: &pb2.InnerMessage{ + Host: proto.String("niles"), + Port: proto.Int32(9099), + Connected: proto.Bool(true), + }, + Others: []*pb2.OtherMessage{ + { + Value: []byte("some bytes"), + }, + }, + Somegroup: &pb2.MyMessage_SomeGroup{ + GroupField: proto.Int32(6), + }, + RepBytes: [][]byte{[]byte("sham"), []byte("wow")}, +} + +func init() { + ext := &pb2.Ext{ + Data: proto.String("extension"), + } + if err := proto.SetExtension(cloneTestMessage, pb2.E_Ext_More, ext); err != nil { + panic("SetExtension: " + err.Error()) + } + if err := proto.SetExtension(cloneTestMessage, pb2.E_Ext_Text, proto.String("hello")); err != nil { + panic("SetExtension: " + err.Error()) + } + if err := proto.SetExtension(cloneTestMessage, pb2.E_Greeting, []string{"one", "two"}); err != nil { + panic("SetExtension: " + err.Error()) + } +} + +func TestClone(t *testing.T) { + // Create a clone using a marshal/unmarshal roundtrip. + vanilla := new(pb2.MyMessage) + b, err := proto.Marshal(cloneTestMessage) + if err != nil { + t.Errorf("unexpected Marshal error: %v", err) + } + if err := proto.Unmarshal(b, vanilla); err != nil { + t.Errorf("unexpected Unarshal error: %v", err) + } + + // Create a clone using Clone and verify that it is equal to the original. + m := proto.Clone(cloneTestMessage).(*pb2.MyMessage) + if !proto.Equal(m, cloneTestMessage) { + t.Fatalf("Clone(%v) = %v", cloneTestMessage, m) + } + + // Mutate the clone, which should not affect the original. + x1, err := proto.GetExtension(m, pb2.E_Ext_More) + if err != nil { + t.Errorf("unexpected GetExtension(%v) error: %v", pb2.E_Ext_More.Name, err) + } + x2, err := proto.GetExtension(m, pb2.E_Ext_Text) + if err != nil { + t.Errorf("unexpected GetExtension(%v) error: %v", pb2.E_Ext_Text.Name, err) + } + x3, err := proto.GetExtension(m, pb2.E_Greeting) + if err != nil { + t.Errorf("unexpected GetExtension(%v) error: %v", pb2.E_Greeting.Name, err) + } + *m.Inner.Port++ + *(x1.(*pb2.Ext)).Data = "blah blah" + *(x2.(*string)) = "goodbye" + x3.([]string)[0] = "zero" + if !proto.Equal(cloneTestMessage, vanilla) { + t.Fatalf("mutation on original detected:\ngot %v\nwant %v", cloneTestMessage, vanilla) + } +} + +func TestCloneNil(t *testing.T) { + var m *pb2.MyMessage + if c := proto.Clone(m); !proto.Equal(m, c) { + t.Errorf("Clone(%v) = %v", m, c) + } +} + +var mergeTests = []struct { + src, dst, want proto.Message +}{ + { + src: &pb2.MyMessage{ + Count: proto.Int32(42), + }, + dst: &pb2.MyMessage{ + Name: proto.String("Dave"), + }, + want: &pb2.MyMessage{ + Count: proto.Int32(42), + Name: proto.String("Dave"), + }, + }, + { + src: &pb2.MyMessage{ + Inner: &pb2.InnerMessage{ + Host: proto.String("hey"), + Connected: proto.Bool(true), + }, + Pet: []string{"horsey"}, + Others: []*pb2.OtherMessage{ + { + Value: []byte("some bytes"), + }, + }, + }, + dst: &pb2.MyMessage{ + Inner: &pb2.InnerMessage{ + Host: proto.String("niles"), + Port: proto.Int32(9099), + }, + Pet: []string{"bunny", "kitty"}, + Others: []*pb2.OtherMessage{ + { + Key: proto.Int64(31415926535), + }, + { + // Explicitly test a src=nil field + Inner: nil, + }, + }, + }, + want: &pb2.MyMessage{ + Inner: &pb2.InnerMessage{ + Host: proto.String("hey"), + Connected: proto.Bool(true), + Port: proto.Int32(9099), + }, + Pet: []string{"bunny", "kitty", "horsey"}, + Others: []*pb2.OtherMessage{ + { + Key: proto.Int64(31415926535), + }, + {}, + { + Value: []byte("some bytes"), + }, + }, + }, + }, + { + src: &pb2.MyMessage{ + RepBytes: [][]byte{[]byte("wow")}, + }, + dst: &pb2.MyMessage{ + Somegroup: &pb2.MyMessage_SomeGroup{ + GroupField: proto.Int32(6), + }, + RepBytes: [][]byte{[]byte("sham")}, + }, + want: &pb2.MyMessage{ + Somegroup: &pb2.MyMessage_SomeGroup{ + GroupField: proto.Int32(6), + }, + RepBytes: [][]byte{[]byte("sham"), []byte("wow")}, + }, + }, + // Check that a scalar bytes field replaces rather than appends. + { + src: &pb2.OtherMessage{Value: []byte("foo")}, + dst: &pb2.OtherMessage{Value: []byte("bar")}, + want: &pb2.OtherMessage{Value: []byte("foo")}, + }, + { + src: &pb2.MessageWithMap{ + NameMapping: map[int32]string{6: "Nigel"}, + MsgMapping: map[int64]*pb2.FloatingPoint{ + 0x4001: &pb2.FloatingPoint{F: proto.Float64(2.0)}, + 0x4002: &pb2.FloatingPoint{ + F: proto.Float64(2.0), + }, + }, + ByteMapping: map[bool][]byte{true: []byte("wowsa")}, + }, + dst: &pb2.MessageWithMap{ + NameMapping: map[int32]string{ + 6: "Bruce", // should be overwritten + 7: "Andrew", + }, + MsgMapping: map[int64]*pb2.FloatingPoint{ + 0x4002: &pb2.FloatingPoint{ + F: proto.Float64(3.0), + Exact: proto.Bool(true), + }, // the entire message should be overwritten + }, + }, + want: &pb2.MessageWithMap{ + NameMapping: map[int32]string{ + 6: "Nigel", + 7: "Andrew", + }, + MsgMapping: map[int64]*pb2.FloatingPoint{ + 0x4001: &pb2.FloatingPoint{F: proto.Float64(2.0)}, + 0x4002: &pb2.FloatingPoint{ + F: proto.Float64(2.0), + }, + }, + ByteMapping: map[bool][]byte{true: []byte("wowsa")}, + }, + }, + // proto3 shouldn't merge zero values, + // in the same way that proto2 shouldn't merge nils. + { + src: &pb3.Message{ + Name: "Aaron", + Data: []byte(""), // zero value, but not nil + }, + dst: &pb3.Message{ + HeightInCm: 176, + Data: []byte("texas!"), + }, + want: &pb3.Message{ + Name: "Aaron", + HeightInCm: 176, + Data: []byte("texas!"), + }, + }, + { // Oneof fields should merge by assignment. + src: &pb2.Communique{Union: &pb2.Communique_Number{41}}, + dst: &pb2.Communique{Union: &pb2.Communique_Name{"Bobby Tables"}}, + want: &pb2.Communique{Union: &pb2.Communique_Number{41}}, + }, + { // Oneof nil is the same as not set. + src: &pb2.Communique{}, + dst: &pb2.Communique{Union: &pb2.Communique_Name{"Bobby Tables"}}, + want: &pb2.Communique{Union: &pb2.Communique_Name{"Bobby Tables"}}, + }, + { + src: &pb2.Communique{Union: &pb2.Communique_Number{1337}}, + dst: &pb2.Communique{}, + want: &pb2.Communique{Union: &pb2.Communique_Number{1337}}, + }, + { + src: &pb2.Communique{Union: &pb2.Communique_Col{pb2.MyMessage_RED}}, + dst: &pb2.Communique{}, + want: &pb2.Communique{Union: &pb2.Communique_Col{pb2.MyMessage_RED}}, + }, + { + src: &pb2.Communique{Union: &pb2.Communique_Data{[]byte("hello")}}, + dst: &pb2.Communique{}, + want: &pb2.Communique{Union: &pb2.Communique_Data{[]byte("hello")}}, + }, + { + src: &pb2.Communique{Union: &pb2.Communique_Msg{&pb2.Strings{BytesField: []byte{1, 2, 3}}}}, + dst: &pb2.Communique{}, + want: &pb2.Communique{Union: &pb2.Communique_Msg{&pb2.Strings{BytesField: []byte{1, 2, 3}}}}, + }, + { + src: &pb2.Communique{Union: &pb2.Communique_Msg{}}, + dst: &pb2.Communique{}, + want: &pb2.Communique{Union: &pb2.Communique_Msg{}}, + }, + { + src: &pb2.Communique{Union: &pb2.Communique_Msg{&pb2.Strings{StringField: proto.String("123")}}}, + dst: &pb2.Communique{Union: &pb2.Communique_Msg{&pb2.Strings{BytesField: []byte{1, 2, 3}}}}, + want: &pb2.Communique{Union: &pb2.Communique_Msg{&pb2.Strings{StringField: proto.String("123"), BytesField: []byte{1, 2, 3}}}}, + }, + { + src: &pb3.Message{ + Terrain: map[string]*pb3.Nested{ + "kay_a": &pb3.Nested{Cute: true}, // replace + "kay_b": &pb3.Nested{Bunny: "rabbit"}, // insert + }, + }, + dst: &pb3.Message{ + Terrain: map[string]*pb3.Nested{ + "kay_a": &pb3.Nested{Bunny: "lost"}, // replaced + "kay_c": &pb3.Nested{Bunny: "bunny"}, // keep + }, + }, + want: &pb3.Message{ + Terrain: map[string]*pb3.Nested{ + "kay_a": &pb3.Nested{Cute: true}, + "kay_b": &pb3.Nested{Bunny: "rabbit"}, + "kay_c": &pb3.Nested{Bunny: "bunny"}, + }, + }, + }, + { + src: &pb2.GoTest{ + F_BoolRepeated: []bool{}, + F_Int32Repeated: []int32{}, + F_Int64Repeated: []int64{}, + F_Uint32Repeated: []uint32{}, + F_Uint64Repeated: []uint64{}, + F_FloatRepeated: []float32{}, + F_DoubleRepeated: []float64{}, + F_StringRepeated: []string{}, + F_BytesRepeated: [][]byte{}, + }, + dst: &pb2.GoTest{}, + want: &pb2.GoTest{ + F_BoolRepeated: []bool{}, + F_Int32Repeated: []int32{}, + F_Int64Repeated: []int64{}, + F_Uint32Repeated: []uint32{}, + F_Uint64Repeated: []uint64{}, + F_FloatRepeated: []float32{}, + F_DoubleRepeated: []float64{}, + F_StringRepeated: []string{}, + F_BytesRepeated: [][]byte{}, + }, + }, + { + src: &pb2.GoTest{}, + dst: &pb2.GoTest{ + F_BoolRepeated: []bool{}, + F_Int32Repeated: []int32{}, + F_Int64Repeated: []int64{}, + F_Uint32Repeated: []uint32{}, + F_Uint64Repeated: []uint64{}, + F_FloatRepeated: []float32{}, + F_DoubleRepeated: []float64{}, + F_StringRepeated: []string{}, + F_BytesRepeated: [][]byte{}, + }, + want: &pb2.GoTest{ + F_BoolRepeated: []bool{}, + F_Int32Repeated: []int32{}, + F_Int64Repeated: []int64{}, + F_Uint32Repeated: []uint32{}, + F_Uint64Repeated: []uint64{}, + F_FloatRepeated: []float32{}, + F_DoubleRepeated: []float64{}, + F_StringRepeated: []string{}, + F_BytesRepeated: [][]byte{}, + }, + }, + { + src: &pb2.GoTest{ + F_BytesRepeated: [][]byte{nil, []byte{}, []byte{0}}, + }, + dst: &pb2.GoTest{}, + want: &pb2.GoTest{ + F_BytesRepeated: [][]byte{nil, []byte{}, []byte{0}}, + }, + }, + { + src: &pb2.MyMessage{ + Others: []*pb2.OtherMessage{}, + }, + dst: &pb2.MyMessage{}, + want: &pb2.MyMessage{ + Others: []*pb2.OtherMessage{}, + }, + }, +} + +func TestMerge(t *testing.T) { + for _, m := range mergeTests { + got := proto.Clone(m.dst) + if !proto.Equal(got, m.dst) { + t.Errorf("Clone()\ngot %v\nwant %v", got, m.dst) + continue + } + proto.Merge(got, m.src) + if !proto.Equal(got, m.want) { + t.Errorf("Merge(%v, %v)\ngot %v\nwant %v", m.dst, m.src, got, m.want) + } + } +} diff --git a/pkg/golang-protobuf/proto/proto_equal_test.go b/pkg/golang-protobuf/proto/proto_equal_test.go new file mode 100644 index 000000000..d5b2541a0 --- /dev/null +++ b/pkg/golang-protobuf/proto/proto_equal_test.go @@ -0,0 +1,218 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto_test + +import ( + "testing" + + "github.com/golang/protobuf/proto" + + pb2 "github.com/golang/protobuf/internal/testprotos/proto2_proto" + pb3 "github.com/golang/protobuf/internal/testprotos/proto3_proto" +) + +// Four identical base messages. +// The init function adds extensions to some of them. +var messageWithoutExtension = &pb2.MyMessage{Count: proto.Int32(7)} +var messageWithExtension1a = &pb2.MyMessage{Count: proto.Int32(7)} +var messageWithExtension1b = &pb2.MyMessage{Count: proto.Int32(7)} +var messageWithExtension2 = &pb2.MyMessage{Count: proto.Int32(7)} +var messageWithExtension3a = &pb2.MyMessage{Count: proto.Int32(7)} +var messageWithExtension3b = &pb2.MyMessage{Count: proto.Int32(7)} +var messageWithExtension3c = &pb2.MyMessage{Count: proto.Int32(7)} + +// Two messages with non-message extensions. +var messageWithInt32Extension1 = &pb2.MyMessage{Count: proto.Int32(8)} +var messageWithInt32Extension2 = &pb2.MyMessage{Count: proto.Int32(8)} + +func init() { + ext1 := &pb2.Ext{Data: proto.String("Kirk")} + ext2 := &pb2.Ext{Data: proto.String("Picard")} + + // messageWithExtension1a has ext1, but never marshals it. + if err := proto.SetExtension(messageWithExtension1a, pb2.E_Ext_More, ext1); err != nil { + panic("proto.SetExtension on 1a failed: " + err.Error()) + } + + // messageWithExtension1b is the unmarshaled form of messageWithExtension1a. + if err := proto.SetExtension(messageWithExtension1b, pb2.E_Ext_More, ext1); err != nil { + panic("proto.SetExtension on 1b failed: " + err.Error()) + } + buf, err := proto.Marshal(messageWithExtension1b) + if err != nil { + panic("proto.Marshal of 1b failed: " + err.Error()) + } + messageWithExtension1b.Reset() + if err := proto.Unmarshal(buf, messageWithExtension1b); err != nil { + panic("proto.Unmarshal of 1b failed: " + err.Error()) + } + + // messageWithExtension2 has ext2. + if err := proto.SetExtension(messageWithExtension2, pb2.E_Ext_More, ext2); err != nil { + panic("proto.SetExtension on 2 failed: " + err.Error()) + } + + if err := proto.SetExtension(messageWithInt32Extension1, pb2.E_Ext_Number, proto.Int32(23)); err != nil { + panic("proto.SetExtension on Int32-1 failed: " + err.Error()) + } + if err := proto.SetExtension(messageWithInt32Extension1, pb2.E_Ext_Number, proto.Int32(24)); err != nil { + panic("proto.SetExtension on Int32-2 failed: " + err.Error()) + } + + // messageWithExtension3{a,b,c} has unregistered extension. + if proto.RegisteredExtensions(messageWithExtension3a)[200] != nil { + panic("expect extension 200 unregistered") + } + bytes := []byte{ + 0xc0, 0x0c, 0x01, // id=200, wiretype=0 (varint), data=1 + } + bytes2 := []byte{ + 0xc0, 0x0c, 0x02, // id=200, wiretype=0 (varint), data=2 + } + proto.SetRawExtension(messageWithExtension3a, 200, bytes) + proto.SetRawExtension(messageWithExtension3b, 200, bytes) + proto.SetRawExtension(messageWithExtension3c, 200, bytes2) +} + +var EqualTests = []struct { + desc string + a, b proto.Message + exp bool +}{ + {"different types", &pb2.GoEnum{}, &pb2.GoTestField{}, false}, + {"equal empty", &pb2.GoEnum{}, &pb2.GoEnum{}, true}, + {"nil vs nil", nil, nil, true}, + {"typed nil vs typed nil", (*pb2.GoEnum)(nil), (*pb2.GoEnum)(nil), true}, + {"typed nil vs empty", (*pb2.GoEnum)(nil), &pb2.GoEnum{}, false}, + {"different typed nil", (*pb2.GoEnum)(nil), (*pb2.GoTestField)(nil), false}, + + {"one set field, one unset field", &pb2.GoTestField{Label: proto.String("foo")}, &pb2.GoTestField{}, false}, + {"one set field zero, one unset field", &pb2.GoTest{Param: proto.Int32(0)}, &pb2.GoTest{}, false}, + {"different set fields", &pb2.GoTestField{Label: proto.String("foo")}, &pb2.GoTestField{Label: proto.String("bar")}, false}, + {"equal set", &pb2.GoTestField{Label: proto.String("foo")}, &pb2.GoTestField{Label: proto.String("foo")}, true}, + + {"repeated, one set", &pb2.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb2.GoTest{}, false}, + {"repeated, different length", &pb2.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb2.GoTest{F_Int32Repeated: []int32{2}}, false}, + {"repeated, different value", &pb2.GoTest{F_Int32Repeated: []int32{2}}, &pb2.GoTest{F_Int32Repeated: []int32{3}}, false}, + {"repeated, equal", &pb2.GoTest{F_Int32Repeated: []int32{2, 4}}, &pb2.GoTest{F_Int32Repeated: []int32{2, 4}}, true}, + {"repeated, nil equal nil", &pb2.GoTest{F_Int32Repeated: nil}, &pb2.GoTest{F_Int32Repeated: nil}, true}, + {"repeated, nil equal empty", &pb2.GoTest{F_Int32Repeated: nil}, &pb2.GoTest{F_Int32Repeated: []int32{}}, true}, + {"repeated, empty equal nil", &pb2.GoTest{F_Int32Repeated: []int32{}}, &pb2.GoTest{F_Int32Repeated: nil}, true}, + + { + "nested, different", + &pb2.GoTest{RequiredField: &pb2.GoTestField{Label: proto.String("foo")}}, + &pb2.GoTest{RequiredField: &pb2.GoTestField{Label: proto.String("bar")}}, + false, + }, + { + "nested, equal", + &pb2.GoTest{RequiredField: &pb2.GoTestField{Label: proto.String("wow")}}, + &pb2.GoTest{RequiredField: &pb2.GoTestField{Label: proto.String("wow")}}, + true, + }, + + {"bytes", &pb2.OtherMessage{Value: []byte("foo")}, &pb2.OtherMessage{Value: []byte("foo")}, true}, + {"bytes, empty", &pb2.OtherMessage{Value: []byte{}}, &pb2.OtherMessage{Value: []byte{}}, true}, + {"bytes, empty vs nil", &pb2.OtherMessage{Value: []byte{}}, &pb2.OtherMessage{Value: nil}, false}, + { + "repeated bytes", + &pb2.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}}, + &pb2.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}}, + true, + }, + // In proto3, []byte{} and []byte(nil) are equal. + {"proto3 bytes, empty vs nil", &pb3.Message{Data: []byte{}}, &pb3.Message{Data: nil}, true}, + + {"extension vs. no extension", messageWithoutExtension, messageWithExtension1a, false}, + {"extension vs. same extension", messageWithExtension1a, messageWithExtension1b, true}, + {"extension vs. different extension", messageWithExtension1a, messageWithExtension2, false}, + + {"int32 extension vs. itself", messageWithInt32Extension1, messageWithInt32Extension1, true}, + {"int32 extension vs. a different int32", messageWithInt32Extension1, messageWithInt32Extension2, false}, + + {"unregistered extension same", messageWithExtension3a, messageWithExtension3b, true}, + {"unregistered extension different", messageWithExtension3a, messageWithExtension3c, false}, + + { + "message with group", + &pb2.MyMessage{ + Count: proto.Int32(1), + Somegroup: &pb2.MyMessage_SomeGroup{ + GroupField: proto.Int32(5), + }, + }, + &pb2.MyMessage{ + Count: proto.Int32(1), + Somegroup: &pb2.MyMessage_SomeGroup{ + GroupField: proto.Int32(5), + }, + }, + true, + }, + + { + "map same", + &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, + &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, + true, + }, + { + "map different entry", + &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, + &pb2.MessageWithMap{NameMapping: map[int32]string{2: "Rob"}}, + false, + }, + { + "map different key only", + &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, + &pb2.MessageWithMap{NameMapping: map[int32]string{2: "Ken"}}, + false, + }, + { + "map different value only", + &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, + &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}}, + false, + }, + { + "zero-length maps same", + &pb2.MessageWithMap{NameMapping: map[int32]string{}}, + &pb2.MessageWithMap{NameMapping: nil}, + true, + }, + { + "orders in map don't matter", + &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Ken", 2: "Rob"}}, + &pb2.MessageWithMap{NameMapping: map[int32]string{2: "Rob", 1: "Ken"}}, + true, + }, + { + "oneof same", + &pb2.Communique{Union: &pb2.Communique_Number{41}}, + &pb2.Communique{Union: &pb2.Communique_Number{41}}, + true, + }, + { + "oneof one nil", + &pb2.Communique{Union: &pb2.Communique_Number{41}}, + &pb2.Communique{}, + false, + }, + { + "oneof different", + &pb2.Communique{Union: &pb2.Communique_Number{41}}, + &pb2.Communique{Union: &pb2.Communique_Name{"Bobby Tables"}}, + false, + }, +} + +func TestEqual(t *testing.T) { + for _, tc := range EqualTests { + if res := proto.Equal(tc.a, tc.b); res != tc.exp { + t.Errorf("%v: Equal(%v, %v) = %v, want %v", tc.desc, tc.a, tc.b, res, tc.exp) + } + } +} diff --git a/pkg/golang-protobuf/proto/proto_test.go b/pkg/golang-protobuf/proto/proto_test.go new file mode 100644 index 000000000..61c8f8a02 --- /dev/null +++ b/pkg/golang-protobuf/proto/proto_test.go @@ -0,0 +1,2593 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto_test + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "log" + "math" + "math/rand" + "reflect" + "runtime/debug" + "strings" + "sync" + "testing" + "time" + + "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/testing/protopack" + + pb2 "github.com/golang/protobuf/internal/testprotos/proto2_proto" + pb3 "github.com/golang/protobuf/internal/testprotos/proto3_proto" + tspb "github.com/golang/protobuf/ptypes/timestamp" +) + +func initGoTestField() *pb2.GoTestField { + f := new(pb2.GoTestField) + f.Label = proto.String("label") + f.Type = proto.String("type") + return f +} + +// These are all structurally equivalent but the tag numbers differ. +// (It's remarkable that required, optional, and repeated all have +// 8 letters.) +func initGoTest_RequiredGroup() *pb2.GoTest_RequiredGroup { + return &pb2.GoTest_RequiredGroup{ + RequiredField: proto.String("required"), + } +} + +func initGoTest_OptionalGroup() *pb2.GoTest_OptionalGroup { + return &pb2.GoTest_OptionalGroup{ + RequiredField: proto.String("optional"), + } +} + +func initGoTest_RepeatedGroup() *pb2.GoTest_RepeatedGroup { + return &pb2.GoTest_RepeatedGroup{ + RequiredField: proto.String("repeated"), + } +} + +func initGoTest(setdefaults bool) *pb2.GoTest { + pb := new(pb2.GoTest) + if setdefaults { + pb.F_BoolDefaulted = proto.Bool(pb2.Default_GoTest_F_BoolDefaulted) + pb.F_Int32Defaulted = proto.Int32(pb2.Default_GoTest_F_Int32Defaulted) + pb.F_Int64Defaulted = proto.Int64(pb2.Default_GoTest_F_Int64Defaulted) + pb.F_Fixed32Defaulted = proto.Uint32(pb2.Default_GoTest_F_Fixed32Defaulted) + pb.F_Fixed64Defaulted = proto.Uint64(pb2.Default_GoTest_F_Fixed64Defaulted) + pb.F_Uint32Defaulted = proto.Uint32(pb2.Default_GoTest_F_Uint32Defaulted) + pb.F_Uint64Defaulted = proto.Uint64(pb2.Default_GoTest_F_Uint64Defaulted) + pb.F_FloatDefaulted = proto.Float32(pb2.Default_GoTest_F_FloatDefaulted) + pb.F_DoubleDefaulted = proto.Float64(pb2.Default_GoTest_F_DoubleDefaulted) + pb.F_StringDefaulted = proto.String(pb2.Default_GoTest_F_StringDefaulted) + pb.F_BytesDefaulted = pb2.Default_GoTest_F_BytesDefaulted + pb.F_Sint32Defaulted = proto.Int32(pb2.Default_GoTest_F_Sint32Defaulted) + pb.F_Sint64Defaulted = proto.Int64(pb2.Default_GoTest_F_Sint64Defaulted) + pb.F_Sfixed32Defaulted = proto.Int32(pb2.Default_GoTest_F_Sfixed32Defaulted) + pb.F_Sfixed64Defaulted = proto.Int64(pb2.Default_GoTest_F_Sfixed64Defaulted) + } + + pb.Kind = pb2.GoTest_TIME.Enum() + pb.RequiredField = initGoTestField() + pb.F_BoolRequired = proto.Bool(true) + pb.F_Int32Required = proto.Int32(3) + pb.F_Int64Required = proto.Int64(6) + pb.F_Fixed32Required = proto.Uint32(32) + pb.F_Fixed64Required = proto.Uint64(64) + pb.F_Uint32Required = proto.Uint32(3232) + pb.F_Uint64Required = proto.Uint64(6464) + pb.F_FloatRequired = proto.Float32(3232) + pb.F_DoubleRequired = proto.Float64(6464) + pb.F_StringRequired = proto.String("string") + pb.F_BytesRequired = []byte("bytes") + pb.F_Sint32Required = proto.Int32(-32) + pb.F_Sint64Required = proto.Int64(-64) + pb.F_Sfixed32Required = proto.Int32(-32) + pb.F_Sfixed64Required = proto.Int64(-64) + pb.Requiredgroup = initGoTest_RequiredGroup() + + return pb +} + +func overify(t *testing.T, pb *pb2.GoTest, want []byte) { + bb := new(proto.Buffer) + err := bb.Marshal(pb) + got := bb.Bytes() + if err != nil { + t.Logf("overify marshal-1 err = %v", err) + } + if !bytes.Equal(got, want) { + t.Fatalf("got %q\nwant %q", got, want) + } + + // Now test Unmarshal by recreating the original buffer. + pbd := new(pb2.GoTest) + err = bb.Unmarshal(pbd) + if err != nil { + t.Fatalf("overify unmarshal err = %v", err) + } + bb.Reset() + err = bb.Marshal(pbd) + got = bb.Bytes() + if err != nil { + t.Fatalf("overify marshal-2 err = %v", err) + } + if !bytes.Equal(got, want) { + t.Fatalf("got %q\nwant %q", got, want) + } +} + +// When hooks are enabled, RequiredNotSetError is typed alias to internal/proto +// package. Binary serialization has not been wrapped yet and hence produces +// requiredNotSetError instead. This function is a work-around to identify both +// aliased and non-aliased types. +func isRequiredNotSetError(err error) bool { + e, ok := err.(interface{ RequiredNotSet() bool }) + return ok && e.RequiredNotSet() +} + +// Simple tests for numeric encode/decode primitives (varint, etc.) +func TestNumericPrimitives(t *testing.T) { + for i := uint64(0); i < 1e6; i += 111 { + o := new(proto.Buffer) + if o.EncodeVarint(i) != nil { + t.Error("EncodeVarint") + break + } + x, e := o.DecodeVarint() + if e != nil { + t.Fatal("DecodeVarint") + } + if x != i { + t.Fatal("varint decode fail:", i, x) + } + + o.Reset() + if o.EncodeFixed32(i) != nil { + t.Fatal("encFixed32") + } + x, e = o.DecodeFixed32() + if e != nil { + t.Fatal("decFixed32") + } + if x != i { + t.Fatal("fixed32 decode fail:", i, x) + } + + o.Reset() + if o.EncodeFixed64(i*1234567) != nil { + t.Error("encFixed64") + break + } + x, e = o.DecodeFixed64() + if e != nil { + t.Error("decFixed64") + break + } + if x != i*1234567 { + t.Error("fixed64 decode fail:", i*1234567, x) + break + } + + o.Reset() + i32 := int32(i - 12345) + if o.EncodeZigzag32(uint64(i32)) != nil { + t.Fatal("EncodeZigzag32") + } + x, e = o.DecodeZigzag32() + if e != nil { + t.Fatal("DecodeZigzag32") + } + if x != uint64(uint32(i32)) { + t.Fatal("zigzag32 decode fail:", i32, x) + } + + o.Reset() + i64 := int64(i - 12345) + if o.EncodeZigzag64(uint64(i64)) != nil { + t.Fatal("EncodeZigzag64") + } + x, e = o.DecodeZigzag64() + if e != nil { + t.Fatal("DecodeZigzag64") + } + if x != uint64(i64) { + t.Fatal("zigzag64 decode fail:", i64, x) + } + } +} + +// fakeMarshaler is a simple struct implementing Marshaler and Message interfaces. +type fakeMarshaler struct { + b []byte + err error +} + +func (f *fakeMarshaler) Marshal() ([]byte, error) { return f.b, f.err } +func (f *fakeMarshaler) String() string { return fmt.Sprintf("Bytes: %v Error: %v", f.b, f.err) } +func (f *fakeMarshaler) ProtoMessage() {} +func (f *fakeMarshaler) Reset() {} + +type msgWithFakeMarshaler struct { + M *fakeMarshaler `protobuf:"bytes,1,opt,name=fake"` +} + +func (m *msgWithFakeMarshaler) String() string { return proto.CompactTextString(m) } +func (m *msgWithFakeMarshaler) ProtoMessage() {} +func (m *msgWithFakeMarshaler) Reset() {} + +// Simple tests for proto messages that implement the Marshaler interface. +func TestMarshalerEncoding(t *testing.T) { + tests := []struct { + name string + m proto.Message + want []byte + errType reflect.Type + }{ + { + name: "Marshaler that fails", + m: &fakeMarshaler{ + err: errors.New("some marshal err"), + b: []byte{5, 6, 7}, + }, + errType: reflect.TypeOf(errors.New("some marshal err")), + }, + { + name: "Marshaler that fails with RequiredNotSetError", + m: &msgWithFakeMarshaler{ + M: &fakeMarshaler{ + err: &proto.RequiredNotSetError{}, + b: []byte{5, 6, 7}, + }, + }, + errType: reflect.TypeOf(&proto.RequiredNotSetError{}), + }, + { + name: "Marshaler that succeeds", + m: &fakeMarshaler{ + b: []byte{0, 1, 2, 3, 4, 127, 255}, + }, + want: []byte{0, 1, 2, 3, 4, 127, 255}, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + b := proto.NewBuffer(nil) + err := b.Marshal(test.m) + if reflect.TypeOf(err) != test.errType { + t.Errorf("got err %T(%v) wanted %T", err, err, test.errType) + } + if err != nil { + return // skip comparing output when marshal fails. + } + if !reflect.DeepEqual(test.want, b.Bytes()) { + t.Errorf("got bytes %v wanted %v", b.Bytes(), test.want) + } + if size := proto.Size(test.m); size != len(b.Bytes()) { + t.Errorf("Size(_) = %v, but marshaled to %v bytes", size, len(b.Bytes())) + } + + m, mErr := proto.Marshal(test.m) + if !bytes.Equal(b.Bytes(), m) { + t.Errorf("Marshal returned %v, but (*Buffer).Marshal wrote %v", m, b.Bytes()) + } + if !reflect.DeepEqual(err, mErr) { + t.Errorf("Marshal err = %v, but (*Buffer).Marshal returned %v", mErr, err) + } + }) + } +} + +// Ensure that Buffer.Marshal uses O(N) memory for N messages +func TestBufferMarshalAllocs(t *testing.T) { + value := &pb2.OtherMessage{Key: proto.Int64(1)} + msg := &pb2.MyMessage{Count: proto.Int32(1), Others: []*pb2.OtherMessage{value}} + + for _, prealloc := range []int{0, 100, 10000} { + const count = 1000 + var b proto.Buffer + s := make([]byte, 0, proto.Size(msg)) + marshalAllocs := testing.AllocsPerRun(count, func() { + b.SetBuf(s) + err := b.Marshal(msg) + if err != nil { + t.Errorf("Marshal err = %q", err) + } + }) + + b.SetBuf(make([]byte, 0, prealloc)) + bufferAllocs := testing.AllocsPerRun(count, func() { + err := b.Marshal(msg) + if err != nil { + t.Errorf("Marshal err = %q", err) + } + }) + + if marshalAllocs != bufferAllocs { + t.Errorf("%v allocs/op when writing to a preallocated buffer", marshalAllocs) + t.Errorf("%v allocs/op when repeatedly appending to a buffer", bufferAllocs) + t.Errorf("expect amortized allocs/op to be identical") + } + } +} + +// Simple tests for bytes +func TestBytesPrimitives(t *testing.T) { + bb := new(proto.Buffer) + want := []byte("now is the time") + if err := bb.EncodeRawBytes(want); err != nil { + t.Errorf("EncodeRawBytes error: %v", err) + } + got, err := bb.DecodeRawBytes(false) + if err != nil { + t.Errorf("DecodeRawBytes error: %v", err) + } + if !bytes.Equal(got, want) { + t.Errorf("got %q\nwant %q", got, want) + } +} + +// Simple tests for strings +func TestStringPrimitives(t *testing.T) { + bb := new(proto.Buffer) + want := "now is the time" + if err := bb.EncodeStringBytes(want); err != nil { + t.Errorf("EncodeStringBytes error: %v", err) + } + got, err := bb.DecodeStringBytes() + if err != nil { + t.Errorf("DecodeStringBytes error: %v", err) + } + if got != want { + t.Errorf("got %q\nwant %q", got, want) + } +} + +// Do we catch the "required bit not set" case? +func TestRequiredBit(t *testing.T) { + o := new(proto.Buffer) + pb := new(pb2.GoTest) + err := o.Marshal(pb) + if err == nil { + t.Error("did not catch missing required fields") + } else if !strings.Contains(err.Error(), "Kind") { + t.Error("wrong error type:", err) + } +} + +// Check that all fields are nil. +// Clearly silly, and a residue from a more interesting test with an earlier, +// different initialization property, but it once caught a compiler bug so +// it lives. +func checkInitialized(pb *pb2.GoTest, t *testing.T) { + switch { + case pb.F_BoolDefaulted != nil: + t.Error("New or Reset did not set boolean:", *pb.F_BoolDefaulted) + case pb.F_Int32Defaulted != nil: + t.Error("New or Reset did not set int32:", *pb.F_Int32Defaulted) + case pb.F_Int64Defaulted != nil: + t.Error("New or Reset did not set int64:", *pb.F_Int64Defaulted) + case pb.F_Fixed32Defaulted != nil: + t.Error("New or Reset did not set fixed32:", *pb.F_Fixed32Defaulted) + case pb.F_Fixed64Defaulted != nil: + t.Error("New or Reset did not set fixed64:", *pb.F_Fixed64Defaulted) + case pb.F_Uint32Defaulted != nil: + t.Error("New or Reset did not set uint32:", *pb.F_Uint32Defaulted) + case pb.F_Uint64Defaulted != nil: + t.Error("New or Reset did not set uint64:", *pb.F_Uint64Defaulted) + case pb.F_FloatDefaulted != nil: + t.Error("New or Reset did not set float:", *pb.F_FloatDefaulted) + case pb.F_DoubleDefaulted != nil: + t.Error("New or Reset did not set double:", *pb.F_DoubleDefaulted) + case pb.F_StringDefaulted != nil: + t.Error("New or Reset did not set string:", *pb.F_StringDefaulted) + case pb.F_BytesDefaulted != nil: + t.Error("New or Reset did not set bytes:", string(pb.F_BytesDefaulted)) + case pb.F_Sint32Defaulted != nil: + t.Error("New or Reset did not set int32:", *pb.F_Sint32Defaulted) + case pb.F_Sint64Defaulted != nil: + t.Error("New or Reset did not set int64:", *pb.F_Sint64Defaulted) + } +} + +// Does Reset() reset? +func TestReset(t *testing.T) { + pb := initGoTest(true) + // muck with some values + pb.F_BoolDefaulted = proto.Bool(false) + pb.F_Int32Defaulted = proto.Int32(237) + pb.F_Int64Defaulted = proto.Int64(12346) + pb.F_Fixed32Defaulted = proto.Uint32(32000) + pb.F_Fixed64Defaulted = proto.Uint64(666) + pb.F_Uint32Defaulted = proto.Uint32(323232) + pb.F_Uint64Defaulted = nil + pb.F_FloatDefaulted = nil + pb.F_DoubleDefaulted = proto.Float64(0) + pb.F_StringDefaulted = proto.String("gotcha") + pb.F_BytesDefaulted = []byte("asdfasdf") + pb.F_Sint32Defaulted = proto.Int32(123) + pb.F_Sint64Defaulted = proto.Int64(789) + pb.Reset() + checkInitialized(pb, t) +} + +// All required fields set, no defaults provided. +func TestEncodeDecode1(t *testing.T) { + pb := initGoTest(false) + overify(t, pb, + protopack.Message{ + protopack.Tag{1, protopack.VarintType}, protopack.Uvarint(7), + protopack.Tag{4, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.String("label"), + protopack.Tag{2, protopack.BytesType}, protopack.String("type"), + }), + protopack.Tag{10, protopack.VarintType}, protopack.Bool(true), + protopack.Tag{11, protopack.VarintType}, protopack.Varint(3), + protopack.Tag{12, protopack.VarintType}, protopack.Varint(6), + protopack.Tag{13, protopack.Fixed32Type}, protopack.Uint32(32), + protopack.Tag{14, protopack.Fixed64Type}, protopack.Uint64(64), + protopack.Tag{15, protopack.VarintType}, protopack.Uvarint(3232), + protopack.Tag{16, protopack.VarintType}, protopack.Uvarint(6464), + protopack.Tag{17, protopack.Fixed32Type}, protopack.Float32(3232), + protopack.Tag{18, protopack.Fixed64Type}, protopack.Float64(6464), + protopack.Tag{19, protopack.BytesType}, protopack.String("string"), + protopack.Tag{70, protopack.StartGroupType}, + protopack.Message{ + protopack.Tag{71, protopack.BytesType}, protopack.String("required"), + }, + protopack.Tag{70, protopack.EndGroupType}, + protopack.Tag{101, protopack.BytesType}, protopack.Bytes("bytes"), + protopack.Tag{102, protopack.VarintType}, protopack.Svarint(-32), + protopack.Tag{103, protopack.VarintType}, protopack.Svarint(-64), + protopack.Tag{104, protopack.Fixed32Type}, protopack.Int32(-32), + protopack.Tag{105, protopack.Fixed64Type}, protopack.Int64(-64), + }.Marshal()) +} + +// All required fields set, defaults provided. +func TestEncodeDecode2(t *testing.T) { + pb := initGoTest(true) + overify(t, pb, + protopack.Message{ + protopack.Tag{1, protopack.VarintType}, protopack.Uvarint(7), + protopack.Tag{4, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.String("label"), + protopack.Tag{2, protopack.BytesType}, protopack.String("type"), + }), + protopack.Tag{10, protopack.VarintType}, protopack.Bool(true), + protopack.Tag{11, protopack.VarintType}, protopack.Varint(3), + protopack.Tag{12, protopack.VarintType}, protopack.Varint(6), + protopack.Tag{13, protopack.Fixed32Type}, protopack.Uint32(32), + protopack.Tag{14, protopack.Fixed64Type}, protopack.Uint64(64), + protopack.Tag{15, protopack.VarintType}, protopack.Uvarint(3232), + protopack.Tag{16, protopack.VarintType}, protopack.Uvarint(6464), + protopack.Tag{17, protopack.Fixed32Type}, protopack.Float32(3232), + protopack.Tag{18, protopack.Fixed64Type}, protopack.Float64(6464), + protopack.Tag{19, protopack.BytesType}, protopack.String("string"), + protopack.Tag{40, protopack.VarintType}, protopack.Bool(true), + protopack.Tag{41, protopack.VarintType}, protopack.Varint(32), + protopack.Tag{42, protopack.VarintType}, protopack.Varint(64), + protopack.Tag{43, protopack.Fixed32Type}, protopack.Uint32(320), + protopack.Tag{44, protopack.Fixed64Type}, protopack.Uint64(640), + protopack.Tag{45, protopack.VarintType}, protopack.Uvarint(3200), + protopack.Tag{46, protopack.VarintType}, protopack.Uvarint(6400), + protopack.Tag{47, protopack.Fixed32Type}, protopack.Float32(314159), + protopack.Tag{48, protopack.Fixed64Type}, protopack.Float64(271828), + protopack.Tag{49, protopack.BytesType}, protopack.String("hello, \"world!\"\n"), + protopack.Tag{70, protopack.StartGroupType}, + protopack.Message{ + protopack.Tag{71, protopack.BytesType}, protopack.String("required"), + }, + protopack.Tag{70, protopack.EndGroupType}, + protopack.Tag{101, protopack.BytesType}, protopack.Bytes("bytes"), + protopack.Tag{102, protopack.VarintType}, protopack.Svarint(-32), + protopack.Tag{103, protopack.VarintType}, protopack.Svarint(-64), + protopack.Tag{104, protopack.Fixed32Type}, protopack.Int32(-32), + protopack.Tag{105, protopack.Fixed64Type}, protopack.Int64(-64), + protopack.Tag{401, protopack.BytesType}, protopack.Bytes("Bignose"), + protopack.Tag{402, protopack.VarintType}, protopack.Svarint(-32), + protopack.Tag{403, protopack.VarintType}, protopack.Svarint(-64), + protopack.Tag{404, protopack.Fixed32Type}, protopack.Int32(-32), + protopack.Tag{405, protopack.Fixed64Type}, protopack.Int64(-64), + }.Marshal()) +} + +// All default fields set to their default value by hand +func TestEncodeDecode3(t *testing.T) { + pb := initGoTest(false) + pb.F_BoolDefaulted = proto.Bool(true) + pb.F_Int32Defaulted = proto.Int32(32) + pb.F_Int64Defaulted = proto.Int64(64) + pb.F_Fixed32Defaulted = proto.Uint32(320) + pb.F_Fixed64Defaulted = proto.Uint64(640) + pb.F_Uint32Defaulted = proto.Uint32(3200) + pb.F_Uint64Defaulted = proto.Uint64(6400) + pb.F_FloatDefaulted = proto.Float32(314159) + pb.F_DoubleDefaulted = proto.Float64(271828) + pb.F_StringDefaulted = proto.String("hello, \"world!\"\n") + pb.F_BytesDefaulted = []byte("Bignose") + pb.F_Sint32Defaulted = proto.Int32(-32) + pb.F_Sint64Defaulted = proto.Int64(-64) + pb.F_Sfixed32Defaulted = proto.Int32(-32) + pb.F_Sfixed64Defaulted = proto.Int64(-64) + + overify(t, pb, + protopack.Message{ + protopack.Tag{1, protopack.VarintType}, protopack.Uvarint(7), + protopack.Tag{4, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.String("label"), + protopack.Tag{2, protopack.BytesType}, protopack.String("type"), + }), + protopack.Tag{10, protopack.VarintType}, protopack.Bool(true), + protopack.Tag{11, protopack.VarintType}, protopack.Varint(3), + protopack.Tag{12, protopack.VarintType}, protopack.Varint(6), + protopack.Tag{13, protopack.Fixed32Type}, protopack.Uint32(32), + protopack.Tag{14, protopack.Fixed64Type}, protopack.Uint64(64), + protopack.Tag{15, protopack.VarintType}, protopack.Uvarint(3232), + protopack.Tag{16, protopack.VarintType}, protopack.Uvarint(6464), + protopack.Tag{17, protopack.Fixed32Type}, protopack.Float32(3232), + protopack.Tag{18, protopack.Fixed64Type}, protopack.Float64(6464), + protopack.Tag{19, protopack.BytesType}, protopack.String("string"), + protopack.Tag{40, protopack.VarintType}, protopack.Bool(true), + protopack.Tag{41, protopack.VarintType}, protopack.Varint(32), + protopack.Tag{42, protopack.VarintType}, protopack.Varint(64), + protopack.Tag{43, protopack.Fixed32Type}, protopack.Uint32(320), + protopack.Tag{44, protopack.Fixed64Type}, protopack.Uint64(640), + protopack.Tag{45, protopack.VarintType}, protopack.Uvarint(3200), + protopack.Tag{46, protopack.VarintType}, protopack.Uvarint(6400), + protopack.Tag{47, protopack.Fixed32Type}, protopack.Float32(314159), + protopack.Tag{48, protopack.Fixed64Type}, protopack.Float64(271828), + protopack.Tag{49, protopack.BytesType}, protopack.String("hello, \"world!\"\n"), + protopack.Tag{70, protopack.StartGroupType}, + protopack.Message{ + protopack.Tag{71, protopack.BytesType}, protopack.String("required"), + }, + protopack.Tag{70, protopack.EndGroupType}, + protopack.Tag{101, protopack.BytesType}, protopack.Bytes("bytes"), + protopack.Tag{102, protopack.VarintType}, protopack.Svarint(-32), + protopack.Tag{103, protopack.VarintType}, protopack.Svarint(-64), + protopack.Tag{104, protopack.Fixed32Type}, protopack.Int32(-32), + protopack.Tag{105, protopack.Fixed64Type}, protopack.Int64(-64), + protopack.Tag{401, protopack.BytesType}, protopack.Bytes("Bignose"), + protopack.Tag{402, protopack.VarintType}, protopack.Svarint(-32), + protopack.Tag{403, protopack.VarintType}, protopack.Svarint(-64), + protopack.Tag{404, protopack.Fixed32Type}, protopack.Int32(-32), + protopack.Tag{405, protopack.Fixed64Type}, protopack.Int64(-64), + }.Marshal()) +} + +// All required fields set, defaults provided, all non-defaulted optional fields have values. +func TestEncodeDecode4(t *testing.T) { + pb := initGoTest(true) + pb.Table = proto.String("hello") + pb.Param = proto.Int32(7) + pb.OptionalField = initGoTestField() + pb.F_BoolOptional = proto.Bool(true) + pb.F_Int32Optional = proto.Int32(32) + pb.F_Int64Optional = proto.Int64(64) + pb.F_Fixed32Optional = proto.Uint32(3232) + pb.F_Fixed64Optional = proto.Uint64(6464) + pb.F_Uint32Optional = proto.Uint32(323232) + pb.F_Uint64Optional = proto.Uint64(646464) + pb.F_FloatOptional = proto.Float32(32.) + pb.F_DoubleOptional = proto.Float64(64.) + pb.F_StringOptional = proto.String("hello") + pb.F_BytesOptional = []byte("Bignose") + pb.F_Sint32Optional = proto.Int32(-32) + pb.F_Sint64Optional = proto.Int64(-64) + pb.F_Sfixed32Optional = proto.Int32(-32) + pb.F_Sfixed64Optional = proto.Int64(-64) + pb.Optionalgroup = initGoTest_OptionalGroup() + + overify(t, pb, + protopack.Message{ + protopack.Tag{1, protopack.VarintType}, protopack.Uvarint(7), + protopack.Tag{2, protopack.BytesType}, protopack.String("hello"), + protopack.Tag{3, protopack.VarintType}, protopack.Varint(7), + protopack.Tag{4, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.String("label"), + protopack.Tag{2, protopack.BytesType}, protopack.String("type"), + }), + protopack.Tag{6, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.String("label"), + protopack.Tag{2, protopack.BytesType}, protopack.String("type"), + }), + protopack.Tag{10, protopack.VarintType}, protopack.Bool(true), + protopack.Tag{11, protopack.VarintType}, protopack.Varint(3), + protopack.Tag{12, protopack.VarintType}, protopack.Varint(6), + protopack.Tag{13, protopack.Fixed32Type}, protopack.Uint32(32), + protopack.Tag{14, protopack.Fixed64Type}, protopack.Uint64(64), + protopack.Tag{15, protopack.VarintType}, protopack.Uvarint(3232), + protopack.Tag{16, protopack.VarintType}, protopack.Uvarint(6464), + protopack.Tag{17, protopack.Fixed32Type}, protopack.Float32(3232), + protopack.Tag{18, protopack.Fixed64Type}, protopack.Float64(6464), + protopack.Tag{19, protopack.BytesType}, protopack.String("string"), + protopack.Tag{30, protopack.VarintType}, protopack.Bool(true), + protopack.Tag{31, protopack.VarintType}, protopack.Varint(32), + protopack.Tag{32, protopack.VarintType}, protopack.Varint(64), + protopack.Tag{33, protopack.Fixed32Type}, protopack.Uint32(3232), + protopack.Tag{34, protopack.Fixed64Type}, protopack.Uint64(6464), + protopack.Tag{35, protopack.VarintType}, protopack.Uvarint(323232), + protopack.Tag{36, protopack.VarintType}, protopack.Uvarint(646464), + protopack.Tag{37, protopack.Fixed32Type}, protopack.Float32(32), + protopack.Tag{38, protopack.Fixed64Type}, protopack.Float64(64), + protopack.Tag{39, protopack.BytesType}, protopack.String("hello"), + protopack.Tag{40, protopack.VarintType}, protopack.Bool(true), + protopack.Tag{41, protopack.VarintType}, protopack.Varint(32), + protopack.Tag{42, protopack.VarintType}, protopack.Varint(64), + protopack.Tag{43, protopack.Fixed32Type}, protopack.Uint32(320), + protopack.Tag{44, protopack.Fixed64Type}, protopack.Uint64(640), + protopack.Tag{45, protopack.VarintType}, protopack.Uvarint(3200), + protopack.Tag{46, protopack.VarintType}, protopack.Uvarint(6400), + protopack.Tag{47, protopack.Fixed32Type}, protopack.Float32(314159), + protopack.Tag{48, protopack.Fixed64Type}, protopack.Float64(271828), + protopack.Tag{49, protopack.BytesType}, protopack.String("hello, \"world!\"\n"), + protopack.Tag{70, protopack.StartGroupType}, + protopack.Message{ + protopack.Tag{71, protopack.BytesType}, protopack.String("required"), + }, + protopack.Tag{70, protopack.EndGroupType}, + protopack.Tag{90, protopack.StartGroupType}, + protopack.Message{ + protopack.Tag{91, protopack.BytesType}, protopack.String("optional"), + }, + protopack.Tag{90, protopack.EndGroupType}, + protopack.Tag{101, protopack.BytesType}, protopack.Bytes("bytes"), + protopack.Tag{102, protopack.VarintType}, protopack.Svarint(-32), + protopack.Tag{103, protopack.VarintType}, protopack.Svarint(-64), + protopack.Tag{104, protopack.Fixed32Type}, protopack.Int32(-32), + protopack.Tag{105, protopack.Fixed64Type}, protopack.Int64(-64), + protopack.Tag{301, protopack.BytesType}, protopack.Bytes("Bignose"), + protopack.Tag{302, protopack.VarintType}, protopack.Svarint(-32), + protopack.Tag{303, protopack.VarintType}, protopack.Svarint(-64), + protopack.Tag{304, protopack.Fixed32Type}, protopack.Int32(-32), + protopack.Tag{305, protopack.Fixed64Type}, protopack.Int64(-64), + protopack.Tag{401, protopack.BytesType}, protopack.Bytes("Bignose"), + protopack.Tag{402, protopack.VarintType}, protopack.Svarint(-32), + protopack.Tag{403, protopack.VarintType}, protopack.Svarint(-64), + protopack.Tag{404, protopack.Fixed32Type}, protopack.Int32(-32), + protopack.Tag{405, protopack.Fixed64Type}, protopack.Int64(-64), + }.Marshal()) +} + +// All required fields set, defaults provided, all repeated fields given two values. +func TestEncodeDecode5(t *testing.T) { + pb := initGoTest(true) + pb.RepeatedField = []*pb2.GoTestField{initGoTestField(), initGoTestField()} + pb.F_BoolRepeated = []bool{false, true} + pb.F_Int32Repeated = []int32{32, 33} + pb.F_Int64Repeated = []int64{64, 65} + pb.F_Fixed32Repeated = []uint32{3232, 3333} + pb.F_Fixed64Repeated = []uint64{6464, 6565} + pb.F_Uint32Repeated = []uint32{323232, 333333} + pb.F_Uint64Repeated = []uint64{646464, 656565} + pb.F_FloatRepeated = []float32{32., 33.} + pb.F_DoubleRepeated = []float64{64., 65.} + pb.F_StringRepeated = []string{"hello", "sailor"} + pb.F_BytesRepeated = [][]byte{[]byte("big"), []byte("nose")} + pb.F_Sint32Repeated = []int32{32, -32} + pb.F_Sint64Repeated = []int64{64, -64} + pb.F_Sfixed32Repeated = []int32{32, -32} + pb.F_Sfixed64Repeated = []int64{64, -64} + pb.Repeatedgroup = []*pb2.GoTest_RepeatedGroup{initGoTest_RepeatedGroup(), initGoTest_RepeatedGroup()} + + overify(t, pb, + protopack.Message{ + protopack.Tag{1, protopack.VarintType}, protopack.Uvarint(7), + protopack.Tag{4, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.String("label"), + protopack.Tag{2, protopack.BytesType}, protopack.String("type"), + }), + protopack.Tag{5, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.String("label"), + protopack.Tag{2, protopack.BytesType}, protopack.String("type"), + }), + protopack.Tag{5, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.String("label"), + protopack.Tag{2, protopack.BytesType}, protopack.String("type"), + }), + protopack.Tag{10, protopack.VarintType}, protopack.Bool(true), + protopack.Tag{11, protopack.VarintType}, protopack.Varint(3), + protopack.Tag{12, protopack.VarintType}, protopack.Varint(6), + protopack.Tag{13, protopack.Fixed32Type}, protopack.Uint32(32), + protopack.Tag{14, protopack.Fixed64Type}, protopack.Uint64(64), + protopack.Tag{15, protopack.VarintType}, protopack.Uvarint(3232), + protopack.Tag{16, protopack.VarintType}, protopack.Uvarint(6464), + protopack.Tag{17, protopack.Fixed32Type}, protopack.Float32(3232), + protopack.Tag{18, protopack.Fixed64Type}, protopack.Float64(6464), + protopack.Tag{19, protopack.BytesType}, protopack.String("string"), + protopack.Tag{20, protopack.VarintType}, protopack.Bool(false), + protopack.Tag{20, protopack.VarintType}, protopack.Bool(true), + protopack.Tag{21, protopack.VarintType}, protopack.Varint(32), + protopack.Tag{21, protopack.VarintType}, protopack.Varint(33), + protopack.Tag{22, protopack.VarintType}, protopack.Varint(64), + protopack.Tag{22, protopack.VarintType}, protopack.Varint(65), + protopack.Tag{23, protopack.Fixed32Type}, protopack.Uint32(3232), + protopack.Tag{23, protopack.Fixed32Type}, protopack.Uint32(3333), + protopack.Tag{24, protopack.Fixed64Type}, protopack.Uint64(6464), + protopack.Tag{24, protopack.Fixed64Type}, protopack.Uint64(6565), + protopack.Tag{25, protopack.VarintType}, protopack.Uvarint(323232), + protopack.Tag{25, protopack.VarintType}, protopack.Uvarint(333333), + protopack.Tag{26, protopack.VarintType}, protopack.Uvarint(646464), + protopack.Tag{26, protopack.VarintType}, protopack.Uvarint(656565), + protopack.Tag{27, protopack.Fixed32Type}, protopack.Float32(32), + protopack.Tag{27, protopack.Fixed32Type}, protopack.Float32(33), + protopack.Tag{28, protopack.Fixed64Type}, protopack.Float64(64), + protopack.Tag{28, protopack.Fixed64Type}, protopack.Float64(65), + protopack.Tag{29, protopack.BytesType}, protopack.String("hello"), + protopack.Tag{29, protopack.BytesType}, protopack.String("sailor"), + protopack.Tag{40, protopack.VarintType}, protopack.Bool(true), + protopack.Tag{41, protopack.VarintType}, protopack.Varint(32), + protopack.Tag{42, protopack.VarintType}, protopack.Varint(64), + protopack.Tag{43, protopack.Fixed32Type}, protopack.Uint32(320), + protopack.Tag{44, protopack.Fixed64Type}, protopack.Uint64(640), + protopack.Tag{45, protopack.VarintType}, protopack.Uvarint(3200), + protopack.Tag{46, protopack.VarintType}, protopack.Uvarint(6400), + protopack.Tag{47, protopack.Fixed32Type}, protopack.Float32(314159), + protopack.Tag{48, protopack.Fixed64Type}, protopack.Float64(271828), + protopack.Tag{49, protopack.BytesType}, protopack.String("hello, \"world!\"\n"), + protopack.Tag{70, protopack.StartGroupType}, + protopack.Message{ + protopack.Tag{71, protopack.BytesType}, protopack.String("required"), + }, + protopack.Tag{70, protopack.EndGroupType}, + protopack.Tag{80, protopack.StartGroupType}, + protopack.Message{ + protopack.Tag{81, protopack.BytesType}, protopack.String("repeated"), + }, + protopack.Tag{80, protopack.EndGroupType}, + protopack.Tag{80, protopack.StartGroupType}, + protopack.Message{ + protopack.Tag{81, protopack.BytesType}, protopack.String("repeated"), + }, + protopack.Tag{80, protopack.EndGroupType}, + protopack.Tag{101, protopack.BytesType}, protopack.Bytes("bytes"), + protopack.Tag{102, protopack.VarintType}, protopack.Svarint(-32), + protopack.Tag{103, protopack.VarintType}, protopack.Svarint(-64), + protopack.Tag{104, protopack.Fixed32Type}, protopack.Int32(-32), + protopack.Tag{105, protopack.Fixed64Type}, protopack.Int64(-64), + protopack.Tag{201, protopack.BytesType}, protopack.Bytes("big"), + protopack.Tag{201, protopack.BytesType}, protopack.Bytes("nose"), + protopack.Tag{202, protopack.VarintType}, protopack.Svarint(32), + protopack.Tag{202, protopack.VarintType}, protopack.Svarint(-32), + protopack.Tag{203, protopack.VarintType}, protopack.Svarint(64), + protopack.Tag{203, protopack.VarintType}, protopack.Svarint(-64), + protopack.Tag{204, protopack.Fixed32Type}, protopack.Int32(32), + protopack.Tag{204, protopack.Fixed32Type}, protopack.Int32(-32), + protopack.Tag{205, protopack.Fixed64Type}, protopack.Int64(64), + protopack.Tag{205, protopack.Fixed64Type}, protopack.Int64(-64), + protopack.Tag{401, protopack.BytesType}, protopack.Bytes("Bignose"), + protopack.Tag{402, protopack.VarintType}, protopack.Svarint(-32), + protopack.Tag{403, protopack.VarintType}, protopack.Svarint(-64), + protopack.Tag{404, protopack.Fixed32Type}, protopack.Int32(-32), + protopack.Tag{405, protopack.Fixed64Type}, protopack.Int64(-64), + }.Marshal()) +} + +// All required fields set, all packed repeated fields given two values. +func TestEncodeDecode6(t *testing.T) { + pb := initGoTest(false) + pb.F_BoolRepeatedPacked = []bool{false, true} + pb.F_Int32RepeatedPacked = []int32{32, 33} + pb.F_Int64RepeatedPacked = []int64{64, 65} + pb.F_Fixed32RepeatedPacked = []uint32{3232, 3333} + pb.F_Fixed64RepeatedPacked = []uint64{6464, 6565} + pb.F_Uint32RepeatedPacked = []uint32{323232, 333333} + pb.F_Uint64RepeatedPacked = []uint64{646464, 656565} + pb.F_FloatRepeatedPacked = []float32{32., 33.} + pb.F_DoubleRepeatedPacked = []float64{64., 65.} + pb.F_Sint32RepeatedPacked = []int32{32, -32} + pb.F_Sint64RepeatedPacked = []int64{64, -64} + pb.F_Sfixed32RepeatedPacked = []int32{32, -32} + pb.F_Sfixed64RepeatedPacked = []int64{64, -64} + + overify(t, pb, + protopack.Message{ + protopack.Tag{1, protopack.VarintType}, protopack.Uvarint(7), + protopack.Tag{4, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.String("label"), + protopack.Tag{2, protopack.BytesType}, protopack.String("type"), + }), + protopack.Tag{10, protopack.VarintType}, protopack.Bool(true), + protopack.Tag{11, protopack.VarintType}, protopack.Varint(3), + protopack.Tag{12, protopack.VarintType}, protopack.Varint(6), + protopack.Tag{13, protopack.Fixed32Type}, protopack.Uint32(32), + protopack.Tag{14, protopack.Fixed64Type}, protopack.Uint64(64), + protopack.Tag{15, protopack.VarintType}, protopack.Uvarint(3232), + protopack.Tag{16, protopack.VarintType}, protopack.Uvarint(6464), + protopack.Tag{17, protopack.Fixed32Type}, protopack.Float32(3232), + protopack.Tag{18, protopack.Fixed64Type}, protopack.Float64(6464), + protopack.Tag{19, protopack.BytesType}, protopack.String("string"), + protopack.Tag{50, protopack.BytesType}, protopack.LengthPrefix{protopack.Bool(false), protopack.Bool(true)}, + protopack.Tag{51, protopack.BytesType}, protopack.LengthPrefix{protopack.Varint(32), protopack.Varint(33)}, + protopack.Tag{52, protopack.BytesType}, protopack.LengthPrefix{protopack.Varint(64), protopack.Varint(65)}, + protopack.Tag{53, protopack.BytesType}, protopack.LengthPrefix{protopack.Uint32(3232), protopack.Uint32(3333)}, + protopack.Tag{54, protopack.BytesType}, protopack.LengthPrefix{protopack.Uint64(6464), protopack.Uint64(6565)}, + protopack.Tag{55, protopack.BytesType}, protopack.LengthPrefix{protopack.Uvarint(323232), protopack.Uvarint(333333)}, + protopack.Tag{56, protopack.BytesType}, protopack.LengthPrefix{protopack.Uvarint(646464), protopack.Uvarint(656565)}, + protopack.Tag{57, protopack.BytesType}, protopack.LengthPrefix{protopack.Float32(32), protopack.Float32(33)}, + protopack.Tag{58, protopack.BytesType}, protopack.LengthPrefix{protopack.Float64(64), protopack.Float64(65)}, + protopack.Tag{70, protopack.StartGroupType}, + protopack.Message{ + protopack.Tag{71, protopack.BytesType}, protopack.String("required"), + }, + protopack.Tag{70, protopack.EndGroupType}, + protopack.Tag{101, protopack.BytesType}, protopack.Bytes("bytes"), + protopack.Tag{102, protopack.VarintType}, protopack.Svarint(-32), + protopack.Tag{103, protopack.VarintType}, protopack.Svarint(-64), + protopack.Tag{104, protopack.Fixed32Type}, protopack.Int32(-32), + protopack.Tag{105, protopack.Fixed64Type}, protopack.Int64(-64), + protopack.Tag{502, protopack.BytesType}, protopack.LengthPrefix{protopack.Svarint(32), protopack.Svarint(-32)}, + protopack.Tag{503, protopack.BytesType}, protopack.LengthPrefix{protopack.Svarint(64), protopack.Svarint(-64)}, + protopack.Tag{504, protopack.BytesType}, protopack.LengthPrefix{protopack.Int32(32), protopack.Int32(-32)}, + protopack.Tag{505, protopack.BytesType}, protopack.LengthPrefix{protopack.Int64(64), protopack.Int64(-64)}, + }.Marshal()) +} + +// Test that we can encode empty bytes fields. +func TestEncodeDecodeBytes1(t *testing.T) { + pb := initGoTest(false) + + // Create our bytes + pb.F_BytesRequired = []byte{} + pb.F_BytesRepeated = [][]byte{{}} + pb.F_BytesOptional = []byte{} + + d, err := proto.Marshal(pb) + if err != nil { + t.Error(err) + } + + pbd := new(pb2.GoTest) + if err := proto.Unmarshal(d, pbd); err != nil { + t.Error(err) + } + + if pbd.F_BytesRequired == nil || len(pbd.F_BytesRequired) != 0 { + t.Error("required empty bytes field is incorrect") + } + if pbd.F_BytesRepeated == nil || len(pbd.F_BytesRepeated) == 1 && pbd.F_BytesRepeated[0] == nil { + t.Error("repeated empty bytes field is incorrect") + } + if pbd.F_BytesOptional == nil || len(pbd.F_BytesOptional) != 0 { + t.Error("optional empty bytes field is incorrect") + } +} + +// Test that we encode nil-valued fields of a repeated bytes field correctly. +// Since entries in a repeated field cannot be nil, nil must mean empty value. +func TestEncodeDecodeBytes2(t *testing.T) { + pb := initGoTest(false) + + // Create our bytes + pb.F_BytesRepeated = [][]byte{nil} + + d, err := proto.Marshal(pb) + if err != nil { + t.Error(err) + } + + pbd := new(pb2.GoTest) + if err := proto.Unmarshal(d, pbd); err != nil { + t.Error(err) + } + + if len(pbd.F_BytesRepeated) != 1 || pbd.F_BytesRepeated[0] == nil { + t.Error("Unexpected value for repeated bytes field") + } +} + +// All required fields set, defaults provided, all repeated fields given two values. +func TestSkippingUnrecognizedFields(t *testing.T) { + o := new(proto.Buffer) + pb := initGoTestField() + + // Marshal it normally. + o.Marshal(pb) + + // Now new a GoSkipTest record. + skip := &pb2.GoSkipTest{ + SkipInt32: proto.Int32(32), + SkipFixed32: proto.Uint32(3232), + SkipFixed64: proto.Uint64(6464), + SkipString: proto.String("skipper"), + Skipgroup: &pb2.GoSkipTest_SkipGroup{ + GroupInt32: proto.Int32(75), + GroupString: proto.String("wxyz"), + }, + } + + // Marshal it into same buffer. + o.Marshal(skip) + + pbd := new(pb2.GoTestField) + o.Unmarshal(pbd) + + // The __unrecognized field should be a marshaling of GoSkipTest + skipd := new(pb2.GoSkipTest) + + o.SetBuf(pbd.XXX_unrecognized) + o.Unmarshal(skipd) + + switch { + case *skipd.SkipInt32 != *skip.SkipInt32: + t.Error("skip int32", skipd.SkipInt32) + case *skipd.SkipFixed32 != *skip.SkipFixed32: + t.Error("skip fixed32", skipd.SkipFixed32) + case *skipd.SkipFixed64 != *skip.SkipFixed64: + t.Error("skip fixed64", skipd.SkipFixed64) + case *skipd.SkipString != *skip.SkipString: + t.Error("skip string", *skipd.SkipString) + case *skipd.Skipgroup.GroupInt32 != *skip.Skipgroup.GroupInt32: + t.Error("skip group int32", skipd.Skipgroup.GroupInt32) + case *skipd.Skipgroup.GroupString != *skip.Skipgroup.GroupString: + t.Error("skip group string", *skipd.Skipgroup.GroupString) + } +} + +// Check that unrecognized fields of a submessage are preserved. +func TestSubmessageUnrecognizedFields(t *testing.T) { + nm := &pb2.NewMessage{ + Nested: &pb2.NewMessage_Nested{ + Name: proto.String("Nigel"), + FoodGroup: proto.String("carbs"), + }, + } + b, err := proto.Marshal(nm) + if err != nil { + t.Fatalf("Marshal of NewMessage: %v", err) + } + + // Unmarshal into an OldMessage. + om := new(pb2.OldMessage) + if err := proto.Unmarshal(b, om); err != nil { + t.Fatalf("Unmarshal to OldMessage: %v", err) + } + exp := &pb2.OldMessage{ + Nested: &pb2.OldMessage_Nested{ + Name: proto.String("Nigel"), + // normal protocol buffer users should not do this + XXX_unrecognized: []byte("\x12\x05carbs"), + }, + } + if !proto.Equal(om, exp) { + t.Errorf("om = %v, want %v", om, exp) + } + + // Clone the OldMessage. + om = proto.Clone(om).(*pb2.OldMessage) + if !proto.Equal(om, exp) { + t.Errorf("Clone(om) = %v, want %v", om, exp) + } + + // Marshal the OldMessage, then unmarshal it into an empty NewMessage. + if b, err = proto.Marshal(om); err != nil { + t.Fatalf("Marshal of OldMessage: %v", err) + } + t.Logf("Marshal(%v) -> %q", om, b) + nm2 := new(pb2.NewMessage) + if err := proto.Unmarshal(b, nm2); err != nil { + t.Fatalf("Unmarshal to NewMessage: %v", err) + } + if !proto.Equal(nm, nm2) { + t.Errorf("NewMessage round-trip: %v => %v", nm, nm2) + } +} + +// Check that an int32 field can be upgraded to an int64 field. +func TestNegativeInt32(t *testing.T) { + om := &pb2.OldMessage{ + Num: proto.Int32(-1), + } + b, err := proto.Marshal(om) + if err != nil { + t.Fatalf("Marshal of OldMessage: %v", err) + } + + // Check the size. It should be 11 bytes; + // 1 for the field/wire type, and 10 for the negative number. + if len(b) != 11 { + t.Errorf("%v marshaled as %q, wanted 11 bytes", om, b) + } + + // Unmarshal into a NewMessage. + nm := new(pb2.NewMessage) + if err := proto.Unmarshal(b, nm); err != nil { + t.Fatalf("Unmarshal to NewMessage: %v", err) + } + want := &pb2.NewMessage{ + Num: proto.Int64(-1), + } + if !proto.Equal(nm, want) { + t.Errorf("nm = %v, want %v", nm, want) + } +} + +// Check that we can grow an array (repeated field) to have many elements. +// This test doesn't depend only on our encoding; for variety, it makes sure +// we create, encode, and decode the correct contents explicitly. It's therefore +// a bit messier. +// This test also uses (and hence tests) the Marshal/Unmarshal functions +// instead of the methods. +func TestBigRepeated(t *testing.T) { + pb := initGoTest(true) + + // Create the arrays + const N = 50 // Internally the library starts much smaller. + pb.Repeatedgroup = make([]*pb2.GoTest_RepeatedGroup, N) + pb.F_Sint64Repeated = make([]int64, N) + pb.F_Sint32Repeated = make([]int32, N) + pb.F_BytesRepeated = make([][]byte, N) + pb.F_StringRepeated = make([]string, N) + pb.F_DoubleRepeated = make([]float64, N) + pb.F_FloatRepeated = make([]float32, N) + pb.F_Uint64Repeated = make([]uint64, N) + pb.F_Uint32Repeated = make([]uint32, N) + pb.F_Fixed64Repeated = make([]uint64, N) + pb.F_Fixed32Repeated = make([]uint32, N) + pb.F_Int64Repeated = make([]int64, N) + pb.F_Int32Repeated = make([]int32, N) + pb.F_BoolRepeated = make([]bool, N) + pb.RepeatedField = make([]*pb2.GoTestField, N) + + // Fill in the arrays with checkable values. + igtf := initGoTestField() + igtrg := initGoTest_RepeatedGroup() + for i := 0; i < N; i++ { + pb.Repeatedgroup[i] = igtrg + pb.F_Sint64Repeated[i] = int64(i) + pb.F_Sint32Repeated[i] = int32(i) + s := fmt.Sprint(i) + pb.F_BytesRepeated[i] = []byte(s) + pb.F_StringRepeated[i] = s + pb.F_DoubleRepeated[i] = float64(i) + pb.F_FloatRepeated[i] = float32(i) + pb.F_Uint64Repeated[i] = uint64(i) + pb.F_Uint32Repeated[i] = uint32(i) + pb.F_Fixed64Repeated[i] = uint64(i) + pb.F_Fixed32Repeated[i] = uint32(i) + pb.F_Int64Repeated[i] = int64(i) + pb.F_Int32Repeated[i] = int32(i) + pb.F_BoolRepeated[i] = i%2 == 0 + pb.RepeatedField[i] = igtf + } + + // Marshal. + buf, _ := proto.Marshal(pb) + + // Now test Unmarshal by recreating the original buffer. + pbd := new(pb2.GoTest) + proto.Unmarshal(buf, pbd) + + // Check the checkable values + for i := uint64(0); i < N; i++ { + switch { + case pbd.Repeatedgroup[i] == nil: + t.Error("pbd.Repeatedgroup bad") + case uint64(pbd.F_Sint64Repeated[i]) != i: + t.Error("pbd.F_Sint64Repeated bad", uint64(pbd.F_Sint64Repeated[i]), i) + case uint64(pbd.F_Sint32Repeated[i]) != i: + t.Error("pbd.F_Sint32Repeated bad", uint64(pbd.F_Sint32Repeated[i]), i) + case !bytes.Equal(pbd.F_BytesRepeated[i], []byte(fmt.Sprint(i))): + t.Error("pbd.F_BytesRepeated bad", pbd.F_BytesRepeated[i], i) + case pbd.F_StringRepeated[i] != string(fmt.Sprint(i)): + t.Error("pbd.F_Sint32Repeated bad", pbd.F_StringRepeated[i], i) + case uint64(pbd.F_DoubleRepeated[i]) != i: + t.Error("pbd.F_DoubleRepeated bad", uint64(pbd.F_DoubleRepeated[i]), i) + case uint64(pbd.F_FloatRepeated[i]) != i: + t.Error("pbd.F_FloatRepeated bad", uint64(pbd.F_FloatRepeated[i]), i) + case pbd.F_Uint64Repeated[i] != i: + t.Error("pbd.F_Uint64Repeated bad", pbd.F_Uint64Repeated[i], i) + case uint64(pbd.F_Uint32Repeated[i]) != i: + t.Error("pbd.F_Uint32Repeated bad", uint64(pbd.F_Uint32Repeated[i]), i) + case pbd.F_Fixed64Repeated[i] != i: + t.Error("pbd.F_Fixed64Repeated bad", pbd.F_Fixed64Repeated[i], i) + case uint64(pbd.F_Fixed32Repeated[i]) != i: + t.Error("pbd.F_Fixed32Repeated bad", uint64(pbd.F_Fixed32Repeated[i]), i) + case uint64(pbd.F_Int64Repeated[i]) != i: + t.Error("pbd.F_Int64Repeated bad", uint64(pbd.F_Int64Repeated[i]), i) + case uint64(pbd.F_Int32Repeated[i]) != i: + t.Error("pbd.F_Int32Repeated bad", uint64(pbd.F_Int32Repeated[i]), i) + case pbd.F_BoolRepeated[i] != (i%2 == 0): + t.Error("pbd.F_BoolRepeated bad", pbd.F_BoolRepeated[i], i) + case pbd.RepeatedField[i] == nil: + t.Error("pbd.RepeatedField bad") + } + } +} + +func TestBadWireTypeUnknown(t *testing.T) { + b := protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.Bytes("x"), + protopack.Tag{1, protopack.Fixed32Type}, protopack.Uint32(0), + protopack.Tag{1, protopack.VarintType}, protopack.Varint(11), + protopack.Tag{2, protopack.VarintType}, protopack.Uvarint(22), + protopack.Tag{2, protopack.BytesType}, protopack.String("aaa"), + protopack.Tag{2, protopack.Fixed32Type}, protopack.Uint32(33), + protopack.Tag{4, protopack.VarintType}, protopack.Uvarint(44), + protopack.Tag{4, protopack.BytesType}, protopack.String("bbb"), + protopack.Tag{4, protopack.Fixed32Type}, protopack.Uint32(55), + protopack.Tag{4, protopack.BytesType}, protopack.String("ccc"), + protopack.Tag{4, protopack.Fixed64Type}, protopack.Uint64(66), + protopack.Tag{11, protopack.VarintType}, protopack.Uvarint(77), + protopack.Tag{11, protopack.BytesType}, protopack.Bytes("ddd"), + protopack.Tag{11, protopack.Fixed64Type}, protopack.Float64(88), + protopack.Tag{11, protopack.Fixed32Type}, protopack.Uint32(99), + }.Marshal() + + m := new(pb2.MyMessage) + if err := proto.Unmarshal(b, m); err != nil { + t.Errorf("unexpected Unmarshal error: %v", err) + } + + unknown := protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.Bytes("x"), + protopack.Tag{1, protopack.Fixed32Type}, protopack.Uint32(0), + protopack.Tag{2, protopack.VarintType}, protopack.Uvarint(22), + protopack.Tag{2, protopack.Fixed32Type}, protopack.Uint32(33), + protopack.Tag{4, protopack.VarintType}, protopack.Uvarint(44), + protopack.Tag{4, protopack.Fixed32Type}, protopack.Uint32(55), + protopack.Tag{4, protopack.Fixed64Type}, protopack.Uint64(66), + protopack.Tag{11, protopack.VarintType}, protopack.Uvarint(77), + protopack.Tag{11, protopack.BytesType}, protopack.Bytes("ddd"), + protopack.Tag{11, protopack.Fixed32Type}, protopack.Uint32(99), + }.Marshal() + if !bytes.Equal(m.XXX_unrecognized, unknown) { + t.Errorf("unknown bytes mismatch:\ngot %x\nwant %x", m.XXX_unrecognized, unknown) + } + proto.DiscardUnknown(m) + + want := &pb2.MyMessage{Count: proto.Int32(11), Name: proto.String("aaa"), Pet: []string{"bbb", "ccc"}, Bigfloat: proto.Float64(88)} + if !proto.Equal(m, want) { + t.Errorf("message mismatch:\ngot %v\nwant %v", m, want) + } +} + +func encodeDecode(t *testing.T, in, out proto.Message, msg string) { + buf, err := proto.Marshal(in) + if err != nil { + t.Fatalf("failed marshaling %v: %v", msg, err) + } + if err := proto.Unmarshal(buf, out); err != nil { + t.Fatalf("failed unmarshaling %v: %v", msg, err) + } +} + +func TestPackedNonPackedDecoderSwitching(t *testing.T) { + np, p := new(pb2.NonPackedTest), new(pb2.PackedTest) + + // non-packed -> packed + np.A = []int32{0, 1, 1, 2, 3, 5} + encodeDecode(t, np, p, "non-packed -> packed") + if !reflect.DeepEqual(np.A, p.B) { + t.Errorf("failed non-packed -> packed; np.A=%+v, p.B=%+v", np.A, p.B) + } + + // packed -> non-packed + np.Reset() + p.B = []int32{3, 1, 4, 1, 5, 9} + encodeDecode(t, p, np, "packed -> non-packed") + if !reflect.DeepEqual(p.B, np.A) { + t.Errorf("failed packed -> non-packed; p.B=%+v, np.A=%+v", p.B, np.A) + } +} + +func TestProto1RepeatedGroup(t *testing.T) { + pb := &pb2.MessageList{ + Message: []*pb2.MessageList_Message{ + { + Name: proto.String("blah"), + Count: proto.Int32(7), + }, + // NOTE: pb.Message[1] is a nil + nil, + }, + } + + o := new(proto.Buffer) + err := o.Marshal(pb) + if err == nil { + t.Fatalf("expected error when marshaling repeted nil MessageList.Message") + } + if _, ok := err.(*proto.RequiredNotSetError); !ok { + t.Fatalf("unexpected error when marshaling: %v", err) + } +} + +// Test that enums work. Checks for a bug introduced by making enums +// named types instead of int32: newInt32FromUint64 would crash with +// a type mismatch in reflect.PointTo. +func TestEnum(t *testing.T) { + pb := new(pb2.GoEnum) + pb.Foo = pb2.FOO_FOO1.Enum() + o := new(proto.Buffer) + if err := o.Marshal(pb); err != nil { + t.Fatal("error encoding enum:", err) + } + pb1 := new(pb2.GoEnum) + if err := o.Unmarshal(pb1); err != nil { + t.Fatal("error decoding enum:", err) + } + if *pb1.Foo != pb2.FOO_FOO1 { + t.Error("expected 7 but got ", *pb1.Foo) + } +} + +// Enum types have String methods. Check that enum fields can be printed. +// We don't care what the value actually is, just as long as it doesn't crash. +func TestPrintingNilEnumFields(t *testing.T) { + pb := new(pb2.GoEnum) + _ = fmt.Sprintf("%+v", pb) +} + +// Verify that absent required fields cause Marshal/Unmarshal to return errors. +func TestRequiredFieldEnforcement(t *testing.T) { + pb := new(pb2.GoTestField) + _, err := proto.Marshal(pb) + if err == nil { + t.Error("marshal: expected error, got nil") + } else if !isRequiredNotSetError(err) { + t.Errorf("marshal: bad error type: %v", err) + } + + // A slightly sneaky, yet valid, proto. It encodes the same required field twice, + // so simply counting the required fields is insufficient. + // field 1, encoding 2, value "hi" + buf := []byte("\x0A\x02hi\x0A\x02hi") + err = proto.Unmarshal(buf, pb) + if err == nil { + t.Error("unmarshal: expected error, got nil") + } else if !isRequiredNotSetError(err) { + t.Errorf("unmarshal: bad error type: %v", err) + } +} + +// Verify that absent required fields in groups cause Marshal/Unmarshal to return errors. +func TestRequiredFieldEnforcementGroups(t *testing.T) { + pb := &pb2.GoTestRequiredGroupField{Group: &pb2.GoTestRequiredGroupField_Group{}} + if _, err := proto.Marshal(pb); err == nil { + t.Error("marshal: expected error, got nil") + } else if !isRequiredNotSetError(err) { + t.Errorf("marshal: bad error type: %v", err) + } + + buf := []byte{11, 12} + if err := proto.Unmarshal(buf, pb); err == nil { + t.Error("unmarshal: expected error, got nil") + } else if !isRequiredNotSetError(err) { + t.Errorf("unmarshal: bad error type: %v", err) + } +} + +func TestTypedNilMarshal(t *testing.T) { + // A typed nil should return ErrNil and not crash. + var m *pb2.GoEnum + if _, err := proto.Marshal(m); err != proto.ErrNil { + t.Errorf("Marshal(%#v): got %v, want ErrNil", m, err) + } +} + +func TestTypedNilMarshalInOneof(t *testing.T) { + // It should not panic. + m := &pb2.Communique{Union: &pb2.Communique_Msg{nil}} + if _, err := proto.Marshal(m); err == proto.ErrNil { + t.Errorf("Marshal(%#v): got %v, want nil or errOneofHasNil", m, err) + } +} + +// A type that implements the Marshaler interface, but is not nillable. +type nonNillableInt uint64 + +func (nni nonNillableInt) Marshal() ([]byte, error) { + return proto.EncodeVarint(uint64(nni)), nil +} + +type NNIMessage struct { + nni nonNillableInt +} + +func (*NNIMessage) Reset() {} +func (*NNIMessage) String() string { return "" } +func (*NNIMessage) ProtoMessage() {} + +type NMMessage struct{} + +func (*NMMessage) Reset() {} +func (*NMMessage) String() string { return "" } +func (*NMMessage) ProtoMessage() {} + +// Verify a type that uses the Marshaler interface, but has a nil pointer. +func TestNilMarshaler(t *testing.T) { + // Try a struct with a Marshaler field that is nil. + // It should be directly marshable. + nmm := new(NMMessage) + if _, err := proto.Marshal(nmm); err != nil { + t.Error("unexpected error marshaling nmm: ", err) + } + + // Try a struct with a Marshaler field that is not nillable. + nnim := new(NNIMessage) + nnim.nni = 7 + var _ proto.Marshaler = nnim.nni // verify it is truly a Marshaler + if _, err := proto.Marshal(nnim); err != nil { + t.Error("unexpected error marshaling nnim: ", err) + } +} + +func TestAllSetDefaults(t *testing.T) { + // Exercise SetDefaults with all scalar field types. + got := &pb2.Defaults{ + // NaN != NaN, so override that here. + F_Nan: proto.Float32(1.7), + } + want := &pb2.Defaults{ + F_Bool: proto.Bool(true), + F_Int32: proto.Int32(32), + F_Int64: proto.Int64(64), + F_Fixed32: proto.Uint32(320), + F_Fixed64: proto.Uint64(640), + F_Uint32: proto.Uint32(3200), + F_Uint64: proto.Uint64(6400), + F_Float: proto.Float32(314159), + F_Double: proto.Float64(271828), + F_String: proto.String(`hello, "world!"` + "\n"), + F_Bytes: []byte("Bignose"), + F_Sint32: proto.Int32(-32), + F_Sint64: proto.Int64(-64), + F_Enum: pb2.Defaults_GREEN.Enum(), + F_Pinf: proto.Float32(float32(math.Inf(1))), + F_Ninf: proto.Float32(float32(math.Inf(-1))), + F_Nan: proto.Float32(1.7), + StrZero: proto.String(""), + } + proto.SetDefaults(got) + if !proto.Equal(got, want) { + t.Errorf("SetDefaults failed\n got %v\nwant %v", got, want) + } +} + +func TestSetDefaultsWithSetField(t *testing.T) { + // Check that a set value is not overridden. + m := &pb2.Defaults{ + F_Int32: proto.Int32(12), + } + proto.SetDefaults(m) + if v := m.GetF_Int32(); v != 12 { + t.Errorf("m.FInt32 = %v, want 12", v) + } +} + +func TestSetDefaultsWithSubMessage(t *testing.T) { + got := &pb2.OtherMessage{ + Key: proto.Int64(123), + Inner: &pb2.InnerMessage{ + Host: proto.String("gopher"), + }, + } + want := &pb2.OtherMessage{ + Key: proto.Int64(123), + Inner: &pb2.InnerMessage{ + Host: proto.String("gopher"), + Port: proto.Int32(4000), + }, + } + proto.SetDefaults(got) + if !proto.Equal(got, want) { + t.Errorf("\n got %v\nwant %v", got, want) + } +} + +func TestSetDefaultsWithRepeatedSubMessage(t *testing.T) { + got := &pb2.MyMessage{ + RepInner: []*pb2.InnerMessage{{}}, + } + want := &pb2.MyMessage{ + RepInner: []*pb2.InnerMessage{{ + Port: proto.Int32(4000), + }}, + } + proto.SetDefaults(got) + if !proto.Equal(got, want) { + t.Errorf("\n got %v\nwant %v", got, want) + } +} + +func TestSetDefaultWithRepeatedNonMessage(t *testing.T) { + got := &pb2.MyMessage{ + Pet: []string{"turtle", "wombat"}, + } + want := proto.Clone(got) + proto.SetDefaults(got) + if !proto.Equal(got, want) { + t.Errorf("\n got %v\nwant %v", got, want) + } +} + +func TestMaximumTagNumber(t *testing.T) { + m := &pb2.MaxTag{ + LastField: proto.String("natural goat essence"), + } + buf, err := proto.Marshal(m) + if err != nil { + t.Fatalf("proto.Marshal failed: %v", err) + } + m2 := new(pb2.MaxTag) + if err := proto.Unmarshal(buf, m2); err != nil { + t.Fatalf("proto.Unmarshal failed: %v", err) + } + if got, want := m2.GetLastField(), *m.LastField; got != want { + t.Errorf("got %q, want %q", got, want) + } +} + +func TestJSON(t *testing.T) { + m := &pb2.MyMessage{ + Count: proto.Int32(4), + Pet: []string{"bunny", "kitty"}, + Inner: &pb2.InnerMessage{ + Host: proto.String("cauchy"), + }, + Bikeshed: pb2.MyMessage_GREEN.Enum(), + } + const want = `{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"},"bikeshed":1}` + + b, err := json.Marshal(m) + if err != nil { + t.Fatalf("json.Marshal failed: %v", err) + } + s := string(b) + if s != want { + t.Errorf("got %s\nwant %s", s, want) + } + + received := new(pb2.MyMessage) + if err := json.Unmarshal(b, received); err != nil { + t.Fatalf("json.Unmarshal failed: %v", err) + } + if !proto.Equal(received, m) { + t.Fatalf("got %s, want %s", received, m) + } + + // Test unmarshaling of JSON with symbolic enum name. + const old = `{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"},"bikeshed":"GREEN"}` + received.Reset() + if err := json.Unmarshal([]byte(old), received); err != nil { + t.Fatalf("json.Unmarshal failed: %v", err) + } + if !proto.Equal(received, m) { + t.Fatalf("got %s, want %s", received, m) + } +} + +func TestBadWireType(t *testing.T) { + b := []byte{7<<3 | 6} // field 7, wire type 6 + pb := new(pb2.OtherMessage) + if err := proto.Unmarshal(b, pb); err == nil { + t.Errorf("Unmarshal did not fail") + } +} + +func TestBytesWithInvalidLength(t *testing.T) { + // If a byte sequence has an invalid (negative) length, Unmarshal should not panic. + b := protopack.Message{ + protopack.Tag{2, protopack.BytesType}, protopack.Denormalized{+1, protopack.Uvarint(34359738367)}, + }.Marshal() + proto.Unmarshal(b, new(pb2.MyMessage)) +} + +func TestLengthOverflow(t *testing.T) { + // Overflowing a length should not panic. + b := protopack.Message{ + protopack.Tag{2, protopack.BytesType}, protopack.String("\x01"), + protopack.Tag{3, protopack.BytesType}, protopack.Uvarint(9223372036854775807), + protopack.Raw("\x01"), + }.Marshal() + proto.Unmarshal(b, new(pb2.MyMessage)) +} + +func TestVarintOverflow(t *testing.T) { + // Overflowing a 64-bit length should not be allowed. + b := protopack.Message{ + protopack.Tag{1, protopack.VarintType}, protopack.Varint(1), + protopack.Tag{3, protopack.BytesType}, + protopack.Raw("\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x01"), + }.Marshal() + if err := proto.Unmarshal(b, new(pb2.MyMessage)); err == nil { + t.Fatalf("Overflowed uint64 length without error") + } +} + +func TestBytesWithInvalidLengthInGroup(t *testing.T) { + // Overflowing a 64-bit length should not be allowed. + b := protopack.Message{ + protopack.Tag{775, protopack.StartGroupType}, + protopack.Message{ + protopack.Tag{774, protopack.BytesType}, protopack.Uvarint(13654841034505509168), + protopack.Raw(""), + }, + }.Marshal() + if err := proto.Unmarshal(b, new(pb2.MyMessage)); err == nil { + t.Fatalf("Overflowed uint64 length without error") + } +} + +func TestUnmarshalFuzz(t *testing.T) { + const N = 1000 + seed := time.Now().UnixNano() + t.Logf("RNG seed is %d", seed) + rng := rand.New(rand.NewSource(seed)) + buf := make([]byte, 20) + for i := 0; i < N; i++ { + for j := range buf { + buf[j] = byte(rng.Intn(256)) + } + fuzzUnmarshal(t, buf) + } +} + +func TestMergeMessages(t *testing.T) { + pb := &pb2.MessageList{Message: []*pb2.MessageList_Message{{Name: proto.String("x"), Count: proto.Int32(1)}}} + data, err := proto.Marshal(pb) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + + pb1 := new(pb2.MessageList) + if err := proto.Unmarshal(data, pb1); err != nil { + t.Fatalf("first Unmarshal: %v", err) + } + if err := proto.Unmarshal(data, pb1); err != nil { + t.Fatalf("second Unmarshal: %v", err) + } + if len(pb1.Message) != 1 { + t.Errorf("two Unmarshals produced %d Messages, want 1", len(pb1.Message)) + } + + pb2 := new(pb2.MessageList) + if err := proto.UnmarshalMerge(data, pb2); err != nil { + t.Fatalf("first UnmarshalMerge: %v", err) + } + if err := proto.UnmarshalMerge(data, pb2); err != nil { + t.Fatalf("second UnmarshalMerge: %v", err) + } + if len(pb2.Message) != 2 { + t.Errorf("two UnmarshalMerges produced %d Messages, want 2", len(pb2.Message)) + } +} + +func TestExtensionMarshalOrder(t *testing.T) { + m := &pb2.MyMessage{Count: proto.Int(123)} + if err := proto.SetExtension(m, pb2.E_Ext_More, &pb2.Ext{Data: proto.String("alpha")}); err != nil { + t.Fatalf("SetExtension: %v", err) + } + if err := proto.SetExtension(m, pb2.E_Ext_Text, proto.String("aleph")); err != nil { + t.Fatalf("SetExtension: %v", err) + } + if err := proto.SetExtension(m, pb2.E_Ext_Number, proto.Int32(1)); err != nil { + t.Fatalf("SetExtension: %v", err) + } + + // Serialize m several times, and check we get the same bytes each time. + var orig []byte + for i := 0; i < 100; i++ { + b, err := proto.Marshal(m) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + if i == 0 { + orig = b + continue + } + if !bytes.Equal(b, orig) { + t.Errorf("Bytes differ on attempt #%d", i) + } + } +} + +func TestExtensionMapFieldMarshalDeterministic(t *testing.T) { + m := &pb2.MyMessage{Count: proto.Int(123)} + if err := proto.SetExtension(m, pb2.E_Ext_More, &pb2.Ext{MapField: map[int32]int32{1: 1, 2: 2, 3: 3, 4: 4}}); err != nil { + t.Fatalf("SetExtension: %v", err) + } + marshal := func(m proto.Message) []byte { + var b proto.Buffer + b.SetDeterministic(true) + if err := b.Marshal(m); err != nil { + t.Fatalf("Marshal failed: %v", err) + } + return b.Bytes() + } + + want := marshal(m) + for i := 0; i < 100; i++ { + if got := marshal(m); !bytes.Equal(got, want) { + t.Errorf("Marshal produced inconsistent output with determinism enabled (pass %d).\n got %v\nwant %v", i, got, want) + } + } +} + +func TestUnmarshalMergesMessages(t *testing.T) { + // If a nested message occurs twice in the input, + // the fields should be merged when decoding. + a := &pb2.OtherMessage{ + Key: proto.Int64(123), + Inner: &pb2.InnerMessage{ + Host: proto.String("polhode"), + Port: proto.Int32(1234), + }, + } + aData, err := proto.Marshal(a) + if err != nil { + t.Fatalf("Marshal(a): %v", err) + } + b := &pb2.OtherMessage{ + Weight: proto.Float32(1.2), + Inner: &pb2.InnerMessage{ + Host: proto.String("herpolhode"), + Connected: proto.Bool(true), + }, + } + bData, err := proto.Marshal(b) + if err != nil { + t.Fatalf("Marshal(b): %v", err) + } + want := &pb2.OtherMessage{ + Key: proto.Int64(123), + Weight: proto.Float32(1.2), + Inner: &pb2.InnerMessage{ + Host: proto.String("herpolhode"), + Port: proto.Int32(1234), + Connected: proto.Bool(true), + }, + } + got := new(pb2.OtherMessage) + if err := proto.Unmarshal(append(aData, bData...), got); err != nil { + t.Fatalf("Unmarshal: %v", err) + } + if !proto.Equal(got, want) { + t.Errorf("\n got %v\nwant %v", got, want) + } +} + +func TestUnmarshalMergesGroups(t *testing.T) { + // If a nested group occurs twice in the input, + // the fields should be merged when decoding. + a := &pb2.GroupNew{ + G: &pb2.GroupNew_G{ + X: proto.Int32(7), + Y: proto.Int32(8), + }, + } + aData, err := proto.Marshal(a) + if err != nil { + t.Fatalf("Marshal(a): %v", err) + } + b := &pb2.GroupNew{ + G: &pb2.GroupNew_G{ + X: proto.Int32(9), + }, + } + bData, err := proto.Marshal(b) + if err != nil { + t.Fatalf("Marshal(b): %v", err) + } + want := &pb2.GroupNew{ + G: &pb2.GroupNew_G{ + X: proto.Int32(9), + Y: proto.Int32(8), + }, + } + got := new(pb2.GroupNew) + if err := proto.Unmarshal(append(aData, bData...), got); err != nil { + t.Fatalf("Unmarshal: %v", err) + } + if !proto.Equal(got, want) { + t.Errorf("\n got %v\nwant %v", got, want) + } +} + +func TestEncodingSizes(t *testing.T) { + tests := []struct { + m proto.Message + n int + }{ + {&pb2.Defaults{F_Int32: proto.Int32(math.MaxInt32)}, 6}, + {&pb2.Defaults{F_Int32: proto.Int32(math.MinInt32)}, 11}, + {&pb2.Defaults{F_Uint32: proto.Uint32(uint32(math.MaxInt32) + 1)}, 6}, + {&pb2.Defaults{F_Uint32: proto.Uint32(math.MaxUint32)}, 6}, + } + for _, test := range tests { + b, err := proto.Marshal(test.m) + if err != nil { + t.Errorf("Marshal(%v): %v", test.m, err) + continue + } + if len(b) != test.n { + t.Errorf("Marshal(%v) yielded %d bytes, want %d bytes", test.m, len(b), test.n) + } + } +} + +func TestRequiredNotSetError(t *testing.T) { + pb := initGoTest(false) + pb.RequiredField.Label = nil + pb.F_Int32Required = nil + pb.F_Int64Required = nil + + want := protopack.Message{ + protopack.Tag{1, protopack.VarintType}, protopack.Uvarint(7), + protopack.Tag{4, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{ + protopack.Tag{2, protopack.BytesType}, protopack.String("type"), + }), + protopack.Tag{10, protopack.VarintType}, protopack.Bool(true), + protopack.Tag{13, protopack.Fixed32Type}, protopack.Uint32(32), + protopack.Tag{14, protopack.Fixed64Type}, protopack.Uint64(64), + protopack.Tag{15, protopack.VarintType}, protopack.Uvarint(3232), + protopack.Tag{16, protopack.VarintType}, protopack.Uvarint(6464), + protopack.Tag{17, protopack.Fixed32Type}, protopack.Float32(3232), + protopack.Tag{18, protopack.Fixed64Type}, protopack.Float64(6464), + protopack.Tag{19, protopack.BytesType}, protopack.String("string"), + protopack.Tag{70, protopack.StartGroupType}, + protopack.Message{ + protopack.Tag{71, protopack.BytesType}, protopack.String("required"), + }, + protopack.Tag{70, protopack.EndGroupType}, + protopack.Tag{101, protopack.BytesType}, protopack.Bytes("bytes"), + protopack.Tag{102, protopack.VarintType}, protopack.Svarint(-32), + protopack.Tag{103, protopack.VarintType}, protopack.Svarint(-64), + protopack.Tag{104, protopack.Fixed32Type}, protopack.Int32(-32), + protopack.Tag{105, protopack.Fixed64Type}, protopack.Int64(-64), + }.Marshal() + + got, err := proto.Marshal(pb) + if !isRequiredNotSetError(err) { + t.Logf("marshal-1 err = %v, want *RequiredNotSetError", err) + t.Fatalf("got %q\nwant %q", got, want) + } + if !bytes.Equal(got, want) { + t.Fatalf("got %q\nwant %q", got, want) + } + + // Now test Unmarshal by recreating the original buffer. + pbd := new(pb2.GoTest) + err = proto.Unmarshal(got, pbd) + if !isRequiredNotSetError(err) { + t.Errorf("unmarshal err = %v, want *RequiredNotSetError", err) + t.Fatalf("got %q\nwant %q", got, want) + } + got, err = proto.Marshal(pbd) + if !isRequiredNotSetError(err) { + t.Errorf("marshal-2 err = %v, want *RequiredNotSetError", err) + t.Fatalf("got %q\nwant %q", got, want) + } + if !bytes.Equal(got, want) { + t.Fatalf("got %q\nwant %q", got, want) + } +} + +func TestRequiredNotSetErrorWithBadWireTypes(t *testing.T) { + // Required field expects a varint, and properly found a varint. + if err := proto.Unmarshal([]byte{0x08, 0x00}, new(pb2.GoEnum)); err != nil { + t.Errorf("Unmarshal = %v, want nil", err) + } + // Required field expects a varint, but found a fixed32 instead. + if err := proto.Unmarshal([]byte{0x0d, 0x00, 0x00, 0x00, 0x00}, new(pb2.GoEnum)); err == nil { + t.Errorf("Unmarshal = nil, want RequiredNotSetError") + } + // Required field expects a varint, and found both a varint and fixed32 (ignored). + m := new(pb2.GoEnum) + if err := proto.Unmarshal([]byte{0x08, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00}, m); err != nil { + t.Errorf("Unmarshal = %v, want nil", err) + } + if !bytes.Equal(m.XXX_unrecognized, []byte{0x0d, 0x00, 0x00, 0x00, 0x00}) { + t.Errorf("expected fixed32 to appear as unknown bytes: %x", m.XXX_unrecognized) + } +} + +func fuzzUnmarshal(t *testing.T, data []byte) { + defer func() { + if e := recover(); e != nil { + t.Errorf("These bytes caused a panic: %+v", data) + t.Logf("Stack:\n%s", debug.Stack()) + t.FailNow() + } + }() + + pb := new(pb2.MyMessage) + proto.Unmarshal(data, pb) +} + +func TestMapFieldMarshal(t *testing.T) { + m := &pb2.MessageWithMap{ + NameMapping: map[int32]string{ + 1: "Rob", + 4: "Ian", + 8: "Dave", + }, + } + b, err := proto.Marshal(m) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + + // b should be the concatenation of these three byte sequences in some order. + parts := []string{ + "\n\a\b\x01\x12\x03Rob", + "\n\a\b\x04\x12\x03Ian", + "\n\b\b\x08\x12\x04Dave", + } + ok := false + for i := range parts { + for j := range parts { + if j == i { + continue + } + for k := range parts { + if k == i || k == j { + continue + } + try := parts[i] + parts[j] + parts[k] + if bytes.Equal(b, []byte(try)) { + ok = true + break + } + } + } + } + if !ok { + t.Fatalf("Incorrect Marshal output.\n got %q\nwant %q (or a permutation of that)", b, parts[0]+parts[1]+parts[2]) + } + t.Logf("FYI b: %q", b) +} + +func TestMapFieldDeterministicMarshal(t *testing.T) { + m := &pb2.MessageWithMap{ + NameMapping: map[int32]string{ + 1: "Rob", + 4: "Ian", + 8: "Dave", + }, + } + + marshal := func(m proto.Message) []byte { + var b proto.Buffer + b.SetDeterministic(true) + if err := b.Marshal(m); err != nil { + t.Fatalf("Marshal failed: %v", err) + } + return b.Bytes() + } + + want := marshal(m) + for i := 0; i < 10; i++ { + if got := marshal(m); !bytes.Equal(got, want) { + t.Errorf("Marshal produced inconsistent output with determinism enabled (pass %d).\n got %v\nwant %v", i, got, want) + } + } +} + +func TestMapFieldRoundTrips(t *testing.T) { + m := &pb2.MessageWithMap{ + NameMapping: map[int32]string{ + 1: "Rob", + 4: "Ian", + 8: "Dave", + }, + MsgMapping: map[int64]*pb2.FloatingPoint{ + 0x7001: {F: proto.Float64(2.0)}, + }, + ByteMapping: map[bool][]byte{ + false: []byte("that's not right!"), + true: []byte("aye, 'tis true!"), + }, + } + b, err := proto.Marshal(m) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + t.Logf("FYI b: %q", b) + m2 := new(pb2.MessageWithMap) + if err := proto.Unmarshal(b, m2); err != nil { + t.Fatalf("Unmarshal: %v", err) + } + if !proto.Equal(m, m2) { + t.Errorf("Map did not survive a round trip.\ninitial: %v\n final: %v", m, m2) + } +} + +func TestMapFieldWithNil(t *testing.T) { + m1 := &pb2.MessageWithMap{ + MsgMapping: map[int64]*pb2.FloatingPoint{ + 1: nil, + }, + } + b, err := proto.Marshal(m1) + if _, ok := err.(*proto.RequiredNotSetError); !ok { + t.Fatalf("Marshal(%v): err=%v, want RequiredNotSet", m1, err) + } + m2 := new(pb2.MessageWithMap) + err = proto.Unmarshal(b, m2) + if _, ok := err.(*proto.RequiredNotSetError); !ok { + t.Fatalf("Unmarshal(%v): err=%v, want RequiredNotSet", m1, err) + } + if !proto.Equal(m1, m2) { + t.Fatalf("roundtrip marshal/unmarshal changed message; got:\n%v\nwant:\n%v", m2, m1) + } +} + +func TestMapFieldWithNilBytes(t *testing.T) { + m1 := &pb2.MessageWithMap{ + ByteMapping: map[bool][]byte{ + false: {}, + true: nil, + }, + } + n := proto.Size(m1) + b, err := proto.Marshal(m1) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + if n != len(b) { + t.Errorf("Size(m1) = %d; want len(Marshal(m1)) = %d", n, len(b)) + } + m2 := new(pb2.MessageWithMap) + if err := proto.Unmarshal(b, m2); err != nil { + t.Fatalf("Unmarshal: %v, got these bytes: %v", err, b) + } + if v, ok := m2.ByteMapping[false]; !ok { + t.Error("byte_mapping[false] not present") + } else if len(v) != 0 { + t.Errorf("byte_mapping[false] not empty: %#v", v) + } + if v, ok := m2.ByteMapping[true]; !ok { + t.Error("byte_mapping[true] not present") + } else if len(v) != 0 { + t.Errorf("byte_mapping[true] not empty: %#v", v) + } +} + +func TestDecodeMapFieldMissingKey(t *testing.T) { + b := []byte{ + 0x0A, 0x03, // message, tag 1 (name_mapping), of length 3 bytes + // no key + 0x12, 0x01, 0x6D, // string value of length 1 byte, value "m" + } + got := &pb2.MessageWithMap{} + err := proto.Unmarshal(b, got) + if err != nil { + t.Fatalf("failed to marshal map with missing key: %v", err) + } + want := &pb2.MessageWithMap{NameMapping: map[int32]string{0: "m"}} + if !proto.Equal(got, want) { + t.Errorf("Unmarshaled map with no key was not as expected. got: %v, want %v", got, want) + } +} + +func TestDecodeMapFieldMissingValue(t *testing.T) { + b := protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{ + protopack.Tag{1, protopack.VarintType}, protopack.Uvarint(1), + }), + }.Marshal() + got := &pb2.MessageWithMap{} + err := proto.Unmarshal(b, got) + if err != nil { + t.Fatalf("failed to marshal map with missing value: %v", err) + } + want := &pb2.MessageWithMap{NameMapping: map[int32]string{1: ""}} + if !proto.Equal(got, want) { + t.Errorf("Unmarshaled map with no value was not as expected. got: %v, want %v", got, want) + } +} + +func TestOneof(t *testing.T) { + m := &pb2.Communique{} + b, err := proto.Marshal(m) + if err != nil { + t.Fatalf("Marshal of empty message with oneof: %v", err) + } + if len(b) != 0 { + t.Errorf("Marshal of empty message yielded too many bytes: %v", b) + } + + m = &pb2.Communique{ + Union: &pb2.Communique_Name{"Barry"}, + } + + // Round-trip. + b, err = proto.Marshal(m) + if err != nil { + t.Fatalf("Marshal of message with oneof: %v", err) + } + if len(b) != 7 { // name tag/wire (1) + name len (1) + name (5) + t.Errorf("Incorrect marshal of message with oneof: %v", b) + } + m.Reset() + if err := proto.Unmarshal(b, m); err != nil { + t.Fatalf("Unmarshal of message with oneof: %v", err) + } + if x, ok := m.Union.(*pb2.Communique_Name); !ok || x.Name != "Barry" { + t.Errorf("After round trip, Union = %+v", m.Union) + } + if name := m.GetName(); name != "Barry" { + t.Errorf("After round trip, GetName = %q, want %q", name, "Barry") + } + + // Let's try with a message in the oneof. + m.Union = &pb2.Communique_Msg{&pb2.Strings{StringField: proto.String("deep deep string")}} + b, err = proto.Marshal(m) + if err != nil { + t.Fatalf("Marshal of message with oneof set to message: %v", err) + } + if len(b) != 20 { // msg tag/wire (1) + msg len (1) + msg (1 + 1 + 16) + t.Errorf("Incorrect marshal of message with oneof set to message: %v", b) + } + m.Reset() + if err := proto.Unmarshal(b, m); err != nil { + t.Fatalf("Unmarshal of message with oneof set to message: %v", err) + } + ss, ok := m.Union.(*pb2.Communique_Msg) + if !ok || ss.Msg.GetStringField() != "deep deep string" { + t.Errorf("After round trip with oneof set to message, Union = %+v", m.Union) + } +} + +func TestOneofNilBytes(t *testing.T) { + // A oneof with nil byte slice should marshal to tag + 0 (size), with no error. + m := &pb2.Communique{Union: &pb2.Communique_Data{Data: nil}} + b, err := proto.Marshal(m) + if err != nil { + t.Fatalf("Marshal failed: %v", err) + } + want := protopack.Message{ + protopack.Tag{7, protopack.BytesType}, protopack.Bytes(""), + }.Marshal() + if !bytes.Equal(b, want) { + t.Errorf("Wrong result of Marshal: got %x, want %x", b, want) + } +} + +func TestInefficientPackedBool(t *testing.T) { + // https://github.com/golang/protobuf/issues/76 + inp := protopack.Message{ + protopack.Tag{2, protopack.BytesType}, protopack.Bytes("\xb90"), + }.Marshal() + if err := proto.Unmarshal(inp, new(pb2.MoreRepeated)); err != nil { + t.Error(err) + } +} + +// Make sure pure-reflect-based implementation handles +// []int32-[]enum conversion correctly. +func TestRepeatedEnum2(t *testing.T) { + pb := &pb2.RepeatedEnum{ + Color: []pb2.RepeatedEnum_Color{pb2.RepeatedEnum_RED}, + } + b, err := proto.Marshal(pb) + if err != nil { + t.Fatalf("Marshal failed: %v", err) + } + x := new(pb2.RepeatedEnum) + err = proto.Unmarshal(b, x) + if err != nil { + t.Fatalf("Unmarshal failed: %v", err) + } + if !proto.Equal(pb, x) { + t.Errorf("Incorrect result: want: %v got: %v", pb, x) + } +} + +// TestConcurrentMarshal makes sure that it is safe to marshal +// same message in multiple goroutines concurrently. +func TestConcurrentMarshal(t *testing.T) { + pb := initGoTest(true) + const N = 100 + b := make([][]byte, N) + + var wg sync.WaitGroup + for i := 0; i < N; i++ { + wg.Add(1) + go func(i int) { + defer wg.Done() + var err error + b[i], err = proto.Marshal(pb) + if err != nil { + t.Errorf("marshal error: %v", err) + } + }(i) + } + + wg.Wait() + for i := 1; i < N; i++ { + if !bytes.Equal(b[0], b[i]) { + t.Errorf("concurrent marshal result not same: b[0] = %v, b[%d] = %v", b[0], i, b[i]) + } + } +} + +func TestInvalidUTF8(t *testing.T) { + const invalidUTF8 = "\xde\xad\xbe\xef\x80\x00\xff" + tests := []struct { + label string + proto2 proto.Message + proto3 proto.Message + want []byte + }{{ + label: "Scalar", + proto2: &pb2.TestUTF8{Scalar: proto.String(invalidUTF8)}, + proto3: &pb3.TestUTF8{Scalar: invalidUTF8}, + want: []byte{0x0a, 0x07, 0xde, 0xad, 0xbe, 0xef, 0x80, 0x00, 0xff}, + }, { + label: "Vector", + proto2: &pb2.TestUTF8{Vector: []string{invalidUTF8}}, + proto3: &pb3.TestUTF8{Vector: []string{invalidUTF8}}, + want: []byte{0x12, 0x07, 0xde, 0xad, 0xbe, 0xef, 0x80, 0x00, 0xff}, + }, { + label: "Oneof", + proto2: &pb2.TestUTF8{Oneof: &pb2.TestUTF8_Field{invalidUTF8}}, + proto3: &pb3.TestUTF8{Oneof: &pb3.TestUTF8_Field{invalidUTF8}}, + want: []byte{0x1a, 0x07, 0xde, 0xad, 0xbe, 0xef, 0x80, 0x00, 0xff}, + }, { + label: "MapKey", + proto2: &pb2.TestUTF8{MapKey: map[string]int64{invalidUTF8: 0}}, + proto3: &pb3.TestUTF8{MapKey: map[string]int64{invalidUTF8: 0}}, + want: []byte{0x22, 0x0b, 0x0a, 0x07, 0xde, 0xad, 0xbe, 0xef, 0x80, 0x00, 0xff, 0x10, 0x00}, + }, { + label: "MapValue", + proto2: &pb2.TestUTF8{MapValue: map[int64]string{0: invalidUTF8}}, + proto3: &pb3.TestUTF8{MapValue: map[int64]string{0: invalidUTF8}}, + want: []byte{0x2a, 0x0b, 0x08, 0x00, 0x12, 0x07, 0xde, 0xad, 0xbe, 0xef, 0x80, 0x00, 0xff}, + }} + + for _, tt := range tests { + // Proto2 should not validate UTF-8. + b, err := proto.Marshal(tt.proto2) + if err != nil { + t.Errorf("Marshal(proto2.%s) = %v, want nil", tt.label, err) + } + if !bytes.Equal(b, tt.want) { + t.Errorf("Marshal(proto2.%s) = %x, want %x", tt.label, b, tt.want) + } + + m := proto.Clone(tt.proto2) + m.Reset() + if err = proto.Unmarshal(tt.want, m); err != nil { + t.Errorf("Unmarshal(proto2.%s) = %v, want nil", tt.label, err) + } + if !proto.Equal(m, tt.proto2) { + t.Errorf("proto2.%s: output mismatch:\ngot %v\nwant %v", tt.label, m, tt.proto2) + } + + // Proto3 should validate UTF-8. + if _, err := proto.Marshal(tt.proto3); err == nil { + t.Errorf("Marshal(proto3.%s) = %v, want non-nil", tt.label, err) + } + + m = proto.Clone(tt.proto3) + m.Reset() + if err := proto.Unmarshal(tt.want, m); err == nil { + t.Errorf("Unmarshal(proto3.%s) = %v, want non-nil", tt.label, err) + } + } +} + +func TestRequired(t *testing.T) { + // The F_BoolRequired field appears after all of the required fields. + // It should still be handled even after multiple required field violations. + m := &pb2.GoTest{F_BoolRequired: proto.Bool(true)} + got, err := proto.Marshal(m) + if !isRequiredNotSetError(err) { + t.Errorf("Marshal() = %v, want RequiredNotSetError error", err) + } + if want := []byte{0x50, 0x01}; !bytes.Equal(got, want) { + t.Errorf("Marshal() = %x, want %x", got, want) + } + + m = new(pb2.GoTest) + err = proto.Unmarshal(got, m) + if !isRequiredNotSetError(err) { + t.Errorf("Marshal() = %v, want RequiredNotSetError error", err) + } + if !m.GetF_BoolRequired() { + t.Error("m.F_BoolRequired = false, want true") + } +} + +func TestUnknownV2(t *testing.T) { + m := new(tspb.Timestamp) + m.ProtoReflect().SetUnknown([]byte("\x92\x4d\x12unknown field 1234")) + got := proto.CompactTextString(m) + if !strings.Contains(got, "unknown field 1234") { + t.Errorf("got %q, want contains %q", got, "unknown field 1234") + } +} + +func testMsg() *pb2.GoTest { + pb := initGoTest(true) + const N = 1000 // Internally the library starts much smaller. + pb.F_Int32Repeated = make([]int32, N) + pb.F_DoubleRepeated = make([]float64, N) + for i := 0; i < N; i++ { + pb.F_Int32Repeated[i] = int32(i) + pb.F_DoubleRepeated[i] = float64(i) + } + return pb +} + +func bytesMsg() *pb2.GoTest { + pb := initGoTest(true) + buf := make([]byte, 4000) + for i := range buf { + buf[i] = byte(i) + } + pb.F_BytesDefaulted = buf + return pb +} + +func benchmarkMarshal(b *testing.B, pb proto.Message, marshal func(proto.Message) ([]byte, error)) { + d, _ := marshal(pb) + b.SetBytes(int64(len(d))) + b.ResetTimer() + for i := 0; i < b.N; i++ { + marshal(pb) + } +} + +func benchmarkBufferMarshal(b *testing.B, pb proto.Message) { + p := proto.NewBuffer(nil) + benchmarkMarshal(b, pb, func(pb0 proto.Message) ([]byte, error) { + p.Reset() + err := p.Marshal(pb0) + return p.Bytes(), err + }) +} + +func benchmarkSize(b *testing.B, pb proto.Message) { + benchmarkMarshal(b, pb, func(pb0 proto.Message) ([]byte, error) { + proto.Size(pb) + return nil, nil + }) +} + +func TestProto3ZeroValues(t *testing.T) { + tests := []struct { + desc string + m proto.Message + }{ + {"zero message", &pb3.Message{}}, + {"empty bytes field", &pb3.Message{Data: []byte{}}}, + } + for _, test := range tests { + b, err := proto.Marshal(test.m) + if err != nil { + t.Errorf("%s: proto.Marshal: %v", test.desc, err) + continue + } + if len(b) > 0 { + t.Errorf("%s: Encoding is non-empty: %q", test.desc, b) + } + } +} + +func TestRoundTripProto3(t *testing.T) { + m := &pb3.Message{ + Name: "David", // (2 | 1<<3): 0x0a 0x05 "David" + Hilarity: pb3.Message_PUNS, // (0 | 2<<3): 0x10 0x01 + HeightInCm: 178, // (0 | 3<<3): 0x18 0xb2 0x01 + Data: []byte("roboto"), // (2 | 4<<3): 0x20 0x06 "roboto" + ResultCount: 47, // (0 | 7<<3): 0x38 0x2f + TrueScotsman: true, // (0 | 8<<3): 0x40 0x01 + Score: 8.1, // (5 | 9<<3): 0x4d <8.1> + + Key: []uint64{1, 0xdeadbeef}, + Nested: &pb3.Nested{ + Bunny: "Monty", + }, + } + t.Logf(" m: %v", m) + + b, err := proto.Marshal(m) + if err != nil { + t.Fatalf("proto.Marshal: %v", err) + } + t.Logf(" b: %q", b) + + m2 := new(pb3.Message) + if err := proto.Unmarshal(b, m2); err != nil { + t.Fatalf("proto.Unmarshal: %v", err) + } + t.Logf("m2: %v", m2) + + if !proto.Equal(m, m2) { + t.Errorf("proto.Equal returned false:\n m: %v\nm2: %v", m, m2) + } +} + +func TestGettersForBasicTypesExist(t *testing.T) { + var m pb3.Message + if got := m.GetNested().GetBunny(); got != "" { + t.Errorf("m.GetNested().GetBunny() = %q, want empty string", got) + } + if got := m.GetNested().GetCute(); got { + t.Errorf("m.GetNested().GetCute() = %t, want false", got) + } +} + +func TestProto3SetDefaults(t *testing.T) { + in := &pb3.Message{ + Terrain: map[string]*pb3.Nested{ + "meadow": new(pb3.Nested), + }, + Proto2Field: new(pb2.SubDefaults), + Proto2Value: map[string]*pb2.SubDefaults{ + "badlands": new(pb2.SubDefaults), + }, + } + + got := proto.Clone(in).(*pb3.Message) + proto.SetDefaults(got) + + // There are no defaults in proto3. Everything should be the zero value, but + // we need to remember to set defaults for nested proto2 messages. + want := &pb3.Message{ + Terrain: map[string]*pb3.Nested{ + "meadow": new(pb3.Nested), + }, + Proto2Field: &pb2.SubDefaults{N: proto.Int64(7)}, + Proto2Value: map[string]*pb2.SubDefaults{ + "badlands": &pb2.SubDefaults{N: proto.Int64(7)}, + }, + } + + if !proto.Equal(got, want) { + t.Errorf("with in = %v\nproto.SetDefaults(in) =>\ngot %v\nwant %v", in, got, want) + } +} + +func TestUnknownFieldPreservation(t *testing.T) { + b1 := "\x0a\x05David" // Known tag 1 + b2 := "\xc2\x0c\x06Google" // Unknown tag 200 + b := []byte(b1 + b2) + + m := new(pb3.Message) + if err := proto.Unmarshal(b, m); err != nil { + t.Fatalf("proto.Unmarshal: %v", err) + } + + if !bytes.Equal(m.XXX_unrecognized, []byte(b2)) { + t.Fatalf("mismatching unknown fields:\ngot %q\nwant %q", m.XXX_unrecognized, b2) + } +} + +func TestMap(t *testing.T) { + b := protopack.Message{ + protopack.Tag{20, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.String("Key1"), + protopack.Tag{2, protopack.BytesType}, protopack.String("Val1"), + }), + protopack.Tag{20, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.String("Key2"), + protopack.Tag{2, protopack.BytesType}, protopack.String("Val2a"), + protopack.Tag{2, protopack.BytesType}, protopack.String("Val2"), + }), + protopack.Tag{20, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.String("Key3"), + protopack.Tag{1, protopack.Fixed32Type}, protopack.Uint32(5), + protopack.Tag{2, protopack.BytesType}, protopack.String("Val3b"), + protopack.Tag{3, protopack.BytesType}, protopack.Bytes("Val3a"), + protopack.Tag{2, protopack.BytesType}, protopack.String("Val3"), + protopack.Tag{2, protopack.Fixed32Type}, protopack.Uint32(5), + }), + protopack.Tag{20, protopack.BytesType}, protopack.LengthPrefix{}, + protopack.Tag{20, protopack.BytesType}, protopack.LengthPrefix(protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.String("Key4"), + protopack.Tag{2, protopack.StartGroupType}, + protopack.Message{ + protopack.Tag{1, protopack.BytesType}, protopack.Bytes("SomeURL"), + protopack.Tag{2, protopack.BytesType}, protopack.Bytes("SomeTitle"), + protopack.Tag{3, protopack.BytesType}, protopack.Bytes("Snippet1"), + }, + protopack.Tag{2, protopack.EndGroupType}, + }), + }.Marshal() + + var m pb3.Message + if err := proto.Unmarshal(b, &m); err != nil { + t.Fatalf("proto.Unmarshal error: %v", err) + } + + got := m.StringMap + want := map[string]string{ + "": "", + "Key1": "Val1", + "Key2": "Val2", + "Key3": "Val3", + "Key4": "", + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("maps differ:\ngot %#v\nwant %#v", got, want) + } +} + +func marshalled() []byte { + m := &pb3.IntMaps{} + for i := 0; i < 1000; i++ { + m.Maps = append(m.Maps, &pb3.IntMap{ + Rtt: map[int32]int32{1: 2}, + }) + } + b, err := proto.Marshal(m) + if err != nil { + panic(fmt.Sprintf("Can't marshal %+v: %v", m, err)) + } + return b +} + +var messageWithExtension1 = &pb2.MyMessage{Count: proto.Int32(7)} + +// messageWithExtension2 is in equal_test.go. +var messageWithExtension3 = &pb2.MyMessage{Count: proto.Int32(8)} + +func init() { + if err := proto.SetExtension(messageWithExtension1, pb2.E_Ext_More, &pb2.Ext{Data: proto.String("Abbott")}); err != nil { + log.Panicf("proto.SetExtension: %v", err) + } + if err := proto.SetExtension(messageWithExtension3, pb2.E_Ext_More, &pb2.Ext{Data: proto.String("Costello")}); err != nil { + log.Panicf("proto.SetExtension: %v", err) + } + + // Force messageWithExtension3 to have the extension encoded. + proto.Marshal(messageWithExtension3) + +} + +// non-pointer custom message +type nonptrMessage struct{} + +func (m nonptrMessage) ProtoMessage() {} +func (m nonptrMessage) Reset() {} +func (m nonptrMessage) String() string { return "" } + +func (m nonptrMessage) Marshal() ([]byte, error) { + return []byte{42}, nil +} + +var SizeTests = []struct { + desc string + pb proto.Message +}{ + {"empty", &pb2.OtherMessage{}}, + // Basic types. + {"bool", &pb2.Defaults{F_Bool: proto.Bool(true)}}, + {"int32", &pb2.Defaults{F_Int32: proto.Int32(12)}}, + {"negative int32", &pb2.Defaults{F_Int32: proto.Int32(-1)}}, + {"small int64", &pb2.Defaults{F_Int64: proto.Int64(1)}}, + {"big int64", &pb2.Defaults{F_Int64: proto.Int64(1 << 20)}}, + {"negative int64", &pb2.Defaults{F_Int64: proto.Int64(-1)}}, + {"fixed32", &pb2.Defaults{F_Fixed32: proto.Uint32(71)}}, + {"fixed64", &pb2.Defaults{F_Fixed64: proto.Uint64(72)}}, + {"uint32", &pb2.Defaults{F_Uint32: proto.Uint32(123)}}, + {"uint64", &pb2.Defaults{F_Uint64: proto.Uint64(124)}}, + {"float", &pb2.Defaults{F_Float: proto.Float32(12.6)}}, + {"double", &pb2.Defaults{F_Double: proto.Float64(13.9)}}, + {"string", &pb2.Defaults{F_String: proto.String("niles")}}, + {"bytes", &pb2.Defaults{F_Bytes: []byte("wowsa")}}, + {"bytes, empty", &pb2.Defaults{F_Bytes: []byte{}}}, + {"sint32", &pb2.Defaults{F_Sint32: proto.Int32(65)}}, + {"sint64", &pb2.Defaults{F_Sint64: proto.Int64(67)}}, + {"enum", &pb2.Defaults{F_Enum: pb2.Defaults_BLUE.Enum()}}, + // Repeated. + {"empty repeated bool", &pb2.MoreRepeated{Bools: []bool{}}}, + {"repeated bool", &pb2.MoreRepeated{Bools: []bool{false, true, true, false}}}, + {"packed repeated bool", &pb2.MoreRepeated{BoolsPacked: []bool{false, true, true, false, true, true, true}}}, + {"repeated int32", &pb2.MoreRepeated{Ints: []int32{1, 12203, 1729, -1}}}, + {"repeated int32 packed", &pb2.MoreRepeated{IntsPacked: []int32{1, 12203, 1729}}}, + {"repeated int64 packed", &pb2.MoreRepeated{Int64SPacked: []int64{ + // Need enough large numbers to verify that the header is counting the number of bytes + // for the field, not the number of elements. + 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, + 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, + }}}, + {"repeated string", &pb2.MoreRepeated{Strings: []string{"r", "ken", "gri"}}}, + {"repeated fixed", &pb2.MoreRepeated{Fixeds: []uint32{1, 2, 3, 4}}}, + // Nested. + {"nested", &pb2.OldMessage{Nested: &pb2.OldMessage_Nested{Name: proto.String("whatever")}}}, + {"group", &pb2.GroupOld{G: &pb2.GroupOld_G{X: proto.Int32(12345)}}}, + // Other things. + {"unrecognized", &pb2.MoreRepeated{XXX_unrecognized: []byte{13<<3 | 0, 4}}}, + {"extension (unencoded)", messageWithExtension1}, + {"extension (encoded)", messageWithExtension3}, + // proto3 message + {"proto3 empty", &pb3.Message{}}, + {"proto3 bool", &pb3.Message{TrueScotsman: true}}, + {"proto3 int64", &pb3.Message{ResultCount: 1}}, + {"proto3 uint32", &pb3.Message{HeightInCm: 123}}, + {"proto3 float", &pb3.Message{Score: 12.6}}, + {"proto3 string", &pb3.Message{Name: "Snezana"}}, + {"proto3 bytes", &pb3.Message{Data: []byte("wowsa")}}, + {"proto3 bytes, empty", &pb3.Message{Data: []byte{}}}, + {"proto3 enum", &pb3.Message{Hilarity: pb3.Message_PUNS}}, + {"proto3 map field with empty bytes", &pb3.MessageWithMap{ByteMapping: map[bool][]byte{false: []byte{}}}}, + + {"map field", &pb2.MessageWithMap{NameMapping: map[int32]string{1: "Rob", 7: "Andrew"}}}, + {"map field with message", &pb2.MessageWithMap{MsgMapping: map[int64]*pb2.FloatingPoint{0x7001: &pb2.FloatingPoint{F: proto.Float64(2.0)}}}}, + {"map field with bytes", &pb2.MessageWithMap{ByteMapping: map[bool][]byte{true: []byte("this time for sure")}}}, + {"map field with empty bytes", &pb2.MessageWithMap{ByteMapping: map[bool][]byte{true: []byte{}}}}, + + {"map field with big entry", &pb2.MessageWithMap{NameMapping: map[int32]string{8: strings.Repeat("x", 125)}}}, + {"map field with big key and val", &pb2.MessageWithMap{StrToStr: map[string]string{strings.Repeat("x", 70): strings.Repeat("y", 70)}}}, + {"map field with big numeric key", &pb2.MessageWithMap{NameMapping: map[int32]string{0xf00d: "om nom nom"}}}, + + {"oneof not set", &pb2.Oneof{}}, + {"oneof bool", &pb2.Oneof{Union: &pb2.Oneof_F_Bool{true}}}, + {"oneof zero int32", &pb2.Oneof{Union: &pb2.Oneof_F_Int32{0}}}, + {"oneof big int32", &pb2.Oneof{Union: &pb2.Oneof_F_Int32{1 << 20}}}, + {"oneof int64", &pb2.Oneof{Union: &pb2.Oneof_F_Int64{42}}}, + {"oneof fixed32", &pb2.Oneof{Union: &pb2.Oneof_F_Fixed32{43}}}, + {"oneof fixed64", &pb2.Oneof{Union: &pb2.Oneof_F_Fixed64{44}}}, + {"oneof uint32", &pb2.Oneof{Union: &pb2.Oneof_F_Uint32{45}}}, + {"oneof uint64", &pb2.Oneof{Union: &pb2.Oneof_F_Uint64{46}}}, + {"oneof float", &pb2.Oneof{Union: &pb2.Oneof_F_Float{47.1}}}, + {"oneof double", &pb2.Oneof{Union: &pb2.Oneof_F_Double{48.9}}}, + {"oneof string", &pb2.Oneof{Union: &pb2.Oneof_F_String{"Rhythmic Fman"}}}, + {"oneof bytes", &pb2.Oneof{Union: &pb2.Oneof_F_Bytes{[]byte("let go")}}}, + {"oneof sint32", &pb2.Oneof{Union: &pb2.Oneof_F_Sint32{50}}}, + {"oneof sint64", &pb2.Oneof{Union: &pb2.Oneof_F_Sint64{51}}}, + {"oneof enum", &pb2.Oneof{Union: &pb2.Oneof_F_Enum{pb2.MyMessage_BLUE}}}, + {"message for oneof", &pb2.GoTestField{Label: proto.String("k"), Type: proto.String("v")}}, + {"oneof message", &pb2.Oneof{Union: &pb2.Oneof_F_Message{&pb2.GoTestField{Label: proto.String("k"), Type: proto.String("v")}}}}, + {"oneof group", &pb2.Oneof{Union: &pb2.Oneof_FGroup{&pb2.Oneof_F_Group{X: proto.Int32(52)}}}}, + {"oneof largest tag", &pb2.Oneof{Union: &pb2.Oneof_F_Largest_Tag{1}}}, + {"multiple oneofs", &pb2.Oneof{Union: &pb2.Oneof_F_Int32{1}, Tormato: &pb2.Oneof_Value{2}}}, + + {"non-pointer message", nonptrMessage{}}, +} + +func TestSize(t *testing.T) { + for _, tc := range SizeTests { + t.Run(tc.desc, func(t *testing.T) { + size := proto.Size(tc.pb) + b, err := proto.Marshal(tc.pb) + if err != nil { + t.Errorf("%v: Marshal failed: %v", tc.desc, err) + return + } + if size != len(b) { + t.Errorf("%v: Size(%v) = %d, want %d", tc.desc, tc.pb, size, len(b)) + t.Logf("%v: bytes: %#v", tc.desc, b) + } + }) + } +} + +func TestVarintSize(t *testing.T) { + // Check the edge cases carefully. + testCases := []struct { + n uint64 + size int + }{ + {0, 1}, + {1, 1}, + {127, 1}, + {128, 2}, + {16383, 2}, + {16384, 3}, + {math.MaxInt64, 9}, + {math.MaxInt64 + 1, 10}, + } + for _, tc := range testCases { + size := proto.SizeVarint(tc.n) + if size != tc.size { + t.Errorf("sizeVarint(%d) = %d, want %d", tc.n, size, tc.size) + } + } +} diff --git a/pkg/golang-protobuf/proto/registry.go b/pkg/golang-protobuf/proto/registry.go new file mode 100644 index 000000000..066b4323b --- /dev/null +++ b/pkg/golang-protobuf/proto/registry.go @@ -0,0 +1,317 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +import ( + "bytes" + "compress/gzip" + "fmt" + "io/ioutil" + "reflect" + "strings" + "sync" + + "google.golang.org/protobuf/reflect/protodesc" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/runtime/protoimpl" +) + +// filePath is the path to the proto source file. +type filePath = string // e.g., "google/protobuf/descriptor.proto" + +// fileDescGZIP is the compressed contents of the encoded FileDescriptorProto. +type fileDescGZIP = []byte + +var fileCache sync.Map // map[filePath]fileDescGZIP + +// RegisterFile is called from generated code to register the compressed +// FileDescriptorProto with the file path for a proto source file. +// +// Deprecated: Use protoregistry.GlobalFiles.RegisterFile instead. +func RegisterFile(s filePath, d fileDescGZIP) { + // Decompress the descriptor. + zr, err := gzip.NewReader(bytes.NewReader(d)) + if err != nil { + panic(fmt.Sprintf("proto: invalid compressed file descriptor: %v", err)) + } + b, err := ioutil.ReadAll(zr) + if err != nil { + panic(fmt.Sprintf("proto: invalid compressed file descriptor: %v", err)) + } + + // Construct a protoreflect.FileDescriptor from the raw descriptor. + // Note that DescBuilder.Build automatically registers the constructed + // file descriptor with the v2 registry. + protoimpl.DescBuilder{RawDescriptor: b}.Build() + + // Locally cache the raw descriptor form for the file. + fileCache.Store(s, d) +} + +// FileDescriptor returns the compressed FileDescriptorProto given the file path +// for a proto source file. It returns nil if not found. +// +// Deprecated: Use protoregistry.GlobalFiles.FindFileByPath instead. +func FileDescriptor(s filePath) fileDescGZIP { + if v, ok := fileCache.Load(s); ok { + return v.(fileDescGZIP) + } + + // Find the descriptor in the v2 registry. + var b []byte + if fd, _ := protoregistry.GlobalFiles.FindFileByPath(s); fd != nil { + b, _ = Marshal(protodesc.ToFileDescriptorProto(fd)) + } + + // Locally cache the raw descriptor form for the file. + if len(b) > 0 { + v, _ := fileCache.LoadOrStore(s, protoimpl.X.CompressGZIP(b)) + return v.(fileDescGZIP) + } + return nil +} + +// enumName is the name of an enum. For historical reasons, the enum name is +// neither the full Go name nor the full protobuf name of the enum. +// The name is the dot-separated combination of just the proto package that the +// enum is declared within followed by the Go type name of the generated enum. +type enumName = string // e.g., "my.proto.package.GoMessage_GoEnum" + +// enumsByName maps enum values by name to their numeric counterpart. +type enumsByName = map[string]int32 + +// enumsByNumber maps enum values by number to their name counterpart. +type enumsByNumber = map[int32]string + +var enumCache sync.Map // map[enumName]enumsByName +var numFilesCache sync.Map // map[protoreflect.FullName]int + +// RegisterEnum is called from the generated code to register the mapping of +// enum value names to enum numbers for the enum identified by s. +// +// Deprecated: Use protoregistry.GlobalTypes.RegisterEnum instead. +func RegisterEnum(s enumName, _ enumsByNumber, m enumsByName) { + if _, ok := enumCache.Load(s); ok { + panic("proto: duplicate enum registered: " + s) + } + enumCache.Store(s, m) + + // This does not forward registration to the v2 registry since this API + // lacks sufficient information to construct a complete v2 enum descriptor. +} + +// EnumValueMap returns the mapping from enum value names to enum numbers for +// the enum of the given name. It returns nil if not found. +// +// Deprecated: Use protoregistry.GlobalTypes.FindEnumByName instead. +func EnumValueMap(s enumName) enumsByName { + if v, ok := enumCache.Load(s); ok { + return v.(enumsByName) + } + + // Check whether the cache is stale. If the number of files in the current + // package differs, then it means that some enums may have been recently + // registered upstream that we do not know about. + var protoPkg protoreflect.FullName + if i := strings.LastIndexByte(s, '.'); i >= 0 { + protoPkg = protoreflect.FullName(s[:i]) + } + v, _ := numFilesCache.Load(protoPkg) + numFiles, _ := v.(int) + if protoregistry.GlobalFiles.NumFilesByPackage(protoPkg) == numFiles { + return nil // cache is up-to-date; was not found earlier + } + + // Update the enum cache for all enums declared in the given proto package. + numFiles = 0 + protoregistry.GlobalFiles.RangeFilesByPackage(protoPkg, func(fd protoreflect.FileDescriptor) bool { + walkEnums(fd, func(ed protoreflect.EnumDescriptor) { + name := protoimpl.X.LegacyEnumName(ed) + if _, ok := enumCache.Load(name); !ok { + m := make(enumsByName) + evs := ed.Values() + for i := evs.Len() - 1; i >= 0; i-- { + ev := evs.Get(i) + m[string(ev.Name())] = int32(ev.Number()) + } + enumCache.LoadOrStore(name, m) + } + }) + numFiles++ + return true + }) + numFilesCache.Store(protoPkg, numFiles) + + // Check cache again for enum map. + if v, ok := enumCache.Load(s); ok { + return v.(enumsByName) + } + return nil +} + +// walkEnums recursively walks all enums declared in d. +func walkEnums(d interface { + Enums() protoreflect.EnumDescriptors + Messages() protoreflect.MessageDescriptors +}, f func(protoreflect.EnumDescriptor)) { + eds := d.Enums() + for i := eds.Len() - 1; i >= 0; i-- { + f(eds.Get(i)) + } + mds := d.Messages() + for i := mds.Len() - 1; i >= 0; i-- { + walkEnums(mds.Get(i), f) + } +} + +// messageName is the full name of protobuf message. +type messageName = string + +var messageTypeCache sync.Map // map[messageName]reflect.Type + +// RegisterType is called from generated code to register the message Go type +// for a message of the given name. +// +// Deprecated: Use protoregistry.GlobalTypes.RegisterMessage instead. +func RegisterType(m Message, s messageName) { + mt := protoimpl.X.LegacyMessageTypeOf(m, protoreflect.FullName(s)) + if err := protoregistry.GlobalTypes.RegisterMessage(mt); err != nil { + panic(err) + } + messageTypeCache.Store(s, reflect.TypeOf(m)) +} + +// RegisterMapType is called from generated code to register the Go map type +// for a protobuf message representing a map entry. +// +// Deprecated: Do not use. +func RegisterMapType(m interface{}, s messageName) { + t := reflect.TypeOf(m) + if t.Kind() != reflect.Map { + panic(fmt.Sprintf("invalid map kind: %v", t)) + } + if _, ok := messageTypeCache.Load(s); ok { + panic(fmt.Errorf("proto: duplicate proto message registered: %s", s)) + } + messageTypeCache.Store(s, t) +} + +// MessageType returns the message type for a named message. +// It returns nil if not found. +// +// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead. +func MessageType(s messageName) reflect.Type { + if v, ok := messageTypeCache.Load(s); ok { + return v.(reflect.Type) + } + + // Derive the message type from the v2 registry. + var t reflect.Type + if mt, _ := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(s)); mt != nil { + t = messageGoType(mt) + } + + // If we could not get a concrete type, it is possible that it is a + // pseudo-message for a map entry. + if t == nil { + d, _ := protoregistry.GlobalFiles.FindDescriptorByName(protoreflect.FullName(s)) + if md, _ := d.(protoreflect.MessageDescriptor); md != nil && md.IsMapEntry() { + kt := goTypeForField(md.Fields().ByNumber(1)) + vt := goTypeForField(md.Fields().ByNumber(2)) + t = reflect.MapOf(kt, vt) + } + } + + // Locally cache the message type for the given name. + if t != nil { + v, _ := messageTypeCache.LoadOrStore(s, t) + return v.(reflect.Type) + } + return nil +} + +func goTypeForField(fd protoreflect.FieldDescriptor) reflect.Type { + switch k := fd.Kind(); k { + case protoreflect.EnumKind: + if et, _ := protoregistry.GlobalTypes.FindEnumByName(fd.Enum().FullName()); et != nil { + return enumGoType(et) + } + return reflect.TypeOf(protoreflect.EnumNumber(0)) + case protoreflect.MessageKind, protoreflect.GroupKind: + if mt, _ := protoregistry.GlobalTypes.FindMessageByName(fd.Message().FullName()); mt != nil { + return messageGoType(mt) + } + return reflect.TypeOf((*protoreflect.Message)(nil)).Elem() + default: + return reflect.TypeOf(fd.Default().Interface()) + } +} + +func enumGoType(et protoreflect.EnumType) reflect.Type { + return reflect.TypeOf(et.New(0)) +} + +func messageGoType(mt protoreflect.MessageType) reflect.Type { + return reflect.TypeOf(MessageV1(mt.Zero().Interface())) +} + +// MessageName returns the full protobuf name for the given message type. +// +// Deprecated: Use protoreflect.MessageDescriptor.FullName instead. +func MessageName(m Message) messageName { + if m == nil { + return "" + } + if m, ok := m.(interface{ XXX_MessageName() messageName }); ok { + return m.XXX_MessageName() + } + return messageName(protoimpl.X.MessageDescriptorOf(m).FullName()) +} + +// RegisterExtension is called from the generated code to register +// the extension descriptor. +// +// Deprecated: Use protoregistry.GlobalTypes.RegisterExtension instead. +func RegisterExtension(d *ExtensionDesc) { + if err := protoregistry.GlobalTypes.RegisterExtension(d); err != nil { + panic(err) + } +} + +type extensionsByNumber = map[int32]*ExtensionDesc + +var extensionCache sync.Map // map[messageName]extensionsByNumber + +// RegisteredExtensions returns a map of the registered extensions for the +// provided protobuf message, indexed by the extension field number. +// +// Deprecated: Use protoregistry.GlobalTypes.RangeExtensionsByMessage instead. +func RegisteredExtensions(m Message) extensionsByNumber { + // Check whether the cache is stale. If the number of extensions for + // the given message differs, then it means that some extensions were + // recently registered upstream that we do not know about. + s := MessageName(m) + v, _ := extensionCache.Load(s) + xs, _ := v.(extensionsByNumber) + if protoregistry.GlobalTypes.NumExtensionsByMessage(protoreflect.FullName(s)) == len(xs) { + return xs // cache is up-to-date + } + + // Cache is stale, re-compute the extensions map. + xs = make(extensionsByNumber) + protoregistry.GlobalTypes.RangeExtensionsByMessage(protoreflect.FullName(s), func(xt protoreflect.ExtensionType) bool { + if xd, ok := xt.(*ExtensionDesc); ok { + xs[int32(xt.TypeDescriptor().Number())] = xd + } else { + // TODO: This implies that the protoreflect.ExtensionType is a + // custom type not generated by protoc-gen-go. We could try and + // convert the type to an ExtensionDesc. + } + return true + }) + extensionCache.Store(s, xs) + return xs +} diff --git a/pkg/golang-protobuf/proto/registry_test.go b/pkg/golang-protobuf/proto/registry_test.go new file mode 100644 index 000000000..89c4f783c --- /dev/null +++ b/pkg/golang-protobuf/proto/registry_test.go @@ -0,0 +1,37 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto_test + +import ( + "reflect" + "testing" + + "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + + descpb "github.com/golang/protobuf/protoc-gen-go/descriptor" +) + +func TestRegistry(t *testing.T) { + file := new(descpb.DescriptorProto).ProtoReflect().Descriptor().ParentFile() + path := file.Path() + pkg := file.Package() + if got := proto.FileDescriptor(path); len(got) == 0 { + t.Errorf("FileDescriptor(%q) = empty, want non-empty", path) + } + + name := protoreflect.FullName(pkg + ".FieldDescriptorProto_Label") + if got := proto.EnumValueMap(string(name)); len(got) == 0 { + t.Errorf("EnumValueMap(%q) = empty, want non-empty", name) + } + + msg := new(descpb.EnumDescriptorProto_EnumReservedRange) + name = msg.ProtoReflect().Descriptor().FullName() + wantType := reflect.TypeOf(msg) + gotType := proto.MessageType(string(name)) + if gotType != wantType { + t.Errorf("MessageType(%q) = %v, want %v", name, gotType, wantType) + } +} diff --git a/pkg/golang-protobuf/proto/text_decode.go b/pkg/golang-protobuf/proto/text_decode.go new file mode 100644 index 000000000..47eb3e445 --- /dev/null +++ b/pkg/golang-protobuf/proto/text_decode.go @@ -0,0 +1,801 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +import ( + "encoding" + "errors" + "fmt" + "reflect" + "strconv" + "strings" + "unicode/utf8" + + "google.golang.org/protobuf/encoding/prototext" + protoV2 "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" +) + +const wrapTextUnmarshalV2 = false + +// ParseError is returned by UnmarshalText. +type ParseError struct { + Message string + + // Deprecated: Do not use. + Line, Offset int +} + +func (e *ParseError) Error() string { + if wrapTextUnmarshalV2 { + return e.Message + } + if e.Line == 1 { + return fmt.Sprintf("line 1.%d: %v", e.Offset, e.Message) + } + return fmt.Sprintf("line %d: %v", e.Line, e.Message) +} + +// UnmarshalText parses a proto text formatted string into m. +func UnmarshalText(s string, m Message) error { + if u, ok := m.(encoding.TextUnmarshaler); ok { + return u.UnmarshalText([]byte(s)) + } + + m.Reset() + mi := MessageV2(m) + + if wrapTextUnmarshalV2 { + err := prototext.UnmarshalOptions{ + AllowPartial: true, + }.Unmarshal([]byte(s), mi) + if err != nil { + return &ParseError{Message: err.Error()} + } + return checkRequiredNotSet(mi) + } else { + if err := newTextParser(s).unmarshalMessage(mi.ProtoReflect(), ""); err != nil { + return err + } + return checkRequiredNotSet(mi) + } +} + +type textParser struct { + s string // remaining input + done bool // whether the parsing is finished (success or error) + backed bool // whether back() was called + offset, line int + cur token +} + +type token struct { + value string + err *ParseError + line int // line number + offset int // byte number from start of input, not start of line + unquoted string // the unquoted version of value, if it was a quoted string +} + +func newTextParser(s string) *textParser { + p := new(textParser) + p.s = s + p.line = 1 + p.cur.line = 1 + return p +} + +func (p *textParser) unmarshalMessage(m protoreflect.Message, terminator string) (err error) { + md := m.Descriptor() + fds := md.Fields() + + // A struct is a sequence of "name: value", terminated by one of + // '>' or '}', or the end of the input. A name may also be + // "[extension]" or "[type/url]". + // + // The whole struct can also be an expanded Any message, like: + // [type/url] < ... struct contents ... > + seen := make(map[protoreflect.FieldNumber]bool) + for { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == terminator { + break + } + if tok.value == "[" { + if err := p.unmarshalExtensionOrAny(m, seen); err != nil { + return err + } + continue + } + + // This is a normal, non-extension field. + name := protoreflect.Name(tok.value) + fd := fds.ByName(name) + switch { + case fd == nil: + gd := fds.ByName(protoreflect.Name(strings.ToLower(string(name)))) + if gd != nil && gd.Kind() == protoreflect.GroupKind && gd.Message().Name() == name { + fd = gd + } + case fd.Kind() == protoreflect.GroupKind && fd.Message().Name() != name: + fd = nil + case fd.IsWeak() && fd.Message().IsPlaceholder(): + fd = nil + } + if fd == nil { + typeName := string(md.FullName()) + if m, ok := m.Interface().(Message); ok { + t := reflect.TypeOf(m) + if t.Kind() == reflect.Ptr { + typeName = t.Elem().String() + } + } + return p.errorf("unknown field name %q in %v", name, typeName) + } + if od := fd.ContainingOneof(); od != nil && m.WhichOneof(od) != nil { + return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, od.Name()) + } + if fd.Cardinality() != protoreflect.Repeated && seen[fd.Number()] { + return p.errorf("non-repeated field %q was repeated", fd.Name()) + } + seen[fd.Number()] = true + + // Consume any colon. + if err := p.checkForColon(fd); err != nil { + return err + } + + // Parse into the field. + v := m.Get(fd) + if !m.Has(fd) && (fd.IsList() || fd.IsMap() || fd.Message() != nil) { + v = m.Mutable(fd) + } + if v, err = p.unmarshalValue(v, fd); err != nil { + return err + } + m.Set(fd, v) + + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + } + return nil +} + +func (p *textParser) unmarshalExtensionOrAny(m protoreflect.Message, seen map[protoreflect.FieldNumber]bool) error { + name, err := p.consumeExtensionOrAnyName() + if err != nil { + return err + } + + // If it contains a slash, it's an Any type URL. + if slashIdx := strings.LastIndex(name, "/"); slashIdx >= 0 { + tok := p.next() + if tok.err != nil { + return tok.err + } + // consume an optional colon + if tok.value == ":" { + tok = p.next() + if tok.err != nil { + return tok.err + } + } + + var terminator string + switch tok.value { + case "<": + terminator = ">" + case "{": + terminator = "}" + default: + return p.errorf("expected '{' or '<', found %q", tok.value) + } + + mt, err := protoregistry.GlobalTypes.FindMessageByURL(name) + if err != nil { + return p.errorf("unrecognized message %q in google.protobuf.Any", name[slashIdx+len("/"):]) + } + m2 := mt.New() + if err := p.unmarshalMessage(m2, terminator); err != nil { + return err + } + b, err := protoV2.Marshal(m2.Interface()) + if err != nil { + return p.errorf("failed to marshal message of type %q: %v", name[slashIdx+len("/"):], err) + } + + urlFD := m.Descriptor().Fields().ByName("type_url") + valFD := m.Descriptor().Fields().ByName("value") + if seen[urlFD.Number()] { + return p.errorf("Any message unpacked multiple times, or %q already set", urlFD.Name()) + } + if seen[valFD.Number()] { + return p.errorf("Any message unpacked multiple times, or %q already set", valFD.Name()) + } + m.Set(urlFD, protoreflect.ValueOfString(name)) + m.Set(valFD, protoreflect.ValueOfBytes(b)) + seen[urlFD.Number()] = true + seen[valFD.Number()] = true + return nil + } + + xname := protoreflect.FullName(name) + xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname) + if xt == nil && isMessageSet(m.Descriptor()) { + xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension")) + } + if xt == nil { + return p.errorf("unrecognized extension %q", name) + } + fd := xt.TypeDescriptor() + if fd.ContainingMessage().FullName() != m.Descriptor().FullName() { + return p.errorf("extension field %q does not extend message %q", name, m.Descriptor().FullName()) + } + + if err := p.checkForColon(fd); err != nil { + return err + } + + v := m.Get(fd) + if !m.Has(fd) && (fd.IsList() || fd.IsMap() || fd.Message() != nil) { + v = m.Mutable(fd) + } + v, err = p.unmarshalValue(v, fd) + if err != nil { + return err + } + m.Set(fd, v) + return p.consumeOptionalSeparator() +} + +func (p *textParser) unmarshalValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { + tok := p.next() + if tok.err != nil { + return v, tok.err + } + if tok.value == "" { + return v, p.errorf("unexpected EOF") + } + + switch { + case fd.IsList(): + lv := v.List() + var err error + if tok.value == "[" { + // Repeated field with list notation, like [1,2,3]. + for { + vv := lv.NewElement() + vv, err = p.unmarshalSingularValue(vv, fd) + if err != nil { + return v, err + } + lv.Append(vv) + + tok := p.next() + if tok.err != nil { + return v, tok.err + } + if tok.value == "]" { + break + } + if tok.value != "," { + return v, p.errorf("Expected ']' or ',' found %q", tok.value) + } + } + return v, nil + } + + // One value of the repeated field. + p.back() + vv := lv.NewElement() + vv, err = p.unmarshalSingularValue(vv, fd) + if err != nil { + return v, err + } + lv.Append(vv) + return v, nil + case fd.IsMap(): + // The map entry should be this sequence of tokens: + // < key : KEY value : VALUE > + // However, implementations may omit key or value, and technically + // we should support them in any order. + var terminator string + switch tok.value { + case "<": + terminator = ">" + case "{": + terminator = "}" + default: + return v, p.errorf("expected '{' or '<', found %q", tok.value) + } + + keyFD := fd.MapKey() + valFD := fd.MapValue() + + mv := v.Map() + kv := keyFD.Default() + vv := mv.NewValue() + for { + tok := p.next() + if tok.err != nil { + return v, tok.err + } + if tok.value == terminator { + break + } + var err error + switch tok.value { + case "key": + if err := p.consumeToken(":"); err != nil { + return v, err + } + if kv, err = p.unmarshalSingularValue(kv, keyFD); err != nil { + return v, err + } + if err := p.consumeOptionalSeparator(); err != nil { + return v, err + } + case "value": + if err := p.checkForColon(valFD); err != nil { + return v, err + } + if vv, err = p.unmarshalSingularValue(vv, valFD); err != nil { + return v, err + } + if err := p.consumeOptionalSeparator(); err != nil { + return v, err + } + default: + p.back() + return v, p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value) + } + } + mv.Set(kv.MapKey(), vv) + return v, nil + default: + p.back() + return p.unmarshalSingularValue(v, fd) + } +} + +func (p *textParser) unmarshalSingularValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { + tok := p.next() + if tok.err != nil { + return v, tok.err + } + if tok.value == "" { + return v, p.errorf("unexpected EOF") + } + + switch fd.Kind() { + case protoreflect.BoolKind: + switch tok.value { + case "true", "1", "t", "True": + return protoreflect.ValueOfBool(true), nil + case "false", "0", "f", "False": + return protoreflect.ValueOfBool(false), nil + } + case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: + if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { + return protoreflect.ValueOfInt32(int32(x)), nil + } + + // The C++ parser accepts large positive hex numbers that uses + // two's complement arithmetic to represent negative numbers. + // This feature is here for backwards compatibility with C++. + if strings.HasPrefix(tok.value, "0x") { + if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { + return protoreflect.ValueOfInt32(int32(-(int64(^x) + 1))), nil + } + } + case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: + if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil { + return protoreflect.ValueOfInt64(int64(x)), nil + } + + // The C++ parser accepts large positive hex numbers that uses + // two's complement arithmetic to represent negative numbers. + // This feature is here for backwards compatibility with C++. + if strings.HasPrefix(tok.value, "0x") { + if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { + return protoreflect.ValueOfInt64(int64(-(int64(^x) + 1))), nil + } + } + case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: + if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { + return protoreflect.ValueOfUint32(uint32(x)), nil + } + case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: + if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { + return protoreflect.ValueOfUint64(uint64(x)), nil + } + case protoreflect.FloatKind: + // Ignore 'f' for compatibility with output generated by C++, + // but don't remove 'f' when the value is "-inf" or "inf". + v := tok.value + if strings.HasSuffix(v, "f") && v != "-inf" && v != "inf" { + v = v[:len(v)-len("f")] + } + if x, err := strconv.ParseFloat(v, 32); err == nil { + return protoreflect.ValueOfFloat32(float32(x)), nil + } + case protoreflect.DoubleKind: + // Ignore 'f' for compatibility with output generated by C++, + // but don't remove 'f' when the value is "-inf" or "inf". + v := tok.value + if strings.HasSuffix(v, "f") && v != "-inf" && v != "inf" { + v = v[:len(v)-len("f")] + } + if x, err := strconv.ParseFloat(v, 64); err == nil { + return protoreflect.ValueOfFloat64(float64(x)), nil + } + case protoreflect.StringKind: + if isQuote(tok.value[0]) { + return protoreflect.ValueOfString(tok.unquoted), nil + } + case protoreflect.BytesKind: + if isQuote(tok.value[0]) { + return protoreflect.ValueOfBytes([]byte(tok.unquoted)), nil + } + case protoreflect.EnumKind: + if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { + return protoreflect.ValueOfEnum(protoreflect.EnumNumber(x)), nil + } + vd := fd.Enum().Values().ByName(protoreflect.Name(tok.value)) + if vd != nil { + return protoreflect.ValueOfEnum(vd.Number()), nil + } + case protoreflect.MessageKind, protoreflect.GroupKind: + var terminator string + switch tok.value { + case "{": + terminator = "}" + case "<": + terminator = ">" + default: + return v, p.errorf("expected '{' or '<', found %q", tok.value) + } + err := p.unmarshalMessage(v.Message(), terminator) + return v, err + default: + panic(fmt.Sprintf("invalid kind %v", fd.Kind())) + } + return v, p.errorf("invalid %v: %v", fd.Kind(), tok.value) +} + +// Consume a ':' from the input stream (if the next token is a colon), +// returning an error if a colon is needed but not present. +func (p *textParser) checkForColon(fd protoreflect.FieldDescriptor) *ParseError { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != ":" { + if fd.Message() == nil { + return p.errorf("expected ':', found %q", tok.value) + } + p.back() + } + return nil +} + +// consumeExtensionOrAnyName consumes an extension name or an Any type URL and +// the following ']'. It returns the name or URL consumed. +func (p *textParser) consumeExtensionOrAnyName() (string, error) { + tok := p.next() + if tok.err != nil { + return "", tok.err + } + + // If extension name or type url is quoted, it's a single token. + if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] { + name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0])) + if err != nil { + return "", err + } + return name, p.consumeToken("]") + } + + // Consume everything up to "]" + var parts []string + for tok.value != "]" { + parts = append(parts, tok.value) + tok = p.next() + if tok.err != nil { + return "", p.errorf("unrecognized type_url or extension name: %s", tok.err) + } + if p.done && tok.value != "]" { + return "", p.errorf("unclosed type_url or extension name") + } + } + return strings.Join(parts, ""), nil +} + +// consumeOptionalSeparator consumes an optional semicolon or comma. +// It is used in unmarshalMessage to provide backward compatibility. +func (p *textParser) consumeOptionalSeparator() error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != ";" && tok.value != "," { + p.back() + } + return nil +} + +func (p *textParser) errorf(format string, a ...interface{}) *ParseError { + pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset} + p.cur.err = pe + p.done = true + return pe +} + +func (p *textParser) skipWhitespace() { + i := 0 + for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { + if p.s[i] == '#' { + // comment; skip to end of line or input + for i < len(p.s) && p.s[i] != '\n' { + i++ + } + if i == len(p.s) { + break + } + } + if p.s[i] == '\n' { + p.line++ + } + i++ + } + p.offset += i + p.s = p.s[i:len(p.s)] + if len(p.s) == 0 { + p.done = true + } +} + +func (p *textParser) advance() { + // Skip whitespace + p.skipWhitespace() + if p.done { + return + } + + // Start of non-whitespace + p.cur.err = nil + p.cur.offset, p.cur.line = p.offset, p.line + p.cur.unquoted = "" + switch p.s[0] { + case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/': + // Single symbol + p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)] + case '"', '\'': + // Quoted string + i := 1 + for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' { + if p.s[i] == '\\' && i+1 < len(p.s) { + // skip escaped char + i++ + } + i++ + } + if i >= len(p.s) || p.s[i] != p.s[0] { + p.errorf("unmatched quote") + return + } + unq, err := unquoteC(p.s[1:i], rune(p.s[0])) + if err != nil { + p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err) + return + } + p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] + p.cur.unquoted = unq + default: + i := 0 + for i < len(p.s) && isIdentOrNumberChar(p.s[i]) { + i++ + } + if i == 0 { + p.errorf("unexpected byte %#x", p.s[0]) + return + } + p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)] + } + p.offset += len(p.cur.value) +} + +// Back off the parser by one token. Can only be done between calls to next(). +// It makes the next advance() a no-op. +func (p *textParser) back() { p.backed = true } + +// Advances the parser and returns the new current token. +func (p *textParser) next() *token { + if p.backed || p.done { + p.backed = false + return &p.cur + } + p.advance() + if p.done { + p.cur.value = "" + } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { + // Look for multiple quoted strings separated by whitespace, + // and concatenate them. + cat := p.cur + for { + p.skipWhitespace() + if p.done || !isQuote(p.s[0]) { + break + } + p.advance() + if p.cur.err != nil { + return &p.cur + } + cat.value += " " + p.cur.value + cat.unquoted += p.cur.unquoted + } + p.done = false // parser may have seen EOF, but we want to return cat + p.cur = cat + } + return &p.cur +} + +func (p *textParser) consumeToken(s string) error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != s { + p.back() + return p.errorf("expected %q, found %q", s, tok.value) + } + return nil +} + +var errBadUTF8 = errors.New("proto: bad UTF-8") + +func unquoteC(s string, quote rune) (string, error) { + // This is based on C++'s tokenizer.cc. + // Despite its name, this is *not* parsing C syntax. + // For instance, "\0" is an invalid quoted string. + + // Avoid allocation in trivial cases. + simple := true + for _, r := range s { + if r == '\\' || r == quote { + simple = false + break + } + } + if simple { + return s, nil + } + + buf := make([]byte, 0, 3*len(s)/2) + for len(s) > 0 { + r, n := utf8.DecodeRuneInString(s) + if r == utf8.RuneError && n == 1 { + return "", errBadUTF8 + } + s = s[n:] + if r != '\\' { + if r < utf8.RuneSelf { + buf = append(buf, byte(r)) + } else { + buf = append(buf, string(r)...) + } + continue + } + + ch, tail, err := unescape(s) + if err != nil { + return "", err + } + buf = append(buf, ch...) + s = tail + } + return string(buf), nil +} + +func unescape(s string) (ch string, tail string, err error) { + r, n := utf8.DecodeRuneInString(s) + if r == utf8.RuneError && n == 1 { + return "", "", errBadUTF8 + } + s = s[n:] + switch r { + case 'a': + return "\a", s, nil + case 'b': + return "\b", s, nil + case 'f': + return "\f", s, nil + case 'n': + return "\n", s, nil + case 'r': + return "\r", s, nil + case 't': + return "\t", s, nil + case 'v': + return "\v", s, nil + case '?': + return "?", s, nil // trigraph workaround + case '\'', '"', '\\': + return string(r), s, nil + case '0', '1', '2', '3', '4', '5', '6', '7': + if len(s) < 2 { + return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) + } + ss := string(r) + s[:2] + s = s[2:] + i, err := strconv.ParseUint(ss, 8, 8) + if err != nil { + return "", "", fmt.Errorf(`\%s contains non-octal digits`, ss) + } + return string([]byte{byte(i)}), s, nil + case 'x', 'X', 'u', 'U': + var n int + switch r { + case 'x', 'X': + n = 2 + case 'u': + n = 4 + case 'U': + n = 8 + } + if len(s) < n { + return "", "", fmt.Errorf(`\%c requires %d following digits`, r, n) + } + ss := s[:n] + s = s[n:] + i, err := strconv.ParseUint(ss, 16, 64) + if err != nil { + return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, r, ss) + } + if r == 'x' || r == 'X' { + return string([]byte{byte(i)}), s, nil + } + if i > utf8.MaxRune { + return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss) + } + return string(rune(i)), s, nil + } + return "", "", fmt.Errorf(`unknown escape \%c`, r) +} + +func isIdentOrNumberChar(c byte) bool { + switch { + case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z': + return true + case '0' <= c && c <= '9': + return true + } + switch c { + case '-', '+', '.', '_': + return true + } + return false +} + +func isWhitespace(c byte) bool { + switch c { + case ' ', '\t', '\n', '\r': + return true + } + return false +} + +func isQuote(c byte) bool { + switch c { + case '"', '\'': + return true + } + return false +} diff --git a/pkg/golang-protobuf/proto/text_encode.go b/pkg/golang-protobuf/proto/text_encode.go new file mode 100644 index 000000000..a31134eeb --- /dev/null +++ b/pkg/golang-protobuf/proto/text_encode.go @@ -0,0 +1,560 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +import ( + "bytes" + "encoding" + "fmt" + "io" + "math" + "sort" + "strings" + + "google.golang.org/protobuf/encoding/prototext" + "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" +) + +const wrapTextMarshalV2 = false + +// TextMarshaler is a configurable text format marshaler. +type TextMarshaler struct { + Compact bool // use compact text format (one line) + ExpandAny bool // expand google.protobuf.Any messages of known types +} + +// Marshal writes the proto text format of m to w. +func (tm *TextMarshaler) Marshal(w io.Writer, m Message) error { + b, err := tm.marshal(m) + if len(b) > 0 { + if _, err := w.Write(b); err != nil { + return err + } + } + return err +} + +// Text returns a proto text formatted string of m. +func (tm *TextMarshaler) Text(m Message) string { + b, _ := tm.marshal(m) + return string(b) +} + +func (tm *TextMarshaler) marshal(m Message) ([]byte, error) { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() { + return []byte(""), nil + } + + if wrapTextMarshalV2 { + if m, ok := m.(encoding.TextMarshaler); ok { + return m.MarshalText() + } + + opts := prototext.MarshalOptions{ + AllowPartial: true, + EmitUnknown: true, + } + if !tm.Compact { + opts.Indent = " " + } + if !tm.ExpandAny { + opts.Resolver = (*protoregistry.Types)(nil) + } + return opts.Marshal(mr.Interface()) + } else { + w := &textWriter{ + compact: tm.Compact, + expandAny: tm.ExpandAny, + complete: true, + } + + if m, ok := m.(encoding.TextMarshaler); ok { + b, err := m.MarshalText() + if err != nil { + return nil, err + } + w.Write(b) + return w.buf, nil + } + + err := w.writeMessage(mr) + return w.buf, err + } +} + +var ( + defaultTextMarshaler = TextMarshaler{} + compactTextMarshaler = TextMarshaler{Compact: true} +) + +// MarshalText writes the proto text format of m to w. +func MarshalText(w io.Writer, m Message) error { return defaultTextMarshaler.Marshal(w, m) } + +// MarshalTextString returns a proto text formatted string of m. +func MarshalTextString(m Message) string { return defaultTextMarshaler.Text(m) } + +// CompactText writes the compact proto text format of m to w. +func CompactText(w io.Writer, m Message) error { return compactTextMarshaler.Marshal(w, m) } + +// CompactTextString returns a compact proto text formatted string of m. +func CompactTextString(m Message) string { return compactTextMarshaler.Text(m) } + +var ( + newline = []byte("\n") + endBraceNewline = []byte("}\n") + posInf = []byte("inf") + negInf = []byte("-inf") + nan = []byte("nan") +) + +// textWriter is an io.Writer that tracks its indentation level. +type textWriter struct { + compact bool // same as TextMarshaler.Compact + expandAny bool // same as TextMarshaler.ExpandAny + complete bool // whether the current position is a complete line + indent int // indentation level; never negative + buf []byte +} + +func (w *textWriter) Write(p []byte) (n int, _ error) { + newlines := bytes.Count(p, newline) + if newlines == 0 { + if !w.compact && w.complete { + w.writeIndent() + } + w.buf = append(w.buf, p...) + w.complete = false + return len(p), nil + } + + frags := bytes.SplitN(p, newline, newlines+1) + if w.compact { + for i, frag := range frags { + if i > 0 { + w.buf = append(w.buf, ' ') + n++ + } + w.buf = append(w.buf, frag...) + n += len(frag) + } + return n, nil + } + + for i, frag := range frags { + if w.complete { + w.writeIndent() + } + w.buf = append(w.buf, frag...) + n += len(frag) + if i+1 < len(frags) { + w.buf = append(w.buf, '\n') + n++ + } + } + w.complete = len(frags[len(frags)-1]) == 0 + return n, nil +} + +func (w *textWriter) WriteByte(c byte) error { + if w.compact && c == '\n' { + c = ' ' + } + if !w.compact && w.complete { + w.writeIndent() + } + w.buf = append(w.buf, c) + w.complete = c == '\n' + return nil +} + +func (w *textWriter) writeName(fd protoreflect.FieldDescriptor) { + if !w.compact && w.complete { + w.writeIndent() + } + w.complete = false + + if fd.Kind() != protoreflect.GroupKind { + w.buf = append(w.buf, fd.Name()...) + w.WriteByte(':') + } else { + // Use message type name for group field name. + w.buf = append(w.buf, fd.Message().Name()...) + } + + if !w.compact { + w.WriteByte(' ') + } +} + +func requiresQuotes(u string) bool { + // When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted. + for _, ch := range u { + switch { + case ch == '.' || ch == '/' || ch == '_': + continue + case '0' <= ch && ch <= '9': + continue + case 'A' <= ch && ch <= 'Z': + continue + case 'a' <= ch && ch <= 'z': + continue + default: + return true + } + } + return false +} + +// writeProto3Any writes an expanded google.protobuf.Any message. +// +// It returns (false, nil) if sv value can't be unmarshaled (e.g. because +// required messages are not linked in). +// +// It returns (true, error) when sv was written in expanded format or an error +// was encountered. +func (w *textWriter) writeProto3Any(m protoreflect.Message) (bool, error) { + md := m.Descriptor() + fdURL := md.Fields().ByName("type_url") + fdVal := md.Fields().ByName("value") + + url := m.Get(fdURL).String() + mt, err := protoregistry.GlobalTypes.FindMessageByURL(url) + if err != nil { + return false, nil + } + + b := m.Get(fdVal).Bytes() + m2 := mt.New() + if err := proto.Unmarshal(b, m2.Interface()); err != nil { + return false, nil + } + w.Write([]byte("[")) + if requiresQuotes(url) { + w.writeQuotedString(url) + } else { + w.Write([]byte(url)) + } + if w.compact { + w.Write([]byte("]:<")) + } else { + w.Write([]byte("]: <\n")) + w.indent++ + } + if err := w.writeMessage(m2); err != nil { + return true, err + } + if w.compact { + w.Write([]byte("> ")) + } else { + w.indent-- + w.Write([]byte(">\n")) + } + return true, nil +} + +func (w *textWriter) writeMessage(m protoreflect.Message) error { + md := m.Descriptor() + if w.expandAny && md.FullName() == "google.protobuf.Any" { + if canExpand, err := w.writeProto3Any(m); canExpand { + return err + } + } + + fds := md.Fields() + for i := 0; i < fds.Len(); { + fd := fds.Get(i) + if od := fd.ContainingOneof(); od != nil { + fd = m.WhichOneof(od) + i += od.Fields().Len() + } else { + i++ + } + if fd == nil || !m.Has(fd) { + continue + } + + switch { + case fd.IsList(): + lv := m.Get(fd).List() + for j := 0; j < lv.Len(); j++ { + w.writeName(fd) + v := lv.Get(j) + if err := w.writeSingularValue(v, fd); err != nil { + return err + } + w.WriteByte('\n') + } + case fd.IsMap(): + kfd := fd.MapKey() + vfd := fd.MapValue() + mv := m.Get(fd).Map() + + type entry struct{ key, val protoreflect.Value } + var entries []entry + mv.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { + entries = append(entries, entry{k.Value(), v}) + return true + }) + sort.Slice(entries, func(i, j int) bool { + switch kfd.Kind() { + case protoreflect.BoolKind: + return !entries[i].key.Bool() && entries[j].key.Bool() + case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: + return entries[i].key.Int() < entries[j].key.Int() + case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind: + return entries[i].key.Uint() < entries[j].key.Uint() + case protoreflect.StringKind: + return entries[i].key.String() < entries[j].key.String() + default: + panic("invalid kind") + } + }) + for _, entry := range entries { + w.writeName(fd) + w.WriteByte('<') + if !w.compact { + w.WriteByte('\n') + } + w.indent++ + w.writeName(kfd) + if err := w.writeSingularValue(entry.key, kfd); err != nil { + return err + } + w.WriteByte('\n') + w.writeName(vfd) + if err := w.writeSingularValue(entry.val, vfd); err != nil { + return err + } + w.WriteByte('\n') + w.indent-- + w.WriteByte('>') + w.WriteByte('\n') + } + default: + w.writeName(fd) + if err := w.writeSingularValue(m.Get(fd), fd); err != nil { + return err + } + w.WriteByte('\n') + } + } + + if b := m.GetUnknown(); len(b) > 0 { + w.writeUnknownFields(b) + } + return w.writeExtensions(m) +} + +func (w *textWriter) writeSingularValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) error { + switch fd.Kind() { + case protoreflect.FloatKind, protoreflect.DoubleKind: + switch vf := v.Float(); { + case math.IsInf(vf, +1): + w.Write(posInf) + case math.IsInf(vf, -1): + w.Write(negInf) + case math.IsNaN(vf): + w.Write(nan) + default: + fmt.Fprint(w, v.Interface()) + } + case protoreflect.StringKind: + // NOTE: This does not validate UTF-8 for historical reasons. + w.writeQuotedString(string(v.String())) + case protoreflect.BytesKind: + w.writeQuotedString(string(v.Bytes())) + case protoreflect.MessageKind, protoreflect.GroupKind: + var bra, ket byte = '<', '>' + if fd.Kind() == protoreflect.GroupKind { + bra, ket = '{', '}' + } + w.WriteByte(bra) + if !w.compact { + w.WriteByte('\n') + } + w.indent++ + m := v.Message() + if m2, ok := m.Interface().(encoding.TextMarshaler); ok { + b, err := m2.MarshalText() + if err != nil { + return err + } + w.Write(b) + } else { + w.writeMessage(m) + } + w.indent-- + w.WriteByte(ket) + case protoreflect.EnumKind: + if ev := fd.Enum().Values().ByNumber(v.Enum()); ev != nil { + fmt.Fprint(w, ev.Name()) + } else { + fmt.Fprint(w, v.Enum()) + } + default: + fmt.Fprint(w, v.Interface()) + } + return nil +} + +// writeQuotedString writes a quoted string in the protocol buffer text format. +func (w *textWriter) writeQuotedString(s string) { + w.WriteByte('"') + for i := 0; i < len(s); i++ { + switch c := s[i]; c { + case '\n': + w.buf = append(w.buf, `\n`...) + case '\r': + w.buf = append(w.buf, `\r`...) + case '\t': + w.buf = append(w.buf, `\t`...) + case '"': + w.buf = append(w.buf, `\"`...) + case '\\': + w.buf = append(w.buf, `\\`...) + default: + if isPrint := c >= 0x20 && c < 0x7f; isPrint { + w.buf = append(w.buf, c) + } else { + w.buf = append(w.buf, fmt.Sprintf(`\%03o`, c)...) + } + } + } + w.WriteByte('"') +} + +func (w *textWriter) writeUnknownFields(b []byte) { + if !w.compact { + fmt.Fprintf(w, "/* %d unknown bytes */\n", len(b)) + } + + for len(b) > 0 { + num, wtyp, n := protowire.ConsumeTag(b) + if n < 0 { + return + } + b = b[n:] + + if wtyp == protowire.EndGroupType { + w.indent-- + w.Write(endBraceNewline) + continue + } + fmt.Fprint(w, num) + if wtyp != protowire.StartGroupType { + w.WriteByte(':') + } + if !w.compact || wtyp == protowire.StartGroupType { + w.WriteByte(' ') + } + switch wtyp { + case protowire.VarintType: + v, n := protowire.ConsumeVarint(b) + if n < 0 { + return + } + b = b[n:] + fmt.Fprint(w, v) + case protowire.Fixed32Type: + v, n := protowire.ConsumeFixed32(b) + if n < 0 { + return + } + b = b[n:] + fmt.Fprint(w, v) + case protowire.Fixed64Type: + v, n := protowire.ConsumeFixed64(b) + if n < 0 { + return + } + b = b[n:] + fmt.Fprint(w, v) + case protowire.BytesType: + v, n := protowire.ConsumeBytes(b) + if n < 0 { + return + } + b = b[n:] + fmt.Fprintf(w, "%q", v) + case protowire.StartGroupType: + w.WriteByte('{') + w.indent++ + default: + fmt.Fprintf(w, "/* unknown wire type %d */", wtyp) + } + w.WriteByte('\n') + } +} + +// writeExtensions writes all the extensions in m. +func (w *textWriter) writeExtensions(m protoreflect.Message) error { + md := m.Descriptor() + if md.ExtensionRanges().Len() == 0 { + return nil + } + + type ext struct { + desc protoreflect.FieldDescriptor + val protoreflect.Value + } + var exts []ext + m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + if fd.IsExtension() { + exts = append(exts, ext{fd, v}) + } + return true + }) + sort.Slice(exts, func(i, j int) bool { + return exts[i].desc.Number() < exts[j].desc.Number() + }) + + for _, ext := range exts { + // For message set, use the name of the message as the extension name. + name := string(ext.desc.FullName()) + if isMessageSet(ext.desc.ContainingMessage()) { + name = strings.TrimSuffix(name, ".message_set_extension") + } + + if !ext.desc.IsList() { + if err := w.writeSingularExtension(name, ext.val, ext.desc); err != nil { + return err + } + } else { + lv := ext.val.List() + for i := 0; i < lv.Len(); i++ { + if err := w.writeSingularExtension(name, lv.Get(i), ext.desc); err != nil { + return err + } + } + } + } + return nil +} + +func (w *textWriter) writeSingularExtension(name string, v protoreflect.Value, fd protoreflect.FieldDescriptor) error { + fmt.Fprintf(w, "[%s]:", name) + if !w.compact { + w.WriteByte(' ') + } + if err := w.writeSingularValue(v, fd); err != nil { + return err + } + w.WriteByte('\n') + return nil +} + +func (w *textWriter) writeIndent() { + if !w.complete { + return + } + for i := 0; i < w.indent*2; i++ { + w.buf = append(w.buf, ' ') + } + w.complete = false +} diff --git a/pkg/golang-protobuf/proto/text_test.go b/pkg/golang-protobuf/proto/text_test.go new file mode 100644 index 000000000..3f6edc5a6 --- /dev/null +++ b/pkg/golang-protobuf/proto/text_test.go @@ -0,0 +1,1370 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto_test + +import ( + "bytes" + "errors" + "math" + "strings" + "sync" + "testing" + + "github.com/golang/protobuf/proto" + "github.com/google/go-cmp/cmp" + + pb2 "github.com/golang/protobuf/internal/testprotos/proto2_proto" + pb3 "github.com/golang/protobuf/internal/testprotos/proto3_proto" + anypb "github.com/golang/protobuf/ptypes/any" +) + +var ( + expandedMarshaler = proto.TextMarshaler{ExpandAny: true} + expandedCompactMarshaler = proto.TextMarshaler{Compact: true, ExpandAny: true} +) + +// anyEqual reports whether two messages which may be google.protobuf.Any or may +// contain google.protobuf.Any fields are equal. We can't use proto.Equal for +// comparison, because semantically equivalent messages may be marshaled to +// binary in different tag order. Instead, trust that TextMarshaler with +// ExpandAny option works and compare the text marshaling results. +func anyEqual(got, want proto.Message) bool { + // if messages are proto.Equal, no need to marshal. + if proto.Equal(got, want) { + return true + } + g := expandedMarshaler.Text(got) + w := expandedMarshaler.Text(want) + return g == w +} + +type golden struct { + m proto.Message + t, c string +} + +var goldenMessages = makeGolden() + +func makeGolden() []golden { + nested := &pb3.Nested{Bunny: "Monty"} + nb, err := proto.Marshal(nested) + if err != nil { + panic(err) + } + m1 := &pb3.Message{ + Name: "David", + ResultCount: 47, + Anything: &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(nested), Value: nb}, + } + m2 := &pb3.Message{ + Name: "David", + ResultCount: 47, + Anything: &anypb.Any{TypeUrl: "http://[::1]/type.googleapis.com/" + proto.MessageName(nested), Value: nb}, + } + m3 := &pb3.Message{ + Name: "David", + ResultCount: 47, + Anything: &anypb.Any{TypeUrl: `type.googleapis.com/"/` + proto.MessageName(nested), Value: nb}, + } + m4 := &pb3.Message{ + Name: "David", + ResultCount: 47, + Anything: &anypb.Any{TypeUrl: "type.googleapis.com/a/path/" + proto.MessageName(nested), Value: nb}, + } + m5 := &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(nested), Value: nb} + + any1 := &pb2.MyMessage{Count: proto.Int32(47), Name: proto.String("David")} + proto.SetExtension(any1, pb2.E_Ext_More, &pb2.Ext{Data: proto.String("foo")}) + proto.SetExtension(any1, pb2.E_Ext_Text, proto.String("bar")) + any1b, err := proto.Marshal(any1) + if err != nil { + panic(err) + } + any2 := &pb2.MyMessage{Count: proto.Int32(42), Bikeshed: pb2.MyMessage_GREEN.Enum(), RepBytes: [][]byte{[]byte("roboto")}} + proto.SetExtension(any2, pb2.E_Ext_More, &pb2.Ext{Data: proto.String("baz")}) + any2b, err := proto.Marshal(any2) + if err != nil { + panic(err) + } + m6 := &pb3.Message{ + Name: "David", + ResultCount: 47, + Anything: &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(any1), Value: any1b}, + ManyThings: []*anypb.Any{ + &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(any2), Value: any2b}, + &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(any1), Value: any1b}, + }, + } + + const ( + m1Golden = ` +name: "David" +result_count: 47 +anything: < + [type.googleapis.com/proto3_test.Nested]: < + bunny: "Monty" + > +> +` + m2Golden = ` +name: "David" +result_count: 47 +anything: < + ["http://[::1]/type.googleapis.com/proto3_test.Nested"]: < + bunny: "Monty" + > +> +` + m3Golden = ` +name: "David" +result_count: 47 +anything: < + ["type.googleapis.com/\"/proto3_test.Nested"]: < + bunny: "Monty" + > +> +` + m4Golden = ` +name: "David" +result_count: 47 +anything: < + [type.googleapis.com/a/path/proto3_test.Nested]: < + bunny: "Monty" + > +> +` + m5Golden = ` +[type.googleapis.com/proto3_test.Nested]: < + bunny: "Monty" +> +` + m6Golden = ` +name: "David" +result_count: 47 +anything: < + [type.googleapis.com/proto2_test.MyMessage]: < + count: 47 + name: "David" + [proto2_test.Ext.more]: < + data: "foo" + > + [proto2_test.Ext.text]: "bar" + > +> +many_things: < + [type.googleapis.com/proto2_test.MyMessage]: < + count: 42 + bikeshed: GREEN + rep_bytes: "roboto" + [proto2_test.Ext.more]: < + data: "baz" + > + > +> +many_things: < + [type.googleapis.com/proto2_test.MyMessage]: < + count: 47 + name: "David" + [proto2_test.Ext.more]: < + data: "foo" + > + [proto2_test.Ext.text]: "bar" + > +> +` + ) + return []golden{ + {m1, strings.TrimSpace(m1Golden) + "\n", strings.TrimSpace(compact(m1Golden)) + " "}, + {m2, strings.TrimSpace(m2Golden) + "\n", strings.TrimSpace(compact(m2Golden)) + " "}, + {m3, strings.TrimSpace(m3Golden) + "\n", strings.TrimSpace(compact(m3Golden)) + " "}, + {m4, strings.TrimSpace(m4Golden) + "\n", strings.TrimSpace(compact(m4Golden)) + " "}, + {m5, strings.TrimSpace(m5Golden) + "\n", strings.TrimSpace(compact(m5Golden)) + " "}, + {m6, strings.TrimSpace(m6Golden) + "\n", strings.TrimSpace(compact(m6Golden)) + " "}, + } +} + +func TestMarshalGolden(t *testing.T) { + for _, tt := range goldenMessages { + t.Run("", func(t *testing.T) { + if got, want := expandedMarshaler.Text(tt.m), tt.t; got != want { + t.Errorf("message %v: got:\n%s\nwant:\n%s", tt.m, got, want) + } + if got, want := expandedCompactMarshaler.Text(tt.m), tt.c; got != want { + t.Errorf("message %v: got:\n`%s`\nwant:\n`%s`", tt.m, got, want) + } + }) + } +} + +func TestUnmarshalGolden(t *testing.T) { + for _, tt := range goldenMessages { + t.Run("", func(t *testing.T) { + want := tt.m + got := proto.Clone(tt.m) + got.Reset() + if err := proto.UnmarshalText(tt.t, got); err != nil { + t.Errorf("failed to unmarshal\n%s\nerror: %v", tt.t, err) + } + if !anyEqual(got, want) { + t.Errorf("message:\n%s\ngot:\n%s\nwant:\n%s", tt.t, got, want) + } + got.Reset() + if err := proto.UnmarshalText(tt.c, got); err != nil { + t.Errorf("failed to unmarshal\n%s\nerror: %v", tt.c, err) + } + if !anyEqual(got, want) { + t.Errorf("message:\n%s\ngot:\n%s\nwant:\n%s", tt.c, got, want) + } + }) + } +} + +func TestMarshalUnknownAny(t *testing.T) { + m := &pb3.Message{ + Anything: &anypb.Any{ + TypeUrl: "foo", + Value: []byte("bar"), + }, + } + want := `anything: < + type_url: "foo" + value: "bar" +> +` + got := expandedMarshaler.Text(m) + if got != want { + t.Errorf("got:\n%s\nwant:\n%s", got, want) + } +} + +func TestAmbiguousAny(t *testing.T) { + pb := &anypb.Any{} + err := proto.UnmarshalText(` + type_url: "ttt/proto3_test.Nested" + value: "\n\x05Monty" + `, pb) + if err != nil { + t.Errorf("unexpected proto.UnmarshalText error: %v", err) + } +} + +func TestUnmarshalOverwriteAny(t *testing.T) { + pb := &anypb.Any{} + err := proto.UnmarshalText(` + [type.googleapis.com/a/path/proto3_test.Nested]: < + bunny: "Monty" + > + [type.googleapis.com/a/path/proto3_test.Nested]: < + bunny: "Rabbit of Caerbannog" + > + `, pb) + want := `line 7: Any message unpacked multiple times, or "type_url" already set` + if err.Error() != want { + t.Errorf("incorrect error:\ngot: %v\nwant: %v", err.Error(), want) + } +} + +func TestUnmarshalAnyMixAndMatch(t *testing.T) { + pb := &anypb.Any{} + err := proto.UnmarshalText(` + value: "\n\x05Monty" + [type.googleapis.com/a/path/proto3_test.Nested]: < + bunny: "Rabbit of Caerbannog" + > + `, pb) + want := `line 5: Any message unpacked multiple times, or "value" already set` + if err.Error() != want { + t.Errorf("incorrect error:\ngot: %v\nwant: %v", err.Error(), want) + } +} + +// textMessage implements the methods that allow it to marshal and unmarshal +// itself as text. +type textMessage struct { +} + +func (*textMessage) MarshalText() ([]byte, error) { + return []byte("custom"), nil +} + +func (*textMessage) UnmarshalText(bytes []byte) error { + if string(bytes) != "custom" { + return errors.New("expected 'custom'") + } + return nil +} + +func (*textMessage) Reset() {} +func (*textMessage) String() string { return "" } +func (*textMessage) ProtoMessage() {} + +func newTestMessage() *pb2.MyMessage { + msg := &pb2.MyMessage{ + Count: proto.Int32(42), + Name: proto.String("Dave"), + Quote: proto.String(`"I didn't want to go."`), + Pet: []string{"bunny", "kitty", "horsey"}, + Inner: &pb2.InnerMessage{ + Host: proto.String("footrest.syd"), + Port: proto.Int32(7001), + Connected: proto.Bool(true), + }, + Others: []*pb2.OtherMessage{ + { + Key: proto.Int64(0xdeadbeef), + Value: []byte{1, 65, 7, 12}, + }, + { + Weight: proto.Float32(6.022), + Inner: &pb2.InnerMessage{ + Host: proto.String("lesha.mtv"), + Port: proto.Int32(8002), + }, + }, + }, + Bikeshed: pb2.MyMessage_BLUE.Enum(), + Somegroup: &pb2.MyMessage_SomeGroup{ + GroupField: proto.Int32(8), + }, + // One normally wouldn't do this. + // This is an undeclared tag 13, as a varint (wire type 0) with value 4. + XXX_unrecognized: []byte{13<<3 | 0, 4}, + } + ext := &pb2.Ext{ + Data: proto.String("Big gobs for big rats"), + } + if err := proto.SetExtension(msg, pb2.E_Ext_More, ext); err != nil { + panic(err) + } + greetings := []string{"adg", "easy", "cow"} + if err := proto.SetExtension(msg, pb2.E_Greeting, greetings); err != nil { + panic(err) + } + + // Add an unknown extension. We marshal a pb2.Ext, and fake the ID. + b, err := proto.Marshal(&pb2.Ext{Data: proto.String("3G skiing")}) + if err != nil { + panic(err) + } + b = append(proto.EncodeVarint(201<<3|proto.WireBytes), b...) + proto.SetRawExtension(msg, 201, b) + + // Extensions can be plain fields, too, so let's test that. + b = append(proto.EncodeVarint(202<<3|proto.WireVarint), 19) + proto.SetRawExtension(msg, 202, b) + + return msg +} + +const text = `count: 42 +name: "Dave" +quote: "\"I didn't want to go.\"" +pet: "bunny" +pet: "kitty" +pet: "horsey" +inner: < + host: "footrest.syd" + port: 7001 + connected: true +> +others: < + key: 3735928559 + value: "\001A\007\014" +> +others: < + weight: 6.022 + inner: < + host: "lesha.mtv" + port: 8002 + > +> +bikeshed: BLUE +SomeGroup { + group_field: 8 +} +/* 18 unknown bytes */ +13: 4 +201: "\t3G skiing" +202: 19 +[proto2_test.Ext.more]: < + data: "Big gobs for big rats" +> +[proto2_test.greeting]: "adg" +[proto2_test.greeting]: "easy" +[proto2_test.greeting]: "cow" +` + +func TestMarshalText(t *testing.T) { + buf := new(bytes.Buffer) + if err := proto.MarshalText(buf, newTestMessage()); err != nil { + t.Fatalf("proto.MarshalText: %v", err) + } + got := buf.String() + if diff := cmp.Diff(text, got); got != text { + t.Errorf("diff (-want +got):\n%v\n\ngot:\n%v\n\nwant:\n%v", diff, got, text) + } +} + +func TestMarshalTextCustomMessage(t *testing.T) { + buf := new(bytes.Buffer) + if err := proto.MarshalText(buf, &textMessage{}); err != nil { + t.Fatalf("proto.MarshalText: %v", err) + } + got := buf.String() + if got != "custom" { + t.Errorf("got:\n%v\n\nwant:\n%v", got, "custom") + } +} +func TestMarshalTextNil(t *testing.T) { + want := "" + tests := []proto.Message{nil, (*pb2.MyMessage)(nil)} + for i, test := range tests { + buf := new(bytes.Buffer) + if err := proto.MarshalText(buf, test); err != nil { + t.Fatal(err) + } + if got := buf.String(); got != want { + t.Errorf("%d: got %q want %q", i, got, want) + } + } +} + +func TestMarshalTextUnknownEnum(t *testing.T) { + // The Color enum only specifies values 0-2. + m := &pb2.MyMessage{Bikeshed: pb2.MyMessage_Color(3).Enum()} + got := m.String() + const want = `bikeshed:3 ` + if got != want { + t.Errorf("\n got %q\nwant %q", got, want) + } +} + +func TestTextOneof(t *testing.T) { + tests := []struct { + m proto.Message + want string + }{ + // zero message + {&pb2.Communique{}, ``}, + // scalar field + {&pb2.Communique{Union: &pb2.Communique_Number{4}}, `number:4`}, + // message field + {&pb2.Communique{Union: &pb2.Communique_Msg{ + &pb2.Strings{StringField: proto.String("why hello!")}, + }}, `msg:`}, + // bad oneof (should not panic) + {&pb2.Communique{Union: &pb2.Communique_Msg{nil}}, `msg:<>`}, + } + for _, test := range tests { + got := strings.TrimSpace(test.m.String()) + if got != test.want { + t.Errorf("got:\n%s\n\nwant:\n%s", got, test.want) + } + } +} + +func compact(src string) string { + // s/[ \n]+/ /g; s/ $//; + dst := make([]byte, len(src)) + space, comment := false, false + j := 0 + for i := 0; i < len(src); i++ { + if strings.HasPrefix(src[i:], "/*") { + comment = true + i++ + continue + } + if comment && strings.HasPrefix(src[i:], "*/") { + comment = false + i++ + continue + } + if comment { + continue + } + c := src[i] + if c == ' ' || c == '\n' { + space = true + continue + } + if j > 0 && (dst[j-1] == ':' || dst[j-1] == '<' || dst[j-1] == '{') { + space = false + } + if c == '{' { + space = false + } + if space { + dst[j] = ' ' + j++ + space = false + } + dst[j] = c + j++ + } + if space { + dst[j] = ' ' + j++ + } + return string(dst[0:j]) +} + +func TestCompactText(t *testing.T) { + got := proto.CompactTextString(newTestMessage()) + if got != compact(text) { + t.Errorf("got:\n%v\n\nwant:\n%v", got, compact(text)) + } +} + +func TestStringEscaping(t *testing.T) { + testCases := []struct { + in *pb2.Strings + out string + }{ + { + // Test data from C++ test (TextFormatTest.StringEscape). + // Single divergence: we don't escape apostrophes. + &pb2.Strings{StringField: proto.String("\"A string with ' characters \n and \r newlines and \t tabs and \001 slashes \\ and multiple spaces")}, + "string_field: \"\\\"A string with ' characters \\n and \\r newlines and \\t tabs and \\001 slashes \\\\ and multiple spaces\"\n", + }, + { + // Test data from the same C++ test. + &pb2.Strings{StringField: proto.String("\350\260\267\346\255\214")}, + "string_field: \"\\350\\260\\267\\346\\255\\214\"\n", + }, + { + // Some UTF-8. + &pb2.Strings{StringField: proto.String("\x00\x01\xff\x81")}, + `string_field: "\000\001\377\201"` + "\n", + }, + } + + for _, tc := range testCases { + t.Run("", func(t *testing.T) { + var buf bytes.Buffer + if err := proto.MarshalText(&buf, tc.in); err != nil { + t.Fatalf("proto.MarsalText error: %v", err) + } + got := buf.String() + if got != tc.out { + t.Fatalf("want:\n%s\n\nwant:\n%s", got, tc.out) + } + + // Check round-trip. + pb := new(pb2.Strings) + if err := proto.UnmarshalText(got, pb); err != nil { + t.Fatalf("proto.UnmarshalText error: %v", err) + } + if !proto.Equal(pb, tc.in) { + t.Fatalf("proto.Equal mismatch:\ngot:\n%v\n\nwant:\n%v", pb, tc.in) + } + }) + } +} + +// A limitedWriter accepts some output before it fails. +// This is a proxy for something like a nearly-full or imminently-failing disk, +// or a network connection that is about to die. +type limitedWriter struct { + b bytes.Buffer + limit int +} + +var outOfSpace = errors.New("proto: insufficient space") + +func (w *limitedWriter) Write(p []byte) (n int, err error) { + var avail = w.limit - w.b.Len() + if avail <= 0 { + return 0, outOfSpace + } + if len(p) <= avail { + return w.b.Write(p) + } + n, _ = w.b.Write(p[:avail]) + return n, outOfSpace +} + +func TestMarshalTextFailing(t *testing.T) { + // Try lots of different sizes to exercise more error code-paths. + for lim := 0; lim < len(text); lim++ { + buf := new(limitedWriter) + buf.limit = lim + err := proto.MarshalText(buf, newTestMessage()) + // We expect a certain error, but also some partial results in the buffer. + if err != outOfSpace { + t.Errorf("error mismatch: got %v, want %v", err, outOfSpace) + } + got := buf.b.String() + want := text[:buf.limit] + if got != want { + t.Errorf("text mismatch:\n\ngot:\n%v\n\nwant:\n%v", got, want) + } + } +} + +func TestFloats(t *testing.T) { + tests := []struct { + f float64 + want string + }{ + {0, "0"}, + {4.7, "4.7"}, + {math.Inf(1), "inf"}, + {math.Inf(-1), "-inf"}, + {math.NaN(), "nan"}, + } + for _, test := range tests { + msg := &pb2.FloatingPoint{F: &test.f} + got := strings.TrimSpace(msg.String()) + want := `f:` + test.want + if got != want { + t.Errorf("f=%f: got %q, want %q", test.f, got, want) + } + } +} + +func TestRepeatedNilText(t *testing.T) { + m := &pb2.MessageList{ + Message: []*pb2.MessageList_Message{ + nil, + &pb2.MessageList_Message{ + Name: proto.String("Horse"), + }, + nil, + }, + } + want := `Message { +} +Message { + name: "Horse" +} +Message { +} +` + if got := proto.MarshalTextString(m); got != want { + t.Errorf("got:\n%s\n\nwant:\n%s", got, want) + } +} + +func TestProto3Text(t *testing.T) { + tests := []struct { + m proto.Message + want string + }{ + // zero message + {&pb3.Message{}, ``}, + // zero message except for an empty byte slice + {&pb3.Message{Data: []byte{}}, ``}, + // trivial case + {&pb3.Message{Name: "Rob", HeightInCm: 175}, `name:"Rob" height_in_cm:175`}, + // empty map + {&pb2.MessageWithMap{}, ``}, + // non-empty map; map format is the same as a repeated struct, + // and they are sorted by key (numerically for numeric keys). + { + &pb2.MessageWithMap{NameMapping: map[int32]string{ + -1: "Negatory", + 7: "Lucky", + 1234: "Feist", + 6345789: "Otis", + }}, + `name_mapping: ` + + `name_mapping: ` + + `name_mapping: ` + + `name_mapping:`, + }, + // map with nil value; not well-defined, but we shouldn't crash + { + &pb2.MessageWithMap{MsgMapping: map[int64]*pb2.FloatingPoint{7: nil}}, + `msg_mapping: >`, + }, + } + for _, test := range tests { + got := strings.TrimSpace(test.m.String()) + if got != test.want { + t.Errorf("got:\n%s\n\nwant:\n%s", got, test.want) + } + } +} + +func TestRacyMarshal(t *testing.T) { + // This test should be run with the race detector. + + any := &pb2.MyMessage{Count: proto.Int32(47), Name: proto.String("David")} + proto.SetExtension(any, pb2.E_Ext_Text, proto.String("bar")) + b, err := proto.Marshal(any) + if err != nil { + panic(err) + } + m := &pb3.Message{ + Name: "David", + ResultCount: 47, + Anything: &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(any), Value: b}, + } + + wantText := proto.MarshalTextString(m) + wantBytes, err := proto.Marshal(m) + if err != nil { + t.Fatalf("proto.Marshal error: %v", err) + } + + var wg sync.WaitGroup + defer wg.Wait() + wg.Add(20) + for i := 0; i < 10; i++ { + go func() { + defer wg.Done() + got := proto.MarshalTextString(m) + if got != wantText { + t.Errorf("proto.MarshalTextString = %q, want %q", got, wantText) + } + }() + go func() { + defer wg.Done() + got, err := proto.Marshal(m) + if !bytes.Equal(got, wantBytes) || err != nil { + t.Errorf("proto.Marshal = (%x, %v), want (%x, nil)", got, err, wantBytes) + } + }() + } +} + +type UnmarshalTextTest struct { + in string + err string // if "", no error expected + out *pb2.MyMessage +} + +func buildExtStructTest(text string) UnmarshalTextTest { + msg := &pb2.MyMessage{ + Count: proto.Int32(42), + } + proto.SetExtension(msg, pb2.E_Ext_More, &pb2.Ext{ + Data: proto.String("Hello, world!"), + }) + return UnmarshalTextTest{in: text, out: msg} +} + +func buildExtDataTest(text string) UnmarshalTextTest { + msg := &pb2.MyMessage{ + Count: proto.Int32(42), + } + proto.SetExtension(msg, pb2.E_Ext_Text, proto.String("Hello, world!")) + proto.SetExtension(msg, pb2.E_Ext_Number, proto.Int32(1729)) + return UnmarshalTextTest{in: text, out: msg} +} + +func buildExtRepStringTest(text string) UnmarshalTextTest { + msg := &pb2.MyMessage{ + Count: proto.Int32(42), + } + if err := proto.SetExtension(msg, pb2.E_Greeting, []string{"bula", "hola"}); err != nil { + panic(err) + } + return UnmarshalTextTest{in: text, out: msg} +} + +var unmarshalTextTests = []UnmarshalTextTest{ + // Basic + { + in: " count:42\n name:\"Dave\" ", + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Name: proto.String("Dave"), + }, + }, + + // Empty quoted string + { + in: `count:42 name:""`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Name: proto.String(""), + }, + }, + + // Quoted string concatenation with double quotes + { + in: `count:42 name: "My name is "` + "\n" + `"elsewhere"`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Name: proto.String("My name is elsewhere"), + }, + }, + + // Quoted string concatenation with single quotes + { + in: "count:42 name: 'My name is '\n'elsewhere'", + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Name: proto.String("My name is elsewhere"), + }, + }, + + // Quoted string concatenations with mixed quotes + { + in: "count:42 name: 'My name is '\n\"elsewhere\"", + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Name: proto.String("My name is elsewhere"), + }, + }, + { + in: "count:42 name: \"My name is \"\n'elsewhere'", + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Name: proto.String("My name is elsewhere"), + }, + }, + + // Quoted string with escaped apostrophe + { + in: `count:42 name: "HOLIDAY - New Year\'s Day"`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Name: proto.String("HOLIDAY - New Year's Day"), + }, + }, + + // Quoted string with single quote + { + in: `count:42 name: 'Roger "The Ramster" Ramjet'`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Name: proto.String(`Roger "The Ramster" Ramjet`), + }, + }, + + // Quoted string with all the accepted special characters from the C++ test + { + in: `count:42 name: ` + "\"\\\"A string with \\' characters \\n and \\r newlines and \\t tabs and \\001 slashes \\\\ and multiple spaces\"", + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Name: proto.String("\"A string with ' characters \n and \r newlines and \t tabs and \001 slashes \\ and multiple spaces"), + }, + }, + + // Quoted string with quoted backslash + { + in: `count:42 name: "\\'xyz"`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Name: proto.String(`\'xyz`), + }, + }, + + // Quoted string with UTF-8 bytes. + { + in: "count:42 name: '\303\277\302\201\x00\xAB\xCD\xEF'", + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Name: proto.String("\303\277\302\201\x00\xAB\xCD\xEF"), + }, + }, + + // Quoted string with unicode escapes. + { + in: `count: 42 name: "\u0047\U00000047\uffff\U0010ffff"`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Name: proto.String("GG\uffff\U0010ffff"), + }, + }, + + // Bad quoted string + { + in: `inner: < host: "\0" >` + "\n", + err: `line 1.15: invalid quoted string "\0": \0 requires 2 following digits`, + }, + + // Bad \u escape + { + in: `count: 42 name: "\u000"`, + err: `line 1.16: invalid quoted string "\u000": \u requires 4 following digits`, + }, + + // Bad \U escape + { + in: `count: 42 name: "\U0000000"`, + err: `line 1.16: invalid quoted string "\U0000000": \U requires 8 following digits`, + }, + + // Bad \U escape + { + in: `count: 42 name: "\xxx"`, + err: `line 1.16: invalid quoted string "\xxx": \xxx contains non-hexadecimal digits`, + }, + + // Number too large for int64 + { + in: "count: 1 others { key: 123456789012345678901 }", + err: "line 1.23: invalid int64: 123456789012345678901", + }, + + // Number too large for int32 + { + in: "count: 1234567890123", + err: "line 1.7: invalid int32: 1234567890123", + }, + + // Number in hexadecimal + { + in: "count: 0x2beef", + out: &pb2.MyMessage{ + Count: proto.Int32(0x2beef), + }, + }, + + // Number in octal + { + in: "count: 024601", + out: &pb2.MyMessage{ + Count: proto.Int32(024601), + }, + }, + + // Floating point number with "f" suffix + { + in: "count: 4 others:< weight: 17.0f >", + out: &pb2.MyMessage{ + Count: proto.Int32(4), + Others: []*pb2.OtherMessage{ + { + Weight: proto.Float32(17), + }, + }, + }, + }, + + // Floating point positive infinity + { + in: "count: 4 bigfloat: inf", + out: &pb2.MyMessage{ + Count: proto.Int32(4), + Bigfloat: proto.Float64(math.Inf(1)), + }, + }, + + // Floating point negative infinity + { + in: "count: 4 bigfloat: -inf", + out: &pb2.MyMessage{ + Count: proto.Int32(4), + Bigfloat: proto.Float64(math.Inf(-1)), + }, + }, + + // Number too large for float32 + { + in: "others:< weight: 12345678901234567890123456789012345678901234567890 >", + err: "line 1.17: invalid float: 12345678901234567890123456789012345678901234567890", + }, + + // Number posing as a quoted string + { + in: `inner: < host: 12 >` + "\n", + err: `line 1.15: invalid string: 12`, + }, + + // Quoted string posing as int32 + { + in: `count: "12"`, + err: `line 1.7: invalid int32: "12"`, + }, + + // Quoted string posing a float32 + { + in: `others:< weight: "17.4" >`, + err: `line 1.17: invalid float: "17.4"`, + }, + + // unclosed bracket doesn't cause infinite loop + { + in: `[`, + err: `line 1.0: unclosed type_url or extension name`, + }, + + // Enum + { + in: `count:42 bikeshed: BLUE`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Bikeshed: pb2.MyMessage_BLUE.Enum(), + }, + }, + + // Repeated field + { + in: `count:42 pet: "horsey" pet:"bunny"`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Pet: []string{"horsey", "bunny"}, + }, + }, + + // Repeated field with list notation + { + in: `count:42 pet: ["horsey", "bunny"]`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Pet: []string{"horsey", "bunny"}, + }, + }, + + // Repeated message with/without colon and <>/{} + { + in: `count:42 others:{} others{} others:<> others:{}`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Others: []*pb2.OtherMessage{ + {}, + {}, + {}, + {}, + }, + }, + }, + + // Missing colon for inner message + { + in: `count:42 inner < host: "cauchy.syd" >`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Inner: &pb2.InnerMessage{ + Host: proto.String("cauchy.syd"), + }, + }, + }, + + // Missing colon for string field + { + in: `name "Dave"`, + err: `line 1.5: expected ':', found "\"Dave\""`, + }, + + // Missing colon for int32 field + { + in: `count 42`, + err: `line 1.6: expected ':', found "42"`, + }, + + // Missing required field + { + in: `name: "Pawel"`, + err: `required field proto2_test.MyMessage.count not set`, + out: &pb2.MyMessage{ + Name: proto.String("Pawel"), + }, + }, + + // Missing required field in a required submessage + { + in: `count: 42 we_must_go_deeper < leo_finally_won_an_oscar <> >`, + err: `required field proto2_test.InnerMessage.host not set`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + WeMustGoDeeper: &pb2.RequiredInnerMessage{LeoFinallyWonAnOscar: &pb2.InnerMessage{}}, + }, + }, + + // Repeated non-repeated field + { + in: `name: "Rob" name: "Russ"`, + err: `line 1.12: non-repeated field "name" was repeated`, + }, + + // Group + { + in: `count: 17 SomeGroup { group_field: 12 }`, + out: &pb2.MyMessage{ + Count: proto.Int32(17), + Somegroup: &pb2.MyMessage_SomeGroup{ + GroupField: proto.Int32(12), + }, + }, + }, + + // Semicolon between fields + { + in: `count:3;name:"Calvin"`, + out: &pb2.MyMessage{ + Count: proto.Int32(3), + Name: proto.String("Calvin"), + }, + }, + // Comma between fields + { + in: `count:4,name:"Ezekiel"`, + out: &pb2.MyMessage{ + Count: proto.Int32(4), + Name: proto.String("Ezekiel"), + }, + }, + + // Boolean false + { + in: `count:42 inner { host: "example.com" connected: false }`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Inner: &pb2.InnerMessage{ + Host: proto.String("example.com"), + Connected: proto.Bool(false), + }, + }, + }, + // Boolean true + { + in: `count:42 inner { host: "example.com" connected: true }`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Inner: &pb2.InnerMessage{ + Host: proto.String("example.com"), + Connected: proto.Bool(true), + }, + }, + }, + // Boolean 0 + { + in: `count:42 inner { host: "example.com" connected: 0 }`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Inner: &pb2.InnerMessage{ + Host: proto.String("example.com"), + Connected: proto.Bool(false), + }, + }, + }, + // Boolean 1 + { + in: `count:42 inner { host: "example.com" connected: 1 }`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Inner: &pb2.InnerMessage{ + Host: proto.String("example.com"), + Connected: proto.Bool(true), + }, + }, + }, + // Boolean f + { + in: `count:42 inner { host: "example.com" connected: f }`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Inner: &pb2.InnerMessage{ + Host: proto.String("example.com"), + Connected: proto.Bool(false), + }, + }, + }, + // Boolean t + { + in: `count:42 inner { host: "example.com" connected: t }`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Inner: &pb2.InnerMessage{ + Host: proto.String("example.com"), + Connected: proto.Bool(true), + }, + }, + }, + // Boolean False + { + in: `count:42 inner { host: "example.com" connected: False }`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Inner: &pb2.InnerMessage{ + Host: proto.String("example.com"), + Connected: proto.Bool(false), + }, + }, + }, + // Boolean True + { + in: `count:42 inner { host: "example.com" connected: True }`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Inner: &pb2.InnerMessage{ + Host: proto.String("example.com"), + Connected: proto.Bool(true), + }, + }, + }, + + // Extension + buildExtStructTest(`count: 42 [proto2_test.Ext.more]:`), + buildExtStructTest(`count: 42 [proto2_test.Ext.more] {data:"Hello, world!"}`), + buildExtDataTest(`count: 42 [proto2_test.Ext.text]:"Hello, world!" [proto2_test.Ext.number]:1729`), + buildExtRepStringTest(`count: 42 [proto2_test.greeting]:"bula" [proto2_test.greeting]:"hola"`), + { + in: `[proto2_test.complex]:<>`, + err: `line 1.20: extension field "proto2_test.complex" does not extend message "proto2_test.MyMessage"`, + }, + + // Big all-in-one + { + in: "count:42 # Meaning\n" + + `name:"Dave" ` + + `quote:"\"I didn't want to go.\"" ` + + `pet:"bunny" ` + + `pet:"kitty" ` + + `pet:"horsey" ` + + `inner:<` + + ` host:"footrest.syd" ` + + ` port:7001 ` + + ` connected:true ` + + `> ` + + `others:<` + + ` key:3735928559 ` + + ` value:"\x01A\a\f" ` + + `> ` + + `others:<` + + " weight:58.9 # Atomic weight of Co\n" + + ` inner:<` + + ` host:"lesha.mtv" ` + + ` port:8002 ` + + ` >` + + `>`, + out: &pb2.MyMessage{ + Count: proto.Int32(42), + Name: proto.String("Dave"), + Quote: proto.String(`"I didn't want to go."`), + Pet: []string{"bunny", "kitty", "horsey"}, + Inner: &pb2.InnerMessage{ + Host: proto.String("footrest.syd"), + Port: proto.Int32(7001), + Connected: proto.Bool(true), + }, + Others: []*pb2.OtherMessage{ + { + Key: proto.Int64(3735928559), + Value: []byte{0x1, 'A', '\a', '\f'}, + }, + { + Weight: proto.Float32(58.9), + Inner: &pb2.InnerMessage{ + Host: proto.String("lesha.mtv"), + Port: proto.Int32(8002), + }, + }, + }, + }, + }, +} + +func TestUnmarshalText(t *testing.T) { + for _, test := range unmarshalTextTests { + t.Run("", func(t *testing.T) { + pb := new(pb2.MyMessage) + err := proto.UnmarshalText(test.in, pb) + if test.err == "" { + // We don't expect failure. + if err != nil { + t.Errorf("proto.UnmarshalText error: %v", err) + } else if !proto.Equal(pb, test.out) { + t.Errorf("proto.Equal mismatch:\ngot: %v\nwant: %v", pb, test.out) + } + } else { + // We do expect failure. + if err == nil { + t.Errorf("proto.UnmarshalText: got nil error, want %v", test.err) + } else if !strings.Contains(err.Error(), test.err) { + t.Errorf("proto.UnmarshalText error mismatch:\ngot: %v\nwant: %v", err.Error(), test.err) + } else if _, ok := err.(*proto.RequiredNotSetError); ok && test.out != nil && !proto.Equal(pb, test.out) { + t.Errorf("proto.Equal mismatch:\ngot %v\nwant: %v", pb, test.out) + } + } + }) + } +} + +func TestUnmarshalTextCustomMessage(t *testing.T) { + msg := &textMessage{} + if err := proto.UnmarshalText("custom", msg); err != nil { + t.Errorf("proto.UnmarshalText error: %v", err) + } + if err := proto.UnmarshalText("not custom", msg); err == nil { + t.Errorf("proto.UnmarshalText: got nil error, want non-nil") + } +} + +// Regression test; this caused a panic. +func TestRepeatedEnum(t *testing.T) { + pb := new(pb2.RepeatedEnum) + if err := proto.UnmarshalText("color: RED", pb); err != nil { + t.Fatal(err) + } + exp := &pb2.RepeatedEnum{ + Color: []pb2.RepeatedEnum_Color{pb2.RepeatedEnum_RED}, + } + if !proto.Equal(pb, exp) { + t.Errorf("proto.Equal mismatch:\ngot: %v\nwant %v", pb, exp) + } +} + +func TestProto3TextParsing(t *testing.T) { + m := new(pb3.Message) + const in = `name: "Wallace" true_scotsman: true` + want := &pb3.Message{ + Name: "Wallace", + TrueScotsman: true, + } + if err := proto.UnmarshalText(in, m); err != nil { + t.Fatal(err) + } + if !proto.Equal(m, want) { + t.Errorf("proto.Equal mismatch:\ngot: %v\nwant %v", m, want) + } +} + +func TestMapParsing(t *testing.T) { + m := new(pb2.MessageWithMap) + const in = `name_mapping: name_mapping:` + + `msg_mapping:,>` + // separating commas are okay + `msg_mapping>` + // no colon after "value" + `msg_mapping:>` + // omitted key + `byte_mapping:` + + `byte_mapping:<>` // omitted key and value + want := &pb2.MessageWithMap{ + NameMapping: map[int32]string{ + 1: "Beatles", + 1234: "Feist", + }, + MsgMapping: map[int64]*pb2.FloatingPoint{ + -4: {F: proto.Float64(2.0)}, + -2: {F: proto.Float64(4.0)}, + 0: {F: proto.Float64(5.0)}, + }, + ByteMapping: map[bool][]byte{ + false: nil, + true: []byte("so be it"), + }, + } + if err := proto.UnmarshalText(in, m); err != nil { + t.Fatal(err) + } + if !proto.Equal(m, want) { + t.Errorf("proto.Equal mismatch:\ngot: %v\nwant %v", m, want) + } +} + +func TestOneofParsing(t *testing.T) { + const in = `name:"Shrek"` + m := new(pb2.Communique) + want := &pb2.Communique{Union: &pb2.Communique_Name{"Shrek"}} + if err := proto.UnmarshalText(in, m); err != nil { + t.Fatal(err) + } + if !proto.Equal(m, want) { + t.Errorf("\n got %v\nwant %v", m, want) + } + + const inOverwrite = `name:"Shrek" number:42` + m = new(pb2.Communique) + testErr := "line 1.13: field 'number' would overwrite already parsed oneof 'union'" + if err := proto.UnmarshalText(inOverwrite, m); err == nil { + t.Errorf("proto.UnmarshalText: got nil error, want %v", testErr) + } else if err.Error() != testErr { + t.Errorf("error mismatch:\ngot: %v\nwant: %v", err.Error(), testErr) + } +} diff --git a/pkg/golang-protobuf/proto/wire.go b/pkg/golang-protobuf/proto/wire.go new file mode 100644 index 000000000..d7c28da5a --- /dev/null +++ b/pkg/golang-protobuf/proto/wire.go @@ -0,0 +1,78 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +import ( + protoV2 "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/runtime/protoiface" +) + +// Size returns the size in bytes of the wire-format encoding of m. +func Size(m Message) int { + if m == nil { + return 0 + } + mi := MessageV2(m) + return protoV2.Size(mi) +} + +// Marshal returns the wire-format encoding of m. +func Marshal(m Message) ([]byte, error) { + b, err := marshalAppend(nil, m, false) + if b == nil { + b = zeroBytes + } + return b, err +} + +var zeroBytes = make([]byte, 0, 0) + +func marshalAppend(buf []byte, m Message, deterministic bool) ([]byte, error) { + if m == nil { + return nil, ErrNil + } + mi := MessageV2(m) + nbuf, err := protoV2.MarshalOptions{ + Deterministic: deterministic, + AllowPartial: true, + }.MarshalAppend(buf, mi) + if err != nil { + return buf, err + } + if len(buf) == len(nbuf) { + if !mi.ProtoReflect().IsValid() { + return buf, ErrNil + } + } + return nbuf, checkRequiredNotSet(mi) +} + +// Unmarshal parses a wire-format message in b and places the decoded results in m. +// +// Unmarshal resets m before starting to unmarshal, so any existing data in m is always +// removed. Use UnmarshalMerge to preserve and append to existing data. +func Unmarshal(b []byte, m Message) error { + m.Reset() + return UnmarshalMerge(b, m) +} + +// UnmarshalMerge parses a wire-format message in b and places the decoded results in m. +func UnmarshalMerge(b []byte, m Message) error { + mi := MessageV2(m) + out, err := protoV2.UnmarshalOptions{ + AllowPartial: true, + Merge: true, + }.UnmarshalState(protoiface.UnmarshalInput{ + Buf: b, + Message: mi.ProtoReflect(), + }) + if err != nil { + return err + } + if out.Flags&protoiface.UnmarshalInitialized > 0 { + return nil + } + return checkRequiredNotSet(mi) +} diff --git a/pkg/golang-protobuf/proto/wrappers.go b/pkg/golang-protobuf/proto/wrappers.go new file mode 100644 index 000000000..398e34859 --- /dev/null +++ b/pkg/golang-protobuf/proto/wrappers.go @@ -0,0 +1,34 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +// Bool stores v in a new bool value and returns a pointer to it. +func Bool(v bool) *bool { return &v } + +// Int stores v in a new int32 value and returns a pointer to it. +// +// Deprecated: Use Int32 instead. +func Int(v int) *int32 { return Int32(int32(v)) } + +// Int32 stores v in a new int32 value and returns a pointer to it. +func Int32(v int32) *int32 { return &v } + +// Int64 stores v in a new int64 value and returns a pointer to it. +func Int64(v int64) *int64 { return &v } + +// Uint32 stores v in a new uint32 value and returns a pointer to it. +func Uint32(v uint32) *uint32 { return &v } + +// Uint64 stores v in a new uint64 value and returns a pointer to it. +func Uint64(v uint64) *uint64 { return &v } + +// Float32 stores v in a new float32 value and returns a pointer to it. +func Float32(v float32) *float32 { return &v } + +// Float64 stores v in a new float64 value and returns a pointer to it. +func Float64(v float64) *float64 { return &v } + +// String stores v in a new string value and returns a pointer to it. +func String(v string) *string { return &v } diff --git a/pkg/golang-protobuf/protoc-gen-go/descriptor/descriptor.pb.go b/pkg/golang-protobuf/protoc-gen-go/descriptor/descriptor.pb.go new file mode 100644 index 000000000..63dc05785 --- /dev/null +++ b/pkg/golang-protobuf/protoc-gen-go/descriptor/descriptor.pb.go @@ -0,0 +1,200 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.proto + +package descriptor + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + reflect "reflect" +) + +// Symbols defined in public import of google/protobuf/descriptor.proto. + +type FieldDescriptorProto_Type = descriptorpb.FieldDescriptorProto_Type + +const FieldDescriptorProto_TYPE_DOUBLE = descriptorpb.FieldDescriptorProto_TYPE_DOUBLE +const FieldDescriptorProto_TYPE_FLOAT = descriptorpb.FieldDescriptorProto_TYPE_FLOAT +const FieldDescriptorProto_TYPE_INT64 = descriptorpb.FieldDescriptorProto_TYPE_INT64 +const FieldDescriptorProto_TYPE_UINT64 = descriptorpb.FieldDescriptorProto_TYPE_UINT64 +const FieldDescriptorProto_TYPE_INT32 = descriptorpb.FieldDescriptorProto_TYPE_INT32 +const FieldDescriptorProto_TYPE_FIXED64 = descriptorpb.FieldDescriptorProto_TYPE_FIXED64 +const FieldDescriptorProto_TYPE_FIXED32 = descriptorpb.FieldDescriptorProto_TYPE_FIXED32 +const FieldDescriptorProto_TYPE_BOOL = descriptorpb.FieldDescriptorProto_TYPE_BOOL +const FieldDescriptorProto_TYPE_STRING = descriptorpb.FieldDescriptorProto_TYPE_STRING +const FieldDescriptorProto_TYPE_GROUP = descriptorpb.FieldDescriptorProto_TYPE_GROUP +const FieldDescriptorProto_TYPE_MESSAGE = descriptorpb.FieldDescriptorProto_TYPE_MESSAGE +const FieldDescriptorProto_TYPE_BYTES = descriptorpb.FieldDescriptorProto_TYPE_BYTES +const FieldDescriptorProto_TYPE_UINT32 = descriptorpb.FieldDescriptorProto_TYPE_UINT32 +const FieldDescriptorProto_TYPE_ENUM = descriptorpb.FieldDescriptorProto_TYPE_ENUM +const FieldDescriptorProto_TYPE_SFIXED32 = descriptorpb.FieldDescriptorProto_TYPE_SFIXED32 +const FieldDescriptorProto_TYPE_SFIXED64 = descriptorpb.FieldDescriptorProto_TYPE_SFIXED64 +const FieldDescriptorProto_TYPE_SINT32 = descriptorpb.FieldDescriptorProto_TYPE_SINT32 +const FieldDescriptorProto_TYPE_SINT64 = descriptorpb.FieldDescriptorProto_TYPE_SINT64 + +var FieldDescriptorProto_Type_name = descriptorpb.FieldDescriptorProto_Type_name +var FieldDescriptorProto_Type_value = descriptorpb.FieldDescriptorProto_Type_value + +type FieldDescriptorProto_Label = descriptorpb.FieldDescriptorProto_Label + +const FieldDescriptorProto_LABEL_OPTIONAL = descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL +const FieldDescriptorProto_LABEL_REQUIRED = descriptorpb.FieldDescriptorProto_LABEL_REQUIRED +const FieldDescriptorProto_LABEL_REPEATED = descriptorpb.FieldDescriptorProto_LABEL_REPEATED + +var FieldDescriptorProto_Label_name = descriptorpb.FieldDescriptorProto_Label_name +var FieldDescriptorProto_Label_value = descriptorpb.FieldDescriptorProto_Label_value + +type FileOptions_OptimizeMode = descriptorpb.FileOptions_OptimizeMode + +const FileOptions_SPEED = descriptorpb.FileOptions_SPEED +const FileOptions_CODE_SIZE = descriptorpb.FileOptions_CODE_SIZE +const FileOptions_LITE_RUNTIME = descriptorpb.FileOptions_LITE_RUNTIME + +var FileOptions_OptimizeMode_name = descriptorpb.FileOptions_OptimizeMode_name +var FileOptions_OptimizeMode_value = descriptorpb.FileOptions_OptimizeMode_value + +type FieldOptions_CType = descriptorpb.FieldOptions_CType + +const FieldOptions_STRING = descriptorpb.FieldOptions_STRING +const FieldOptions_CORD = descriptorpb.FieldOptions_CORD +const FieldOptions_STRING_PIECE = descriptorpb.FieldOptions_STRING_PIECE + +var FieldOptions_CType_name = descriptorpb.FieldOptions_CType_name +var FieldOptions_CType_value = descriptorpb.FieldOptions_CType_value + +type FieldOptions_JSType = descriptorpb.FieldOptions_JSType + +const FieldOptions_JS_NORMAL = descriptorpb.FieldOptions_JS_NORMAL +const FieldOptions_JS_STRING = descriptorpb.FieldOptions_JS_STRING +const FieldOptions_JS_NUMBER = descriptorpb.FieldOptions_JS_NUMBER + +var FieldOptions_JSType_name = descriptorpb.FieldOptions_JSType_name +var FieldOptions_JSType_value = descriptorpb.FieldOptions_JSType_value + +type MethodOptions_IdempotencyLevel = descriptorpb.MethodOptions_IdempotencyLevel + +const MethodOptions_IDEMPOTENCY_UNKNOWN = descriptorpb.MethodOptions_IDEMPOTENCY_UNKNOWN +const MethodOptions_NO_SIDE_EFFECTS = descriptorpb.MethodOptions_NO_SIDE_EFFECTS +const MethodOptions_IDEMPOTENT = descriptorpb.MethodOptions_IDEMPOTENT + +var MethodOptions_IdempotencyLevel_name = descriptorpb.MethodOptions_IdempotencyLevel_name +var MethodOptions_IdempotencyLevel_value = descriptorpb.MethodOptions_IdempotencyLevel_value + +type FileDescriptorSet = descriptorpb.FileDescriptorSet +type FileDescriptorProto = descriptorpb.FileDescriptorProto +type DescriptorProto = descriptorpb.DescriptorProto +type ExtensionRangeOptions = descriptorpb.ExtensionRangeOptions +type FieldDescriptorProto = descriptorpb.FieldDescriptorProto +type OneofDescriptorProto = descriptorpb.OneofDescriptorProto +type EnumDescriptorProto = descriptorpb.EnumDescriptorProto +type EnumValueDescriptorProto = descriptorpb.EnumValueDescriptorProto +type ServiceDescriptorProto = descriptorpb.ServiceDescriptorProto +type MethodDescriptorProto = descriptorpb.MethodDescriptorProto + +const Default_MethodDescriptorProto_ClientStreaming = descriptorpb.Default_MethodDescriptorProto_ClientStreaming +const Default_MethodDescriptorProto_ServerStreaming = descriptorpb.Default_MethodDescriptorProto_ServerStreaming + +type FileOptions = descriptorpb.FileOptions + +const Default_FileOptions_JavaMultipleFiles = descriptorpb.Default_FileOptions_JavaMultipleFiles +const Default_FileOptions_JavaStringCheckUtf8 = descriptorpb.Default_FileOptions_JavaStringCheckUtf8 +const Default_FileOptions_OptimizeFor = descriptorpb.Default_FileOptions_OptimizeFor +const Default_FileOptions_CcGenericServices = descriptorpb.Default_FileOptions_CcGenericServices +const Default_FileOptions_JavaGenericServices = descriptorpb.Default_FileOptions_JavaGenericServices +const Default_FileOptions_PyGenericServices = descriptorpb.Default_FileOptions_PyGenericServices +const Default_FileOptions_PhpGenericServices = descriptorpb.Default_FileOptions_PhpGenericServices +const Default_FileOptions_Deprecated = descriptorpb.Default_FileOptions_Deprecated +const Default_FileOptions_CcEnableArenas = descriptorpb.Default_FileOptions_CcEnableArenas + +type MessageOptions = descriptorpb.MessageOptions + +const Default_MessageOptions_MessageSetWireFormat = descriptorpb.Default_MessageOptions_MessageSetWireFormat +const Default_MessageOptions_NoStandardDescriptorAccessor = descriptorpb.Default_MessageOptions_NoStandardDescriptorAccessor +const Default_MessageOptions_Deprecated = descriptorpb.Default_MessageOptions_Deprecated + +type FieldOptions = descriptorpb.FieldOptions + +const Default_FieldOptions_Ctype = descriptorpb.Default_FieldOptions_Ctype +const Default_FieldOptions_Jstype = descriptorpb.Default_FieldOptions_Jstype +const Default_FieldOptions_Lazy = descriptorpb.Default_FieldOptions_Lazy +const Default_FieldOptions_Deprecated = descriptorpb.Default_FieldOptions_Deprecated +const Default_FieldOptions_Weak = descriptorpb.Default_FieldOptions_Weak + +type OneofOptions = descriptorpb.OneofOptions +type EnumOptions = descriptorpb.EnumOptions + +const Default_EnumOptions_Deprecated = descriptorpb.Default_EnumOptions_Deprecated + +type EnumValueOptions = descriptorpb.EnumValueOptions + +const Default_EnumValueOptions_Deprecated = descriptorpb.Default_EnumValueOptions_Deprecated + +type ServiceOptions = descriptorpb.ServiceOptions + +const Default_ServiceOptions_Deprecated = descriptorpb.Default_ServiceOptions_Deprecated + +type MethodOptions = descriptorpb.MethodOptions + +const Default_MethodOptions_Deprecated = descriptorpb.Default_MethodOptions_Deprecated +const Default_MethodOptions_IdempotencyLevel = descriptorpb.Default_MethodOptions_IdempotencyLevel + +type UninterpretedOption = descriptorpb.UninterpretedOption +type SourceCodeInfo = descriptorpb.SourceCodeInfo +type GeneratedCodeInfo = descriptorpb.GeneratedCodeInfo +type DescriptorProto_ExtensionRange = descriptorpb.DescriptorProto_ExtensionRange +type DescriptorProto_ReservedRange = descriptorpb.DescriptorProto_ReservedRange +type EnumDescriptorProto_EnumReservedRange = descriptorpb.EnumDescriptorProto_EnumReservedRange +type UninterpretedOption_NamePart = descriptorpb.UninterpretedOption_NamePart +type SourceCodeInfo_Location = descriptorpb.SourceCodeInfo_Location +type GeneratedCodeInfo_Annotation = descriptorpb.GeneratedCodeInfo_Annotation + +var File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto protoreflect.FileDescriptor + +var file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawDesc = []byte{ + 0x0a, 0x44, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, + 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, + 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x3b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x32, +} + +var file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_goTypes = []interface{}{} +var file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_init() } +func file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_init() { + if File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_goTypes, + DependencyIndexes: file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_depIdxs, + }.Build() + File_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto = out.File + file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_rawDesc = nil + file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_goTypes = nil + file_github_com_golang_protobuf_protoc_gen_go_descriptor_descriptor_proto_depIdxs = nil +} diff --git a/pkg/golang-protobuf/protoc-gen-go/generator/generator.go b/pkg/golang-protobuf/protoc-gen-go/generator/generator.go new file mode 100644 index 000000000..12ff35b94 --- /dev/null +++ b/pkg/golang-protobuf/protoc-gen-go/generator/generator.go @@ -0,0 +1,2789 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package generator is deprecated. +// +// This package is excluded from the Go protocol buffer compatibility guarantee +// and may be deleted at some point in the future. +// +// Deprecated: Use the "google.golang.org/protobuf/compiler/protogen" package +// instead to write protoc plugins in Go. +package generator + +import ( + "bufio" + "bytes" + "compress/gzip" + "crypto/sha256" + "encoding/hex" + "fmt" + "go/ast" + "go/build" + "go/parser" + "go/printer" + "go/token" + "log" + "os" + "path" + "sort" + "strconv" + "strings" + "unicode" + "unicode/utf8" + + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/protoc-gen-go/generator/internal/remap" + + "github.com/golang/protobuf/protoc-gen-go/descriptor" + plugin "github.com/golang/protobuf/protoc-gen-go/plugin" +) + +func init() { + fmt.Fprint(os.Stderr, + "WARNING: Package \"github.com/golang/protobuf/protoc-gen-go/generator\" is deprecated.\n"+ + "\tA future release of golang/protobuf will delete this package,\n"+ + "\twhich has long been excluded from the compatibility promise.\n\n") +} + +// generatedCodeVersion indicates a version of the generated code. +// It is incremented whenever an incompatibility between the generated code and +// proto package is introduced; the generated code references +// a constant, proto.ProtoPackageIsVersionN (where N is generatedCodeVersion). +const generatedCodeVersion = 3 + +// A Plugin provides functionality to add to the output during Go code generation, +// such as to produce RPC stubs. +type Plugin interface { + // Name identifies the plugin. + Name() string + // Init is called once after data structures are built but before + // code generation begins. + Init(g *Generator) + // Generate produces the code generated by the plugin for this file, + // except for the imports, by calling the generator's methods P, In, and Out. + Generate(file *FileDescriptor) + // GenerateImports produces the import declarations for this file. + // It is called after Generate. + GenerateImports(file *FileDescriptor) +} + +var plugins []Plugin + +// RegisterPlugin installs a (second-order) plugin to be run when the Go output is generated. +// It is typically called during initialization. +func RegisterPlugin(p Plugin) { + plugins = append(plugins, p) +} + +// A GoImportPath is the import path of a Go package. e.g., "google.golang.org/genproto/protobuf". +type GoImportPath string + +func (p GoImportPath) String() string { return strconv.Quote(string(p)) } + +// A GoPackageName is the name of a Go package. e.g., "protobuf". +type GoPackageName string + +// Each type we import as a protocol buffer (other than FileDescriptorProto) needs +// a pointer to the FileDescriptorProto that represents it. These types achieve that +// wrapping by placing each Proto inside a struct with the pointer to its File. The +// structs have the same names as their contents, with "Proto" removed. +// FileDescriptor is used to store the things that it points to. + +// The file and package name method are common to messages and enums. +type common struct { + file *FileDescriptor // File this object comes from. +} + +// GoImportPath is the import path of the Go package containing the type. +func (c *common) GoImportPath() GoImportPath { + return c.file.importPath +} + +func (c *common) File() *FileDescriptor { return c.file } + +func fileIsProto3(file *descriptor.FileDescriptorProto) bool { + return file.GetSyntax() == "proto3" +} + +func (c *common) proto3() bool { return fileIsProto3(c.file.FileDescriptorProto) } + +// Descriptor represents a protocol buffer message. +type Descriptor struct { + common + *descriptor.DescriptorProto + parent *Descriptor // The containing message, if any. + nested []*Descriptor // Inner messages, if any. + enums []*EnumDescriptor // Inner enums, if any. + ext []*ExtensionDescriptor // Extensions, if any. + typename []string // Cached typename vector. + index int // The index into the container, whether the file or another message. + path string // The SourceCodeInfo path as comma-separated integers. + group bool +} + +// TypeName returns the elements of the dotted type name. +// The package name is not part of this name. +func (d *Descriptor) TypeName() []string { + if d.typename != nil { + return d.typename + } + n := 0 + for parent := d; parent != nil; parent = parent.parent { + n++ + } + s := make([]string, n) + for parent := d; parent != nil; parent = parent.parent { + n-- + s[n] = parent.GetName() + } + d.typename = s + return s +} + +// EnumDescriptor describes an enum. If it's at top level, its parent will be nil. +// Otherwise it will be the descriptor of the message in which it is defined. +type EnumDescriptor struct { + common + *descriptor.EnumDescriptorProto + parent *Descriptor // The containing message, if any. + typename []string // Cached typename vector. + index int // The index into the container, whether the file or a message. + path string // The SourceCodeInfo path as comma-separated integers. +} + +// TypeName returns the elements of the dotted type name. +// The package name is not part of this name. +func (e *EnumDescriptor) TypeName() (s []string) { + if e.typename != nil { + return e.typename + } + name := e.GetName() + if e.parent == nil { + s = make([]string, 1) + } else { + pname := e.parent.TypeName() + s = make([]string, len(pname)+1) + copy(s, pname) + } + s[len(s)-1] = name + e.typename = s + return s +} + +// Everything but the last element of the full type name, CamelCased. +// The values of type Foo.Bar are call Foo_value1... not Foo_Bar_value1... . +func (e *EnumDescriptor) prefix() string { + if e.parent == nil { + // If the enum is not part of a message, the prefix is just the type name. + return CamelCase(*e.Name) + "_" + } + typeName := e.TypeName() + return CamelCaseSlice(typeName[0:len(typeName)-1]) + "_" +} + +// The integer value of the named constant in this enumerated type. +func (e *EnumDescriptor) integerValueAsString(name string) string { + for _, c := range e.Value { + if c.GetName() == name { + return fmt.Sprint(c.GetNumber()) + } + } + log.Fatal("cannot find value for enum constant") + return "" +} + +// ExtensionDescriptor describes an extension. If it's at top level, its parent will be nil. +// Otherwise it will be the descriptor of the message in which it is defined. +type ExtensionDescriptor struct { + common + *descriptor.FieldDescriptorProto + parent *Descriptor // The containing message, if any. +} + +// TypeName returns the elements of the dotted type name. +// The package name is not part of this name. +func (e *ExtensionDescriptor) TypeName() (s []string) { + name := e.GetName() + if e.parent == nil { + // top-level extension + s = make([]string, 1) + } else { + pname := e.parent.TypeName() + s = make([]string, len(pname)+1) + copy(s, pname) + } + s[len(s)-1] = name + return s +} + +// DescName returns the variable name used for the generated descriptor. +func (e *ExtensionDescriptor) DescName() string { + // The full type name. + typeName := e.TypeName() + // Each scope of the extension is individually CamelCased, and all are joined with "_" with an "E_" prefix. + for i, s := range typeName { + typeName[i] = CamelCase(s) + } + return "E_" + strings.Join(typeName, "_") +} + +// ImportedDescriptor describes a type that has been publicly imported from another file. +type ImportedDescriptor struct { + common + o Object +} + +func (id *ImportedDescriptor) TypeName() []string { return id.o.TypeName() } + +// FileDescriptor describes an protocol buffer descriptor file (.proto). +// It includes slices of all the messages and enums defined within it. +// Those slices are constructed by WrapTypes. +type FileDescriptor struct { + *descriptor.FileDescriptorProto + desc []*Descriptor // All the messages defined in this file. + enum []*EnumDescriptor // All the enums defined in this file. + ext []*ExtensionDescriptor // All the top-level extensions defined in this file. + imp []*ImportedDescriptor // All types defined in files publicly imported by this file. + + // Comments, stored as a map of path (comma-separated integers) to the comment. + comments map[string]*descriptor.SourceCodeInfo_Location + + // The full list of symbols that are exported, + // as a map from the exported object to its symbols. + // This is used for supporting public imports. + exported map[Object][]symbol + + importPath GoImportPath // Import path of this file's package. + packageName GoPackageName // Name of this file's Go package. + + proto3 bool // whether to generate proto3 code for this file +} + +// VarName is the variable name we'll use in the generated code to refer +// to the compressed bytes of this descriptor. It is not exported, so +// it is only valid inside the generated package. +func (d *FileDescriptor) VarName() string { + h := sha256.Sum256([]byte(d.GetName())) + return fmt.Sprintf("fileDescriptor_%s", hex.EncodeToString(h[:8])) +} + +// goPackageOption interprets the file's go_package option. +// If there is no go_package, it returns ("", "", false). +// If there's a simple name, it returns ("", pkg, true). +// If the option implies an import path, it returns (impPath, pkg, true). +func (d *FileDescriptor) goPackageOption() (impPath GoImportPath, pkg GoPackageName, ok bool) { + opt := d.GetOptions().GetGoPackage() + if opt == "" { + return "", "", false + } + // A semicolon-delimited suffix delimits the import path and package name. + sc := strings.Index(opt, ";") + if sc >= 0 { + return GoImportPath(opt[:sc]), cleanPackageName(opt[sc+1:]), true + } + // The presence of a slash implies there's an import path. + slash := strings.LastIndex(opt, "/") + if slash >= 0 { + return GoImportPath(opt), cleanPackageName(opt[slash+1:]), true + } + return "", cleanPackageName(opt), true +} + +// goFileName returns the output name for the generated Go file. +func (d *FileDescriptor) goFileName(pathType pathType) string { + name := *d.Name + if ext := path.Ext(name); ext == ".proto" || ext == ".protodevel" { + name = name[:len(name)-len(ext)] + } + name += ".pb.go" + + if pathType == pathTypeSourceRelative { + return name + } + + // Does the file have a "go_package" option? + // If it does, it may override the filename. + if impPath, _, ok := d.goPackageOption(); ok && impPath != "" { + // Replace the existing dirname with the declared import path. + _, name = path.Split(name) + name = path.Join(string(impPath), name) + return name + } + + return name +} + +func (d *FileDescriptor) addExport(obj Object, sym symbol) { + d.exported[obj] = append(d.exported[obj], sym) +} + +// symbol is an interface representing an exported Go symbol. +type symbol interface { + // GenerateAlias should generate an appropriate alias + // for the symbol from the named package. + GenerateAlias(g *Generator, filename string, pkg GoPackageName) +} + +type messageSymbol struct { + sym string + hasExtensions, isMessageSet bool + oneofTypes []string +} + +type getterSymbol struct { + name string + typ string + typeName string // canonical name in proto world; empty for proto.Message and similar + genType bool // whether typ contains a generated type (message/group/enum) +} + +func (ms *messageSymbol) GenerateAlias(g *Generator, filename string, pkg GoPackageName) { + g.P("// ", ms.sym, " from public import ", filename) + g.P("type ", ms.sym, " = ", pkg, ".", ms.sym) + for _, name := range ms.oneofTypes { + g.P("type ", name, " = ", pkg, ".", name) + } +} + +type enumSymbol struct { + name string + proto3 bool // Whether this came from a proto3 file. +} + +func (es enumSymbol) GenerateAlias(g *Generator, filename string, pkg GoPackageName) { + s := es.name + g.P("// ", s, " from public import ", filename) + g.P("type ", s, " = ", pkg, ".", s) + g.P("var ", s, "_name = ", pkg, ".", s, "_name") + g.P("var ", s, "_value = ", pkg, ".", s, "_value") +} + +type constOrVarSymbol struct { + sym string + typ string // either "const" or "var" + cast string // if non-empty, a type cast is required (used for enums) +} + +func (cs constOrVarSymbol) GenerateAlias(g *Generator, filename string, pkg GoPackageName) { + v := string(pkg) + "." + cs.sym + if cs.cast != "" { + v = cs.cast + "(" + v + ")" + } + g.P(cs.typ, " ", cs.sym, " = ", v) +} + +// Object is an interface abstracting the abilities shared by enums, messages, extensions and imported objects. +type Object interface { + GoImportPath() GoImportPath + TypeName() []string + File() *FileDescriptor +} + +// Generator is the type whose methods generate the output, stored in the associated response structure. +type Generator struct { + *bytes.Buffer + + Request *plugin.CodeGeneratorRequest // The input. + Response *plugin.CodeGeneratorResponse // The output. + + Param map[string]string // Command-line parameters. + PackageImportPath string // Go import path of the package we're generating code for + ImportPrefix string // String to prefix to imported package file names. + ImportMap map[string]string // Mapping from .proto file name to import path + + Pkg map[string]string // The names under which we import support packages + + outputImportPath GoImportPath // Package we're generating code for. + allFiles []*FileDescriptor // All files in the tree + allFilesByName map[string]*FileDescriptor // All files by filename. + genFiles []*FileDescriptor // Those files we will generate output for. + file *FileDescriptor // The file we are compiling now. + packageNames map[GoImportPath]GoPackageName // Imported package names in the current file. + usedPackages map[GoImportPath]bool // Packages used in current file. + usedPackageNames map[GoPackageName]bool // Package names used in the current file. + addedImports map[GoImportPath]bool // Additional imports to emit. + typeNameToObject map[string]Object // Key is a fully-qualified name in input syntax. + init []string // Lines to emit in the init function. + indent string + pathType pathType // How to generate output filenames. + writeOutput bool + annotateCode bool // whether to store annotations + annotations []*descriptor.GeneratedCodeInfo_Annotation // annotations to store +} + +type pathType int + +const ( + pathTypeImport pathType = iota + pathTypeSourceRelative +) + +// New creates a new generator and allocates the request and response protobufs. +func New() *Generator { + g := new(Generator) + g.Buffer = new(bytes.Buffer) + g.Request = new(plugin.CodeGeneratorRequest) + g.Response = new(plugin.CodeGeneratorResponse) + return g +} + +// Error reports a problem, including an error, and exits the program. +func (g *Generator) Error(err error, msgs ...string) { + s := strings.Join(msgs, " ") + ":" + err.Error() + log.Print("protoc-gen-go: error:", s) + os.Exit(1) +} + +// Fail reports a problem and exits the program. +func (g *Generator) Fail(msgs ...string) { + s := strings.Join(msgs, " ") + log.Print("protoc-gen-go: error:", s) + os.Exit(1) +} + +// CommandLineParameters breaks the comma-separated list of key=value pairs +// in the parameter (a member of the request protobuf) into a key/value map. +// It then sets file name mappings defined by those entries. +func (g *Generator) CommandLineParameters(parameter string) { + g.Param = make(map[string]string) + for _, p := range strings.Split(parameter, ",") { + if i := strings.Index(p, "="); i < 0 { + g.Param[p] = "" + } else { + g.Param[p[0:i]] = p[i+1:] + } + } + + g.ImportMap = make(map[string]string) + pluginList := "none" // Default list of plugin names to enable (empty means all). + for k, v := range g.Param { + switch k { + case "import_prefix": + g.ImportPrefix = v + case "import_path": + g.PackageImportPath = v + case "paths": + switch v { + case "import": + g.pathType = pathTypeImport + case "source_relative": + g.pathType = pathTypeSourceRelative + default: + g.Fail(fmt.Sprintf(`Unknown path type %q: want "import" or "source_relative".`, v)) + } + case "plugins": + pluginList = v + case "annotate_code": + if v == "true" { + g.annotateCode = true + } + default: + if len(k) > 0 && k[0] == 'M' { + g.ImportMap[k[1:]] = v + } + } + } + if pluginList != "" { + // Amend the set of plugins. + enabled := make(map[string]bool) + for _, name := range strings.Split(pluginList, "+") { + enabled[name] = true + } + var nplugins []Plugin + for _, p := range plugins { + if enabled[p.Name()] { + nplugins = append(nplugins, p) + } + } + plugins = nplugins + } +} + +// DefaultPackageName returns the package name printed for the object. +// If its file is in a different package, it returns the package name we're using for this file, plus ".". +// Otherwise it returns the empty string. +func (g *Generator) DefaultPackageName(obj Object) string { + importPath := obj.GoImportPath() + if importPath == g.outputImportPath { + return "" + } + return string(g.GoPackageName(importPath)) + "." +} + +// GoPackageName returns the name used for a package. +func (g *Generator) GoPackageName(importPath GoImportPath) GoPackageName { + if name, ok := g.packageNames[importPath]; ok { + return name + } + name := cleanPackageName(baseName(string(importPath))) + for i, orig := 1, name; g.usedPackageNames[name] || isGoPredeclaredIdentifier[string(name)]; i++ { + name = orig + GoPackageName(strconv.Itoa(i)) + } + g.packageNames[importPath] = name + g.usedPackageNames[name] = true + return name +} + +// AddImport adds a package to the generated file's import section. +// It returns the name used for the package. +func (g *Generator) AddImport(importPath GoImportPath) GoPackageName { + g.addedImports[importPath] = true + return g.GoPackageName(importPath) +} + +var globalPackageNames = map[GoPackageName]bool{ + "fmt": true, + "math": true, + "proto": true, +} + +// Create and remember a guaranteed unique package name. Pkg is the candidate name. +// The FileDescriptor parameter is unused. +func RegisterUniquePackageName(pkg string, f *FileDescriptor) string { + name := cleanPackageName(pkg) + for i, orig := 1, name; globalPackageNames[name]; i++ { + name = orig + GoPackageName(strconv.Itoa(i)) + } + globalPackageNames[name] = true + return string(name) +} + +var isGoKeyword = map[string]bool{ + "break": true, + "case": true, + "chan": true, + "const": true, + "continue": true, + "default": true, + "else": true, + "defer": true, + "fallthrough": true, + "for": true, + "func": true, + "go": true, + "goto": true, + "if": true, + "import": true, + "interface": true, + "map": true, + "package": true, + "range": true, + "return": true, + "select": true, + "struct": true, + "switch": true, + "type": true, + "var": true, +} + +var isGoPredeclaredIdentifier = map[string]bool{ + "append": true, + "bool": true, + "byte": true, + "cap": true, + "close": true, + "complex": true, + "complex128": true, + "complex64": true, + "copy": true, + "delete": true, + "error": true, + "false": true, + "float32": true, + "float64": true, + "imag": true, + "int": true, + "int16": true, + "int32": true, + "int64": true, + "int8": true, + "iota": true, + "len": true, + "make": true, + "new": true, + "nil": true, + "panic": true, + "print": true, + "println": true, + "real": true, + "recover": true, + "rune": true, + "string": true, + "true": true, + "uint": true, + "uint16": true, + "uint32": true, + "uint64": true, + "uint8": true, + "uintptr": true, +} + +func cleanPackageName(name string) GoPackageName { + name = strings.Map(badToUnderscore, name) + // Identifier must not be keyword or predeclared identifier: insert _. + if isGoKeyword[name] { + name = "_" + name + } + // Identifier must not begin with digit: insert _. + if r, _ := utf8.DecodeRuneInString(name); unicode.IsDigit(r) { + name = "_" + name + } + return GoPackageName(name) +} + +// defaultGoPackage returns the package name to use, +// derived from the import path of the package we're building code for. +func (g *Generator) defaultGoPackage() GoPackageName { + p := g.PackageImportPath + if i := strings.LastIndex(p, "/"); i >= 0 { + p = p[i+1:] + } + return cleanPackageName(p) +} + +// SetPackageNames sets the package name for this run. +// The package name must agree across all files being generated. +// It also defines unique package names for all imported files. +func (g *Generator) SetPackageNames() { + g.outputImportPath = g.genFiles[0].importPath + + defaultPackageNames := make(map[GoImportPath]GoPackageName) + for _, f := range g.genFiles { + if _, p, ok := f.goPackageOption(); ok { + defaultPackageNames[f.importPath] = p + } + } + for _, f := range g.genFiles { + if _, p, ok := f.goPackageOption(); ok { + // Source file: option go_package = "quux/bar"; + f.packageName = p + } else if p, ok := defaultPackageNames[f.importPath]; ok { + // A go_package option in another file in the same package. + // + // This is a poor choice in general, since every source file should + // contain a go_package option. Supported mainly for historical + // compatibility. + f.packageName = p + } else if p := g.defaultGoPackage(); p != "" { + // Command-line: import_path=quux/bar. + // + // The import_path flag sets a package name for files which don't + // contain a go_package option. + f.packageName = p + } else if p := f.GetPackage(); p != "" { + // Source file: package quux.bar; + f.packageName = cleanPackageName(p) + } else { + // Source filename. + f.packageName = cleanPackageName(baseName(f.GetName())) + } + } + + // Check that all files have a consistent package name and import path. + for _, f := range g.genFiles[1:] { + if a, b := g.genFiles[0].importPath, f.importPath; a != b { + g.Fail(fmt.Sprintf("inconsistent package import paths: %v, %v", a, b)) + } + if a, b := g.genFiles[0].packageName, f.packageName; a != b { + g.Fail(fmt.Sprintf("inconsistent package names: %v, %v", a, b)) + } + } + + // Names of support packages. These never vary (if there are conflicts, + // we rename the conflicting package), so this could be removed someday. + g.Pkg = map[string]string{ + "fmt": "fmt", + "math": "math", + "proto": "proto", + } +} + +// WrapTypes walks the incoming data, wrapping DescriptorProtos, EnumDescriptorProtos +// and FileDescriptorProtos into file-referenced objects within the Generator. +// It also creates the list of files to generate and so should be called before GenerateAllFiles. +func (g *Generator) WrapTypes() { + g.allFiles = make([]*FileDescriptor, 0, len(g.Request.ProtoFile)) + g.allFilesByName = make(map[string]*FileDescriptor, len(g.allFiles)) + genFileNames := make(map[string]bool) + for _, n := range g.Request.FileToGenerate { + genFileNames[n] = true + } + for _, f := range g.Request.ProtoFile { + fd := &FileDescriptor{ + FileDescriptorProto: f, + exported: make(map[Object][]symbol), + proto3: fileIsProto3(f), + } + // The import path may be set in a number of ways. + if substitution, ok := g.ImportMap[f.GetName()]; ok { + // Command-line: M=foo.proto=quux/bar. + // + // Explicit mapping of source file to import path. + fd.importPath = GoImportPath(substitution) + } else if genFileNames[f.GetName()] && g.PackageImportPath != "" { + // Command-line: import_path=quux/bar. + // + // The import_path flag sets the import path for every file that + // we generate code for. + fd.importPath = GoImportPath(g.PackageImportPath) + } else if p, _, _ := fd.goPackageOption(); p != "" { + // Source file: option go_package = "quux/bar"; + // + // The go_package option sets the import path. Most users should use this. + fd.importPath = p + } else { + // Source filename. + // + // Last resort when nothing else is available. + fd.importPath = GoImportPath(path.Dir(f.GetName())) + } + // We must wrap the descriptors before we wrap the enums + fd.desc = wrapDescriptors(fd) + g.buildNestedDescriptors(fd.desc) + fd.enum = wrapEnumDescriptors(fd, fd.desc) + g.buildNestedEnums(fd.desc, fd.enum) + fd.ext = wrapExtensions(fd) + extractComments(fd) + g.allFiles = append(g.allFiles, fd) + g.allFilesByName[f.GetName()] = fd + } + for _, fd := range g.allFiles { + fd.imp = wrapImported(fd, g) + } + + g.genFiles = make([]*FileDescriptor, 0, len(g.Request.FileToGenerate)) + for _, fileName := range g.Request.FileToGenerate { + fd := g.allFilesByName[fileName] + if fd == nil { + g.Fail("could not find file named", fileName) + } + g.genFiles = append(g.genFiles, fd) + } +} + +// Scan the descriptors in this file. For each one, build the slice of nested descriptors +func (g *Generator) buildNestedDescriptors(descs []*Descriptor) { + for _, desc := range descs { + if len(desc.NestedType) != 0 { + for _, nest := range descs { + if nest.parent == desc { + desc.nested = append(desc.nested, nest) + } + } + if len(desc.nested) != len(desc.NestedType) { + g.Fail("internal error: nesting failure for", desc.GetName()) + } + } + } +} + +func (g *Generator) buildNestedEnums(descs []*Descriptor, enums []*EnumDescriptor) { + for _, desc := range descs { + if len(desc.EnumType) != 0 { + for _, enum := range enums { + if enum.parent == desc { + desc.enums = append(desc.enums, enum) + } + } + if len(desc.enums) != len(desc.EnumType) { + g.Fail("internal error: enum nesting failure for", desc.GetName()) + } + } + } +} + +// Construct the Descriptor +func newDescriptor(desc *descriptor.DescriptorProto, parent *Descriptor, file *FileDescriptor, index int) *Descriptor { + d := &Descriptor{ + common: common{file}, + DescriptorProto: desc, + parent: parent, + index: index, + } + if parent == nil { + d.path = fmt.Sprintf("%d,%d", messagePath, index) + } else { + d.path = fmt.Sprintf("%s,%d,%d", parent.path, messageMessagePath, index) + } + + // The only way to distinguish a group from a message is whether + // the containing message has a TYPE_GROUP field that matches. + if parent != nil { + parts := d.TypeName() + if file.Package != nil { + parts = append([]string{*file.Package}, parts...) + } + exp := "." + strings.Join(parts, ".") + for _, field := range parent.Field { + if field.GetType() == descriptor.FieldDescriptorProto_TYPE_GROUP && field.GetTypeName() == exp { + d.group = true + break + } + } + } + + for _, field := range desc.Extension { + d.ext = append(d.ext, &ExtensionDescriptor{common{file}, field, d}) + } + + return d +} + +// Return a slice of all the Descriptors defined within this file +func wrapDescriptors(file *FileDescriptor) []*Descriptor { + sl := make([]*Descriptor, 0, len(file.MessageType)+10) + for i, desc := range file.MessageType { + sl = wrapThisDescriptor(sl, desc, nil, file, i) + } + return sl +} + +// Wrap this Descriptor, recursively +func wrapThisDescriptor(sl []*Descriptor, desc *descriptor.DescriptorProto, parent *Descriptor, file *FileDescriptor, index int) []*Descriptor { + sl = append(sl, newDescriptor(desc, parent, file, index)) + me := sl[len(sl)-1] + for i, nested := range desc.NestedType { + sl = wrapThisDescriptor(sl, nested, me, file, i) + } + return sl +} + +// Construct the EnumDescriptor +func newEnumDescriptor(desc *descriptor.EnumDescriptorProto, parent *Descriptor, file *FileDescriptor, index int) *EnumDescriptor { + ed := &EnumDescriptor{ + common: common{file}, + EnumDescriptorProto: desc, + parent: parent, + index: index, + } + if parent == nil { + ed.path = fmt.Sprintf("%d,%d", enumPath, index) + } else { + ed.path = fmt.Sprintf("%s,%d,%d", parent.path, messageEnumPath, index) + } + return ed +} + +// Return a slice of all the EnumDescriptors defined within this file +func wrapEnumDescriptors(file *FileDescriptor, descs []*Descriptor) []*EnumDescriptor { + sl := make([]*EnumDescriptor, 0, len(file.EnumType)+10) + // Top-level enums. + for i, enum := range file.EnumType { + sl = append(sl, newEnumDescriptor(enum, nil, file, i)) + } + // Enums within messages. Enums within embedded messages appear in the outer-most message. + for _, nested := range descs { + for i, enum := range nested.EnumType { + sl = append(sl, newEnumDescriptor(enum, nested, file, i)) + } + } + return sl +} + +// Return a slice of all the top-level ExtensionDescriptors defined within this file. +func wrapExtensions(file *FileDescriptor) []*ExtensionDescriptor { + var sl []*ExtensionDescriptor + for _, field := range file.Extension { + sl = append(sl, &ExtensionDescriptor{common{file}, field, nil}) + } + return sl +} + +// Return a slice of all the types that are publicly imported into this file. +func wrapImported(file *FileDescriptor, g *Generator) (sl []*ImportedDescriptor) { + for _, index := range file.PublicDependency { + df := g.fileByName(file.Dependency[index]) + for _, d := range df.desc { + if d.GetOptions().GetMapEntry() { + continue + } + sl = append(sl, &ImportedDescriptor{common{file}, d}) + } + for _, e := range df.enum { + sl = append(sl, &ImportedDescriptor{common{file}, e}) + } + for _, ext := range df.ext { + sl = append(sl, &ImportedDescriptor{common{file}, ext}) + } + } + return +} + +func extractComments(file *FileDescriptor) { + file.comments = make(map[string]*descriptor.SourceCodeInfo_Location) + for _, loc := range file.GetSourceCodeInfo().GetLocation() { + if loc.LeadingComments == nil { + continue + } + var p []string + for _, n := range loc.Path { + p = append(p, strconv.Itoa(int(n))) + } + file.comments[strings.Join(p, ",")] = loc + } +} + +// BuildTypeNameMap builds the map from fully qualified type names to objects. +// The key names for the map come from the input data, which puts a period at the beginning. +// It should be called after SetPackageNames and before GenerateAllFiles. +func (g *Generator) BuildTypeNameMap() { + g.typeNameToObject = make(map[string]Object) + for _, f := range g.allFiles { + // The names in this loop are defined by the proto world, not us, so the + // package name may be empty. If so, the dotted package name of X will + // be ".X"; otherwise it will be ".pkg.X". + dottedPkg := "." + f.GetPackage() + if dottedPkg != "." { + dottedPkg += "." + } + for _, enum := range f.enum { + name := dottedPkg + dottedSlice(enum.TypeName()) + g.typeNameToObject[name] = enum + } + for _, desc := range f.desc { + name := dottedPkg + dottedSlice(desc.TypeName()) + g.typeNameToObject[name] = desc + } + } +} + +// ObjectNamed, given a fully-qualified input type name as it appears in the input data, +// returns the descriptor for the message or enum with that name. +func (g *Generator) ObjectNamed(typeName string) Object { + o, ok := g.typeNameToObject[typeName] + if !ok { + g.Fail("can't find object with type", typeName) + } + return o +} + +// AnnotatedAtoms is a list of atoms (as consumed by P) that records the file name and proto AST path from which they originated. +type AnnotatedAtoms struct { + source string + path string + atoms []interface{} +} + +// Annotate records the file name and proto AST path of a list of atoms +// so that a later call to P can emit a link from each atom to its origin. +func Annotate(file *FileDescriptor, path string, atoms ...interface{}) *AnnotatedAtoms { + return &AnnotatedAtoms{source: *file.Name, path: path, atoms: atoms} +} + +// printAtom prints the (atomic, non-annotation) argument to the generated output. +func (g *Generator) printAtom(v interface{}) { + switch v := v.(type) { + case string: + g.WriteString(v) + case *string: + g.WriteString(*v) + case bool: + fmt.Fprint(g, v) + case *bool: + fmt.Fprint(g, *v) + case int: + fmt.Fprint(g, v) + case *int32: + fmt.Fprint(g, *v) + case *int64: + fmt.Fprint(g, *v) + case float64: + fmt.Fprint(g, v) + case *float64: + fmt.Fprint(g, *v) + case GoPackageName: + g.WriteString(string(v)) + case GoImportPath: + g.WriteString(strconv.Quote(string(v))) + default: + g.Fail(fmt.Sprintf("unknown type in printer: %T", v)) + } +} + +// P prints the arguments to the generated output. It handles strings and int32s, plus +// handling indirections because they may be *string, etc. Any inputs of type AnnotatedAtoms may emit +// annotations in a .meta file in addition to outputting the atoms themselves (if g.annotateCode +// is true). +func (g *Generator) P(str ...interface{}) { + if !g.writeOutput { + return + } + g.WriteString(g.indent) + for _, v := range str { + switch v := v.(type) { + case *AnnotatedAtoms: + begin := int32(g.Len()) + for _, v := range v.atoms { + g.printAtom(v) + } + if g.annotateCode { + end := int32(g.Len()) + var path []int32 + for _, token := range strings.Split(v.path, ",") { + val, err := strconv.ParseInt(token, 10, 32) + if err != nil { + g.Fail("could not parse proto AST path: ", err.Error()) + } + path = append(path, int32(val)) + } + g.annotations = append(g.annotations, &descriptor.GeneratedCodeInfo_Annotation{ + Path: path, + SourceFile: &v.source, + Begin: &begin, + End: &end, + }) + } + default: + g.printAtom(v) + } + } + g.WriteByte('\n') +} + +// addInitf stores the given statement to be printed inside the file's init function. +// The statement is given as a format specifier and arguments. +func (g *Generator) addInitf(stmt string, a ...interface{}) { + g.init = append(g.init, fmt.Sprintf(stmt, a...)) +} + +// In Indents the output one tab stop. +func (g *Generator) In() { g.indent += "\t" } + +// Out unindents the output one tab stop. +func (g *Generator) Out() { + if len(g.indent) > 0 { + g.indent = g.indent[1:] + } +} + +// GenerateAllFiles generates the output for all the files we're outputting. +func (g *Generator) GenerateAllFiles() { + // Initialize the plugins + for _, p := range plugins { + p.Init(g) + } + // Generate the output. The generator runs for every file, even the files + // that we don't generate output for, so that we can collate the full list + // of exported symbols to support public imports. + genFileMap := make(map[*FileDescriptor]bool, len(g.genFiles)) + for _, file := range g.genFiles { + genFileMap[file] = true + } + for _, file := range g.allFiles { + g.Reset() + g.annotations = nil + g.writeOutput = genFileMap[file] + g.generate(file) + if !g.writeOutput { + continue + } + fname := file.goFileName(g.pathType) + g.Response.File = append(g.Response.File, &plugin.CodeGeneratorResponse_File{ + Name: proto.String(fname), + Content: proto.String(g.String()), + }) + if g.annotateCode { + // Store the generated code annotations in text, as the protoc plugin protocol requires that + // strings contain valid UTF-8. + g.Response.File = append(g.Response.File, &plugin.CodeGeneratorResponse_File{ + Name: proto.String(file.goFileName(g.pathType) + ".meta"), + Content: proto.String(proto.CompactTextString(&descriptor.GeneratedCodeInfo{Annotation: g.annotations})), + }) + } + } +} + +// Run all the plugins associated with the file. +func (g *Generator) runPlugins(file *FileDescriptor) { + for _, p := range plugins { + p.Generate(file) + } +} + +// Fill the response protocol buffer with the generated output for all the files we're +// supposed to generate. +func (g *Generator) generate(file *FileDescriptor) { + g.file = file + g.usedPackages = make(map[GoImportPath]bool) + g.packageNames = make(map[GoImportPath]GoPackageName) + g.usedPackageNames = make(map[GoPackageName]bool) + g.addedImports = make(map[GoImportPath]bool) + for name := range globalPackageNames { + g.usedPackageNames[name] = true + } + + g.P("// This is a compile-time assertion to ensure that this generated file") + g.P("// is compatible with the proto package it is being compiled against.") + g.P("// A compilation error at this line likely means your copy of the") + g.P("// proto package needs to be updated.") + g.P("const _ = ", g.Pkg["proto"], ".ProtoPackageIsVersion", generatedCodeVersion, " // please upgrade the proto package") + g.P() + + for _, td := range g.file.imp { + g.generateImported(td) + } + for _, enum := range g.file.enum { + g.generateEnum(enum) + } + for _, desc := range g.file.desc { + // Don't generate virtual messages for maps. + if desc.GetOptions().GetMapEntry() { + continue + } + g.generateMessage(desc) + } + for _, ext := range g.file.ext { + g.generateExtension(ext) + } + g.generateInitFunction() + g.generateFileDescriptor(file) + + // Run the plugins before the imports so we know which imports are necessary. + g.runPlugins(file) + + // Generate header and imports last, though they appear first in the output. + rem := g.Buffer + remAnno := g.annotations + g.Buffer = new(bytes.Buffer) + g.annotations = nil + g.generateHeader() + g.generateImports() + if !g.writeOutput { + return + } + // Adjust the offsets for annotations displaced by the header and imports. + for _, anno := range remAnno { + *anno.Begin += int32(g.Len()) + *anno.End += int32(g.Len()) + g.annotations = append(g.annotations, anno) + } + g.Write(rem.Bytes()) + + // Reformat generated code and patch annotation locations. + fset := token.NewFileSet() + original := g.Bytes() + if g.annotateCode { + // make a copy independent of g; we'll need it after Reset. + original = append([]byte(nil), original...) + } + fileAST, err := parser.ParseFile(fset, "", original, parser.ParseComments) + if err != nil { + // Print out the bad code with line numbers. + // This should never happen in practice, but it can while changing generated code, + // so consider this a debugging aid. + var src bytes.Buffer + s := bufio.NewScanner(bytes.NewReader(original)) + for line := 1; s.Scan(); line++ { + fmt.Fprintf(&src, "%5d\t%s\n", line, s.Bytes()) + } + g.Fail("bad Go source code was generated:", err.Error(), "\n"+src.String()) + } + ast.SortImports(fset, fileAST) + g.Reset() + err = (&printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8}).Fprint(g, fset, fileAST) + if err != nil { + g.Fail("generated Go source code could not be reformatted:", err.Error()) + } + if g.annotateCode { + m, err := remap.Compute(original, g.Bytes()) + if err != nil { + g.Fail("formatted generated Go source code could not be mapped back to the original code:", err.Error()) + } + for _, anno := range g.annotations { + new, ok := m.Find(int(*anno.Begin), int(*anno.End)) + if !ok { + g.Fail("span in formatted generated Go source code could not be mapped back to the original code") + } + *anno.Begin = int32(new.Pos) + *anno.End = int32(new.End) + } + } +} + +// Generate the header, including package definition +func (g *Generator) generateHeader() { + g.P("// Code generated by protoc-gen-go. DO NOT EDIT.") + if g.file.GetOptions().GetDeprecated() { + g.P("// ", g.file.Name, " is a deprecated file.") + } else { + g.P("// source: ", g.file.Name) + } + g.P() + g.PrintComments(strconv.Itoa(packagePath)) + g.P() + g.P("package ", g.file.packageName) + g.P() +} + +// deprecationComment is the standard comment added to deprecated +// messages, fields, enums, and enum values. +var deprecationComment = "// Deprecated: Do not use." + +// PrintComments prints any comments from the source .proto file. +// The path is a comma-separated list of integers. +// It returns an indication of whether any comments were printed. +// See descriptor.proto for its format. +func (g *Generator) PrintComments(path string) bool { + if !g.writeOutput { + return false + } + if c, ok := g.makeComments(path); ok { + g.P(c) + return true + } + return false +} + +// makeComments generates the comment string for the field, no "\n" at the end +func (g *Generator) makeComments(path string) (string, bool) { + loc, ok := g.file.comments[path] + if !ok { + return "", false + } + w := new(bytes.Buffer) + nl := "" + for _, line := range strings.Split(strings.TrimSuffix(loc.GetLeadingComments(), "\n"), "\n") { + fmt.Fprintf(w, "%s//%s", nl, line) + nl = "\n" + } + return w.String(), true +} + +func (g *Generator) fileByName(filename string) *FileDescriptor { + return g.allFilesByName[filename] +} + +// weak returns whether the ith import of the current file is a weak import. +func (g *Generator) weak(i int32) bool { + for _, j := range g.file.WeakDependency { + if j == i { + return true + } + } + return false +} + +// Generate the imports +func (g *Generator) generateImports() { + imports := make(map[GoImportPath]GoPackageName) + for i, s := range g.file.Dependency { + fd := g.fileByName(s) + importPath := fd.importPath + // Do not import our own package. + if importPath == g.file.importPath { + continue + } + // Do not import weak imports. + if g.weak(int32(i)) { + continue + } + // Do not import a package twice. + if _, ok := imports[importPath]; ok { + continue + } + // We need to import all the dependencies, even if we don't reference them, + // because other code and tools depend on having the full transitive closure + // of protocol buffer types in the binary. + packageName := g.GoPackageName(importPath) + if _, ok := g.usedPackages[importPath]; !ok { + packageName = "_" + } + imports[importPath] = packageName + } + for importPath := range g.addedImports { + imports[importPath] = g.GoPackageName(importPath) + } + // We almost always need a proto import. Rather than computing when we + // do, which is tricky when there's a plugin, just import it and + // reference it later. The same argument applies to the fmt and math packages. + g.P("import (") + g.P(g.Pkg["fmt"] + ` "fmt"`) + g.P(g.Pkg["math"] + ` "math"`) + g.P(g.Pkg["proto"]+" ", GoImportPath(g.ImportPrefix)+"github.com/golang/protobuf/proto") + for importPath, packageName := range imports { + g.P(packageName, " ", GoImportPath(g.ImportPrefix)+importPath) + } + g.P(")") + g.P() + // TODO: may need to worry about uniqueness across plugins + for _, p := range plugins { + p.GenerateImports(g.file) + g.P() + } + g.P("// Reference imports to suppress errors if they are not otherwise used.") + g.P("var _ = ", g.Pkg["proto"], ".Marshal") + g.P("var _ = ", g.Pkg["fmt"], ".Errorf") + g.P("var _ = ", g.Pkg["math"], ".Inf") + g.P() +} + +func (g *Generator) generateImported(id *ImportedDescriptor) { + df := id.o.File() + filename := *df.Name + if df.importPath == g.file.importPath { + // Don't generate type aliases for files in the same Go package as this one. + return + } + if !supportTypeAliases { + g.Fail(fmt.Sprintf("%s: public imports require at least go1.9", filename)) + } + g.usedPackages[df.importPath] = true + + for _, sym := range df.exported[id.o] { + sym.GenerateAlias(g, filename, g.GoPackageName(df.importPath)) + } + + g.P() +} + +// Generate the enum definitions for this EnumDescriptor. +func (g *Generator) generateEnum(enum *EnumDescriptor) { + // The full type name + typeName := enum.TypeName() + // The full type name, CamelCased. + ccTypeName := CamelCaseSlice(typeName) + ccPrefix := enum.prefix() + + deprecatedEnum := "" + if enum.GetOptions().GetDeprecated() { + deprecatedEnum = deprecationComment + } + g.PrintComments(enum.path) + g.P("type ", Annotate(enum.file, enum.path, ccTypeName), " int32", deprecatedEnum) + g.file.addExport(enum, enumSymbol{ccTypeName, enum.proto3()}) + g.P("const (") + for i, e := range enum.Value { + etorPath := fmt.Sprintf("%s,%d,%d", enum.path, enumValuePath, i) + g.PrintComments(etorPath) + + deprecatedValue := "" + if e.GetOptions().GetDeprecated() { + deprecatedValue = deprecationComment + } + + name := ccPrefix + *e.Name + g.P(Annotate(enum.file, etorPath, name), " ", ccTypeName, " = ", e.Number, " ", deprecatedValue) + g.file.addExport(enum, constOrVarSymbol{name, "const", ccTypeName}) + } + g.P(")") + g.P() + g.P("var ", ccTypeName, "_name = map[int32]string{") + generated := make(map[int32]bool) // avoid duplicate values + for _, e := range enum.Value { + duplicate := "" + if _, present := generated[*e.Number]; present { + duplicate = "// Duplicate value: " + } + g.P(duplicate, e.Number, ": ", strconv.Quote(*e.Name), ",") + generated[*e.Number] = true + } + g.P("}") + g.P() + g.P("var ", ccTypeName, "_value = map[string]int32{") + for _, e := range enum.Value { + g.P(strconv.Quote(*e.Name), ": ", e.Number, ",") + } + g.P("}") + g.P() + + if !enum.proto3() { + g.P("func (x ", ccTypeName, ") Enum() *", ccTypeName, " {") + g.P("p := new(", ccTypeName, ")") + g.P("*p = x") + g.P("return p") + g.P("}") + g.P() + } + + g.P("func (x ", ccTypeName, ") String() string {") + g.P("return ", g.Pkg["proto"], ".EnumName(", ccTypeName, "_name, int32(x))") + g.P("}") + g.P() + + if !enum.proto3() { + g.P("func (x *", ccTypeName, ") UnmarshalJSON(data []byte) error {") + g.P("value, err := ", g.Pkg["proto"], ".UnmarshalJSONEnum(", ccTypeName, `_value, data, "`, ccTypeName, `")`) + g.P("if err != nil {") + g.P("return err") + g.P("}") + g.P("*x = ", ccTypeName, "(value)") + g.P("return nil") + g.P("}") + g.P() + } + + var indexes []string + for m := enum.parent; m != nil; m = m.parent { + // XXX: skip groups? + indexes = append([]string{strconv.Itoa(m.index)}, indexes...) + } + indexes = append(indexes, strconv.Itoa(enum.index)) + g.P("func (", ccTypeName, ") EnumDescriptor() ([]byte, []int) {") + g.P("return ", g.file.VarName(), ", []int{", strings.Join(indexes, ", "), "}") + g.P("}") + g.P() + if enum.file.GetPackage() == "google.protobuf" && enum.GetName() == "NullValue" { + g.P("func (", ccTypeName, `) XXX_WellKnownType() string { return "`, enum.GetName(), `" }`) + g.P() + } + + g.generateEnumRegistration(enum) +} + +// The tag is a string like "varint,2,opt,name=fieldname,def=7" that +// identifies details of the field for the protocol buffer marshaling and unmarshaling +// code. The fields are: +// wire encoding +// protocol tag number +// opt,req,rep for optional, required, or repeated +// packed whether the encoding is "packed" (optional; repeated primitives only) +// name= the original declared name +// enum= the name of the enum type if it is an enum-typed field. +// proto3 if this field is in a proto3 message +// def= string representation of the default value, if any. +// The default value must be in a representation that can be used at run-time +// to generate the default value. Thus bools become 0 and 1, for instance. +func (g *Generator) goTag(message *Descriptor, field *descriptor.FieldDescriptorProto, wiretype string) string { + optrepreq := "" + switch { + case isOptional(field): + optrepreq = "opt" + case isRequired(field): + optrepreq = "req" + case isRepeated(field): + optrepreq = "rep" + } + var defaultValue string + if dv := field.DefaultValue; dv != nil { // set means an explicit default + defaultValue = *dv + // Some types need tweaking. + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_BOOL: + if defaultValue == "true" { + defaultValue = "1" + } else { + defaultValue = "0" + } + case descriptor.FieldDescriptorProto_TYPE_STRING, + descriptor.FieldDescriptorProto_TYPE_BYTES: + // Nothing to do. Quoting is done for the whole tag. + case descriptor.FieldDescriptorProto_TYPE_ENUM: + // For enums we need to provide the integer constant. + obj := g.ObjectNamed(field.GetTypeName()) + if id, ok := obj.(*ImportedDescriptor); ok { + // It is an enum that was publicly imported. + // We need the underlying type. + obj = id.o + } + enum, ok := obj.(*EnumDescriptor) + if !ok { + log.Printf("obj is a %T", obj) + if id, ok := obj.(*ImportedDescriptor); ok { + log.Printf("id.o is a %T", id.o) + } + g.Fail("unknown enum type", CamelCaseSlice(obj.TypeName())) + } + defaultValue = enum.integerValueAsString(defaultValue) + case descriptor.FieldDescriptorProto_TYPE_FLOAT: + if def := defaultValue; def != "inf" && def != "-inf" && def != "nan" { + if f, err := strconv.ParseFloat(defaultValue, 32); err == nil { + defaultValue = fmt.Sprint(float32(f)) + } + } + case descriptor.FieldDescriptorProto_TYPE_DOUBLE: + if def := defaultValue; def != "inf" && def != "-inf" && def != "nan" { + if f, err := strconv.ParseFloat(defaultValue, 64); err == nil { + defaultValue = fmt.Sprint(f) + } + } + } + defaultValue = ",def=" + defaultValue + } + enum := "" + if *field.Type == descriptor.FieldDescriptorProto_TYPE_ENUM { + // We avoid using obj.GoPackageName(), because we want to use the + // original (proto-world) package name. + obj := g.ObjectNamed(field.GetTypeName()) + if id, ok := obj.(*ImportedDescriptor); ok { + obj = id.o + } + enum = ",enum=" + if pkg := obj.File().GetPackage(); pkg != "" { + enum += pkg + "." + } + enum += CamelCaseSlice(obj.TypeName()) + } + packed := "" + if (field.Options != nil && field.Options.GetPacked()) || + // Per https://developers.google.com/protocol-buffers/docs/proto3#simple: + // "In proto3, repeated fields of scalar numeric types use packed encoding by default." + (message.proto3() && (field.Options == nil || field.Options.Packed == nil) && + isRepeated(field) && isScalar(field)) { + packed = ",packed" + } + fieldName := field.GetName() + name := fieldName + if *field.Type == descriptor.FieldDescriptorProto_TYPE_GROUP { + // We must use the type name for groups instead of + // the field name to preserve capitalization. + // type_name in FieldDescriptorProto is fully-qualified, + // but we only want the local part. + name = *field.TypeName + if i := strings.LastIndex(name, "."); i >= 0 { + name = name[i+1:] + } + } + if json := field.GetJsonName(); field.Extendee == nil && json != "" && json != name { + // TODO: escaping might be needed, in which case + // perhaps this should be in its own "json" tag. + name += ",json=" + json + } + name = ",name=" + name + if message.proto3() { + name += ",proto3" + } + oneof := "" + if field.OneofIndex != nil { + oneof = ",oneof" + } + return strconv.Quote(fmt.Sprintf("%s,%d,%s%s%s%s%s%s", + wiretype, + field.GetNumber(), + optrepreq, + packed, + name, + enum, + oneof, + defaultValue)) +} + +func needsStar(typ descriptor.FieldDescriptorProto_Type) bool { + switch typ { + case descriptor.FieldDescriptorProto_TYPE_GROUP: + return false + case descriptor.FieldDescriptorProto_TYPE_MESSAGE: + return false + case descriptor.FieldDescriptorProto_TYPE_BYTES: + return false + } + return true +} + +// TypeName is the printed name appropriate for an item. If the object is in the current file, +// TypeName drops the package name and underscores the rest. +// Otherwise the object is from another package; and the result is the underscored +// package name followed by the item name. +// The result always has an initial capital. +func (g *Generator) TypeName(obj Object) string { + return g.DefaultPackageName(obj) + CamelCaseSlice(obj.TypeName()) +} + +// GoType returns a string representing the type name, and the wire type +func (g *Generator) GoType(message *Descriptor, field *descriptor.FieldDescriptorProto) (typ string, wire string) { + // TODO: Options. + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_DOUBLE: + typ, wire = "float64", "fixed64" + case descriptor.FieldDescriptorProto_TYPE_FLOAT: + typ, wire = "float32", "fixed32" + case descriptor.FieldDescriptorProto_TYPE_INT64: + typ, wire = "int64", "varint" + case descriptor.FieldDescriptorProto_TYPE_UINT64: + typ, wire = "uint64", "varint" + case descriptor.FieldDescriptorProto_TYPE_INT32: + typ, wire = "int32", "varint" + case descriptor.FieldDescriptorProto_TYPE_UINT32: + typ, wire = "uint32", "varint" + case descriptor.FieldDescriptorProto_TYPE_FIXED64: + typ, wire = "uint64", "fixed64" + case descriptor.FieldDescriptorProto_TYPE_FIXED32: + typ, wire = "uint32", "fixed32" + case descriptor.FieldDescriptorProto_TYPE_BOOL: + typ, wire = "bool", "varint" + case descriptor.FieldDescriptorProto_TYPE_STRING: + typ, wire = "string", "bytes" + case descriptor.FieldDescriptorProto_TYPE_GROUP: + desc := g.ObjectNamed(field.GetTypeName()) + typ, wire = "*"+g.TypeName(desc), "group" + case descriptor.FieldDescriptorProto_TYPE_MESSAGE: + desc := g.ObjectNamed(field.GetTypeName()) + typ, wire = "*"+g.TypeName(desc), "bytes" + case descriptor.FieldDescriptorProto_TYPE_BYTES: + typ, wire = "[]byte", "bytes" + case descriptor.FieldDescriptorProto_TYPE_ENUM: + desc := g.ObjectNamed(field.GetTypeName()) + typ, wire = g.TypeName(desc), "varint" + case descriptor.FieldDescriptorProto_TYPE_SFIXED32: + typ, wire = "int32", "fixed32" + case descriptor.FieldDescriptorProto_TYPE_SFIXED64: + typ, wire = "int64", "fixed64" + case descriptor.FieldDescriptorProto_TYPE_SINT32: + typ, wire = "int32", "zigzag32" + case descriptor.FieldDescriptorProto_TYPE_SINT64: + typ, wire = "int64", "zigzag64" + default: + g.Fail("unknown type for", field.GetName()) + } + if isRepeated(field) { + typ = "[]" + typ + } else if message != nil && message.proto3() { + return + } else if field.OneofIndex != nil && message != nil { + return + } else if needsStar(*field.Type) { + typ = "*" + typ + } + return +} + +func (g *Generator) RecordTypeUse(t string) { + if _, ok := g.typeNameToObject[t]; !ok { + return + } + importPath := g.ObjectNamed(t).GoImportPath() + if importPath == g.outputImportPath { + // Don't record use of objects in our package. + return + } + g.AddImport(importPath) + g.usedPackages[importPath] = true +} + +// Method names that may be generated. Fields with these names get an +// underscore appended. Any change to this set is a potential incompatible +// API change because it changes generated field names. +var methodNames = [...]string{ + "Reset", + "String", + "ProtoMessage", + "Marshal", + "Unmarshal", + "ExtensionRangeArray", + "ExtensionMap", + "Descriptor", +} + +// Names of messages in the `google.protobuf` package for which +// we will generate XXX_WellKnownType methods. +var wellKnownTypes = map[string]bool{ + "Any": true, + "Duration": true, + "Empty": true, + "Struct": true, + "Timestamp": true, + + "Value": true, + "ListValue": true, + "DoubleValue": true, + "FloatValue": true, + "Int64Value": true, + "UInt64Value": true, + "Int32Value": true, + "UInt32Value": true, + "BoolValue": true, + "StringValue": true, + "BytesValue": true, +} + +// getterDefault finds the default value for the field to return from a getter, +// regardless of if it's a built in default or explicit from the source. Returns e.g. "nil", `""`, "Default_MessageType_FieldName" +func (g *Generator) getterDefault(field *descriptor.FieldDescriptorProto, goMessageType string) string { + if isRepeated(field) { + return "nil" + } + if def := field.GetDefaultValue(); def != "" { + defaultConstant := g.defaultConstantName(goMessageType, field.GetName()) + if *field.Type != descriptor.FieldDescriptorProto_TYPE_BYTES { + return defaultConstant + } + return "append([]byte(nil), " + defaultConstant + "...)" + } + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_BOOL: + return "false" + case descriptor.FieldDescriptorProto_TYPE_STRING: + return `""` + case descriptor.FieldDescriptorProto_TYPE_GROUP, descriptor.FieldDescriptorProto_TYPE_MESSAGE, descriptor.FieldDescriptorProto_TYPE_BYTES: + return "nil" + case descriptor.FieldDescriptorProto_TYPE_ENUM: + obj := g.ObjectNamed(field.GetTypeName()) + var enum *EnumDescriptor + if id, ok := obj.(*ImportedDescriptor); ok { + // The enum type has been publicly imported. + enum, _ = id.o.(*EnumDescriptor) + } else { + enum, _ = obj.(*EnumDescriptor) + } + if enum == nil { + log.Printf("don't know how to generate getter for %s", field.GetName()) + return "nil" + } + if len(enum.Value) == 0 { + return "0 // empty enum" + } + first := enum.Value[0].GetName() + return g.DefaultPackageName(obj) + enum.prefix() + first + default: + return "0" + } +} + +// defaultConstantName builds the name of the default constant from the message +// type name and the untouched field name, e.g. "Default_MessageType_FieldName" +func (g *Generator) defaultConstantName(goMessageType, protoFieldName string) string { + return "Default_" + goMessageType + "_" + CamelCase(protoFieldName) +} + +// The different types of fields in a message and how to actually print them +// Most of the logic for generateMessage is in the methods of these types. +// +// Note that the content of the field is irrelevant, a simpleField can contain +// anything from a scalar to a group (which is just a message). +// +// Extension fields (and message sets) are however handled separately. +// +// simpleField - a field that is neiter weak nor oneof, possibly repeated +// oneofField - field containing list of subfields: +// - oneofSubField - a field within the oneof + +// msgCtx contains the context for the generator functions. +type msgCtx struct { + goName string // Go struct name of the message, e.g. MessageName + message *Descriptor // The descriptor for the message +} + +// fieldCommon contains data common to all types of fields. +type fieldCommon struct { + goName string // Go name of field, e.g. "FieldName" or "Descriptor_" + protoName string // Name of field in proto language, e.g. "field_name" or "descriptor" + getterName string // Name of the getter, e.g. "GetFieldName" or "GetDescriptor_" + goType string // The Go type as a string, e.g. "*int32" or "*OtherMessage" + tags string // The tag string/annotation for the type, e.g. `protobuf:"varint,8,opt,name=region_id,json=regionId"` + fullPath string // The full path of the field as used by Annotate etc, e.g. "4,0,2,0" +} + +// getProtoName gets the proto name of a field, e.g. "field_name" or "descriptor". +func (f *fieldCommon) getProtoName() string { + return f.protoName +} + +// getGoType returns the go type of the field as a string, e.g. "*int32". +func (f *fieldCommon) getGoType() string { + return f.goType +} + +// simpleField is not weak, not a oneof, not an extension. Can be required, optional or repeated. +type simpleField struct { + fieldCommon + protoTypeName string // Proto type name, empty if primitive, e.g. ".google.protobuf.Duration" + protoType descriptor.FieldDescriptorProto_Type // Actual type enum value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64 + deprecated string // Deprecation comment, if any, e.g. "// Deprecated: Do not use." + getterDef string // Default for getters, e.g. "nil", `""` or "Default_MessageType_FieldName" + protoDef string // Default value as defined in the proto file, e.g "yoshi" or "5" + comment string // The full comment for the field, e.g. "// Useful information" +} + +// decl prints the declaration of the field in the struct (if any). +func (f *simpleField) decl(g *Generator, mc *msgCtx) { + g.P(f.comment, Annotate(mc.message.file, f.fullPath, f.goName), "\t", f.goType, "\t`", f.tags, "`", f.deprecated) +} + +// getter prints the getter for the field. +func (f *simpleField) getter(g *Generator, mc *msgCtx) { + star := "" + tname := f.goType + if needsStar(f.protoType) && tname[0] == '*' { + tname = tname[1:] + star = "*" + } + if f.deprecated != "" { + g.P(f.deprecated) + } + g.P("func (m *", mc.goName, ") ", Annotate(mc.message.file, f.fullPath, f.getterName), "() "+tname+" {") + if f.getterDef == "nil" { // Simpler getter + g.P("if m != nil {") + g.P("return m." + f.goName) + g.P("}") + g.P("return nil") + g.P("}") + g.P() + return + } + if mc.message.proto3() { + g.P("if m != nil {") + } else { + g.P("if m != nil && m." + f.goName + " != nil {") + } + g.P("return " + star + "m." + f.goName) + g.P("}") + g.P("return ", f.getterDef) + g.P("}") + g.P() +} + +// setter prints the setter method of the field. +func (f *simpleField) setter(g *Generator, mc *msgCtx) { + // No setter for regular fields yet +} + +// getProtoDef returns the default value explicitly stated in the proto file, e.g "yoshi" or "5". +func (f *simpleField) getProtoDef() string { + return f.protoDef +} + +// getProtoTypeName returns the protobuf type name for the field as returned by field.GetTypeName(), e.g. ".google.protobuf.Duration". +func (f *simpleField) getProtoTypeName() string { + return f.protoTypeName +} + +// getProtoType returns the *field.Type value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64. +func (f *simpleField) getProtoType() descriptor.FieldDescriptorProto_Type { + return f.protoType +} + +// oneofSubFields are kept slize held by each oneofField. They do not appear in the top level slize of fields for the message. +type oneofSubField struct { + fieldCommon + protoTypeName string // Proto type name, empty if primitive, e.g. ".google.protobuf.Duration" + protoType descriptor.FieldDescriptorProto_Type // Actual type enum value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64 + oneofTypeName string // Type name of the enclosing struct, e.g. "MessageName_FieldName" + fieldNumber int // Actual field number, as defined in proto, e.g. 12 + getterDef string // Default for getters, e.g. "nil", `""` or "Default_MessageType_FieldName" + protoDef string // Default value as defined in the proto file, e.g "yoshi" or "5" + deprecated string // Deprecation comment, if any. +} + +// typedNil prints a nil casted to the pointer to this field. +// - for XXX_OneofWrappers +func (f *oneofSubField) typedNil(g *Generator) { + g.P("(*", f.oneofTypeName, ")(nil),") +} + +// getProtoDef returns the default value explicitly stated in the proto file, e.g "yoshi" or "5". +func (f *oneofSubField) getProtoDef() string { + return f.protoDef +} + +// getProtoTypeName returns the protobuf type name for the field as returned by field.GetTypeName(), e.g. ".google.protobuf.Duration". +func (f *oneofSubField) getProtoTypeName() string { + return f.protoTypeName +} + +// getProtoType returns the *field.Type value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64. +func (f *oneofSubField) getProtoType() descriptor.FieldDescriptorProto_Type { + return f.protoType +} + +// oneofField represents the oneof on top level. +// The alternative fields within the oneof are represented by oneofSubField. +type oneofField struct { + fieldCommon + subFields []*oneofSubField // All the possible oneof fields + comment string // The full comment for the field, e.g. "// Types that are valid to be assigned to MyOneof:\n\\" +} + +// decl prints the declaration of the field in the struct (if any). +func (f *oneofField) decl(g *Generator, mc *msgCtx) { + comment := f.comment + for _, sf := range f.subFields { + comment += "//\t*" + sf.oneofTypeName + "\n" + } + g.P(comment, Annotate(mc.message.file, f.fullPath, f.goName), " ", f.goType, " `", f.tags, "`") +} + +// getter for a oneof field will print additional discriminators and interfaces for the oneof, +// also it prints all the getters for the sub fields. +func (f *oneofField) getter(g *Generator, mc *msgCtx) { + // The discriminator type + g.P("type ", f.goType, " interface {") + g.P(f.goType, "()") + g.P("}") + g.P() + // The subField types, fulfilling the discriminator type contract + for _, sf := range f.subFields { + g.P("type ", Annotate(mc.message.file, sf.fullPath, sf.oneofTypeName), " struct {") + g.P(Annotate(mc.message.file, sf.fullPath, sf.goName), " ", sf.goType, " `", sf.tags, "`") + g.P("}") + g.P() + } + for _, sf := range f.subFields { + g.P("func (*", sf.oneofTypeName, ") ", f.goType, "() {}") + g.P() + } + // Getter for the oneof field + g.P("func (m *", mc.goName, ") ", Annotate(mc.message.file, f.fullPath, f.getterName), "() ", f.goType, " {") + g.P("if m != nil { return m.", f.goName, " }") + g.P("return nil") + g.P("}") + g.P() + // Getters for each oneof + for _, sf := range f.subFields { + if sf.deprecated != "" { + g.P(sf.deprecated) + } + g.P("func (m *", mc.goName, ") ", Annotate(mc.message.file, sf.fullPath, sf.getterName), "() "+sf.goType+" {") + g.P("if x, ok := m.", f.getterName, "().(*", sf.oneofTypeName, "); ok {") + g.P("return x.", sf.goName) + g.P("}") + g.P("return ", sf.getterDef) + g.P("}") + g.P() + } +} + +// setter prints the setter method of the field. +func (f *oneofField) setter(g *Generator, mc *msgCtx) { + // No setters for oneof yet +} + +// topLevelField interface implemented by all types of fields on the top level (not oneofSubField). +type topLevelField interface { + decl(g *Generator, mc *msgCtx) // print declaration within the struct + getter(g *Generator, mc *msgCtx) // print getter + setter(g *Generator, mc *msgCtx) // print setter if applicable +} + +// defField interface implemented by all types of fields that can have defaults (not oneofField, but instead oneofSubField). +type defField interface { + getProtoDef() string // default value explicitly stated in the proto file, e.g "yoshi" or "5" + getProtoName() string // proto name of a field, e.g. "field_name" or "descriptor" + getGoType() string // go type of the field as a string, e.g. "*int32" + getProtoTypeName() string // protobuf type name for the field, e.g. ".google.protobuf.Duration" + getProtoType() descriptor.FieldDescriptorProto_Type // *field.Type value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64 +} + +// generateDefaultConstants adds constants for default values if needed, which is only if the default value is. +// explicit in the proto. +func (g *Generator) generateDefaultConstants(mc *msgCtx, topLevelFields []topLevelField) { + // Collect fields that can have defaults + dFields := []defField{} + for _, pf := range topLevelFields { + if f, ok := pf.(*oneofField); ok { + for _, osf := range f.subFields { + dFields = append(dFields, osf) + } + continue + } + dFields = append(dFields, pf.(defField)) + } + for _, df := range dFields { + def := df.getProtoDef() + if def == "" { + continue + } + fieldname := g.defaultConstantName(mc.goName, df.getProtoName()) + typename := df.getGoType() + if typename[0] == '*' { + typename = typename[1:] + } + kind := "const " + switch { + case typename == "bool": + case typename == "string": + def = strconv.Quote(def) + case typename == "[]byte": + def = "[]byte(" + strconv.Quote(unescape(def)) + ")" + kind = "var " + case def == "inf", def == "-inf", def == "nan": + // These names are known to, and defined by, the protocol language. + switch def { + case "inf": + def = "math.Inf(1)" + case "-inf": + def = "math.Inf(-1)" + case "nan": + def = "math.NaN()" + } + if df.getProtoType() == descriptor.FieldDescriptorProto_TYPE_FLOAT { + def = "float32(" + def + ")" + } + kind = "var " + case df.getProtoType() == descriptor.FieldDescriptorProto_TYPE_FLOAT: + if f, err := strconv.ParseFloat(def, 32); err == nil { + def = fmt.Sprint(float32(f)) + } + case df.getProtoType() == descriptor.FieldDescriptorProto_TYPE_DOUBLE: + if f, err := strconv.ParseFloat(def, 64); err == nil { + def = fmt.Sprint(f) + } + case df.getProtoType() == descriptor.FieldDescriptorProto_TYPE_ENUM: + // Must be an enum. Need to construct the prefixed name. + obj := g.ObjectNamed(df.getProtoTypeName()) + var enum *EnumDescriptor + if id, ok := obj.(*ImportedDescriptor); ok { + // The enum type has been publicly imported. + enum, _ = id.o.(*EnumDescriptor) + } else { + enum, _ = obj.(*EnumDescriptor) + } + if enum == nil { + log.Printf("don't know how to generate constant for %s", fieldname) + continue + } + def = g.DefaultPackageName(obj) + enum.prefix() + def + } + g.P(kind, fieldname, " ", typename, " = ", def) + g.file.addExport(mc.message, constOrVarSymbol{fieldname, kind, ""}) + } + g.P() +} + +// generateInternalStructFields just adds the XXX_ fields to the message struct. +func (g *Generator) generateInternalStructFields(mc *msgCtx, topLevelFields []topLevelField) { + g.P("XXX_NoUnkeyedLiteral\tstruct{} `json:\"-\"`") // prevent unkeyed struct literals + if len(mc.message.ExtensionRange) > 0 { + messageset := "" + if opts := mc.message.Options; opts != nil && opts.GetMessageSetWireFormat() { + messageset = "protobuf_messageset:\"1\" " + } + g.P(g.Pkg["proto"], ".XXX_InternalExtensions `", messageset, "json:\"-\"`") + } + g.P("XXX_unrecognized\t[]byte `json:\"-\"`") + g.P("XXX_sizecache\tint32 `json:\"-\"`") + +} + +// generateOneofFuncs adds all the utility functions for oneof, including marshalling, unmarshalling and sizer. +func (g *Generator) generateOneofFuncs(mc *msgCtx, topLevelFields []topLevelField) { + ofields := []*oneofField{} + for _, f := range topLevelFields { + if o, ok := f.(*oneofField); ok { + ofields = append(ofields, o) + } + } + if len(ofields) == 0 { + return + } + + // OneofFuncs + g.P("// XXX_OneofWrappers is for the internal use of the proto package.") + g.P("func (*", mc.goName, ") XXX_OneofWrappers() []interface{} {") + g.P("return []interface{}{") + for _, of := range ofields { + for _, sf := range of.subFields { + sf.typedNil(g) + } + } + g.P("}") + g.P("}") + g.P() +} + +// generateMessageStruct adds the actual struct with it's members (but not methods) to the output. +func (g *Generator) generateMessageStruct(mc *msgCtx, topLevelFields []topLevelField) { + comments := g.PrintComments(mc.message.path) + + // Guarantee deprecation comments appear after user-provided comments. + if mc.message.GetOptions().GetDeprecated() { + if comments { + // Convention: Separate deprecation comments from original + // comments with an empty line. + g.P("//") + } + g.P(deprecationComment) + } + + g.P("type ", Annotate(mc.message.file, mc.message.path, mc.goName), " struct {") + for _, pf := range topLevelFields { + pf.decl(g, mc) + } + g.generateInternalStructFields(mc, topLevelFields) + g.P("}") +} + +// generateGetters adds getters for all fields, including oneofs and weak fields when applicable. +func (g *Generator) generateGetters(mc *msgCtx, topLevelFields []topLevelField) { + for _, pf := range topLevelFields { + pf.getter(g, mc) + } +} + +// generateSetters add setters for all fields, including oneofs and weak fields when applicable. +func (g *Generator) generateSetters(mc *msgCtx, topLevelFields []topLevelField) { + for _, pf := range topLevelFields { + pf.setter(g, mc) + } +} + +// generateCommonMethods adds methods to the message that are not on a per field basis. +func (g *Generator) generateCommonMethods(mc *msgCtx) { + // Reset, String and ProtoMessage methods. + g.P("func (m *", mc.goName, ") Reset() { *m = ", mc.goName, "{} }") + g.P("func (m *", mc.goName, ") String() string { return ", g.Pkg["proto"], ".CompactTextString(m) }") + g.P("func (*", mc.goName, ") ProtoMessage() {}") + var indexes []string + for m := mc.message; m != nil; m = m.parent { + indexes = append([]string{strconv.Itoa(m.index)}, indexes...) + } + g.P("func (*", mc.goName, ") Descriptor() ([]byte, []int) {") + g.P("return ", g.file.VarName(), ", []int{", strings.Join(indexes, ", "), "}") + g.P("}") + g.P() + // TODO: Revisit the decision to use a XXX_WellKnownType method + // if we change proto.MessageName to work with multiple equivalents. + if mc.message.file.GetPackage() == "google.protobuf" && wellKnownTypes[mc.message.GetName()] { + g.P("func (*", mc.goName, `) XXX_WellKnownType() string { return "`, mc.message.GetName(), `" }`) + g.P() + } + + // Extension support methods + if len(mc.message.ExtensionRange) > 0 { + g.P() + g.P("var extRange_", mc.goName, " = []", g.Pkg["proto"], ".ExtensionRange{") + for _, r := range mc.message.ExtensionRange { + end := fmt.Sprint(*r.End - 1) // make range inclusive on both ends + g.P("{Start: ", r.Start, ", End: ", end, "},") + } + g.P("}") + g.P("func (*", mc.goName, ") ExtensionRangeArray() []", g.Pkg["proto"], ".ExtensionRange {") + g.P("return extRange_", mc.goName) + g.P("}") + g.P() + } + + // TODO: It does not scale to keep adding another method for every + // operation on protos that we want to switch over to using the + // table-driven approach. Instead, we should only add a single method + // that allows getting access to the *InternalMessageInfo struct and then + // calling Unmarshal, Marshal, Merge, Size, and Discard directly on that. + + // Wrapper for table-driven marshaling and unmarshaling. + g.P("func (m *", mc.goName, ") XXX_Unmarshal(b []byte) error {") + g.P("return xxx_messageInfo_", mc.goName, ".Unmarshal(m, b)") + g.P("}") + + g.P("func (m *", mc.goName, ") XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {") + g.P("return xxx_messageInfo_", mc.goName, ".Marshal(b, m, deterministic)") + g.P("}") + + g.P("func (m *", mc.goName, ") XXX_Merge(src ", g.Pkg["proto"], ".Message) {") + g.P("xxx_messageInfo_", mc.goName, ".Merge(m, src)") + g.P("}") + + g.P("func (m *", mc.goName, ") XXX_Size() int {") // avoid name clash with "Size" field in some message + g.P("return xxx_messageInfo_", mc.goName, ".Size(m)") + g.P("}") + + g.P("func (m *", mc.goName, ") XXX_DiscardUnknown() {") + g.P("xxx_messageInfo_", mc.goName, ".DiscardUnknown(m)") + g.P("}") + + g.P("var xxx_messageInfo_", mc.goName, " ", g.Pkg["proto"], ".InternalMessageInfo") + g.P() +} + +// Generate the type, methods and default constant definitions for this Descriptor. +func (g *Generator) generateMessage(message *Descriptor) { + topLevelFields := []topLevelField{} + oFields := make(map[int32]*oneofField) + // The full type name + typeName := message.TypeName() + // The full type name, CamelCased. + goTypeName := CamelCaseSlice(typeName) + + usedNames := make(map[string]bool) + for _, n := range methodNames { + usedNames[n] = true + } + + // allocNames finds a conflict-free variation of the given strings, + // consistently mutating their suffixes. + // It returns the same number of strings. + allocNames := func(ns ...string) []string { + Loop: + for { + for _, n := range ns { + if usedNames[n] { + for i := range ns { + ns[i] += "_" + } + continue Loop + } + } + for _, n := range ns { + usedNames[n] = true + } + return ns + } + } + + mapFieldTypes := make(map[*descriptor.FieldDescriptorProto]string) // keep track of the map fields to be added later + + // Build a structure more suitable for generating the text in one pass + for i, field := range message.Field { + // Allocate the getter and the field at the same time so name + // collisions create field/method consistent names. + // TODO: This allocation occurs based on the order of the fields + // in the proto file, meaning that a change in the field + // ordering can change generated Method/Field names. + base := CamelCase(*field.Name) + ns := allocNames(base, "Get"+base) + fieldName, fieldGetterName := ns[0], ns[1] + typename, wiretype := g.GoType(message, field) + jsonName := *field.Name + tag := fmt.Sprintf("protobuf:%s json:%q", g.goTag(message, field, wiretype), jsonName+",omitempty") + + oneof := field.OneofIndex != nil + if oneof && oFields[*field.OneofIndex] == nil { + odp := message.OneofDecl[int(*field.OneofIndex)] + base := CamelCase(odp.GetName()) + names := allocNames(base, "Get"+base) + fname, gname := names[0], names[1] + + // This is the first field of a oneof we haven't seen before. + // Generate the union field. + oneofFullPath := fmt.Sprintf("%s,%d,%d", message.path, messageOneofPath, *field.OneofIndex) + c, ok := g.makeComments(oneofFullPath) + if ok { + c += "\n//\n" + } + c += "// Types that are valid to be assigned to " + fname + ":\n" + // Generate the rest of this comment later, + // when we've computed any disambiguation. + + dname := "is" + goTypeName + "_" + fname + tag := `protobuf_oneof:"` + odp.GetName() + `"` + of := oneofField{ + fieldCommon: fieldCommon{ + goName: fname, + getterName: gname, + goType: dname, + tags: tag, + protoName: odp.GetName(), + fullPath: oneofFullPath, + }, + comment: c, + } + topLevelFields = append(topLevelFields, &of) + oFields[*field.OneofIndex] = &of + } + + if *field.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE { + desc := g.ObjectNamed(field.GetTypeName()) + if d, ok := desc.(*Descriptor); ok && d.GetOptions().GetMapEntry() { + // Figure out the Go types and tags for the key and value types. + keyField, valField := d.Field[0], d.Field[1] + keyType, keyWire := g.GoType(d, keyField) + valType, valWire := g.GoType(d, valField) + keyTag, valTag := g.goTag(d, keyField, keyWire), g.goTag(d, valField, valWire) + + // We don't use stars, except for message-typed values. + // Message and enum types are the only two possibly foreign types used in maps, + // so record their use. They are not permitted as map keys. + keyType = strings.TrimPrefix(keyType, "*") + switch *valField.Type { + case descriptor.FieldDescriptorProto_TYPE_ENUM: + valType = strings.TrimPrefix(valType, "*") + g.RecordTypeUse(valField.GetTypeName()) + case descriptor.FieldDescriptorProto_TYPE_MESSAGE: + g.RecordTypeUse(valField.GetTypeName()) + default: + valType = strings.TrimPrefix(valType, "*") + } + + typename = fmt.Sprintf("map[%s]%s", keyType, valType) + mapFieldTypes[field] = typename // record for the getter generation + + tag += fmt.Sprintf(" protobuf_key:%s protobuf_val:%s", keyTag, valTag) + } + } + + fieldDeprecated := "" + if field.GetOptions().GetDeprecated() { + fieldDeprecated = deprecationComment + } + + dvalue := g.getterDefault(field, goTypeName) + if oneof { + tname := goTypeName + "_" + fieldName + // It is possible for this to collide with a message or enum + // nested in this message. Check for collisions. + for { + ok := true + for _, desc := range message.nested { + if CamelCaseSlice(desc.TypeName()) == tname { + ok = false + break + } + } + for _, enum := range message.enums { + if CamelCaseSlice(enum.TypeName()) == tname { + ok = false + break + } + } + if !ok { + tname += "_" + continue + } + break + } + + oneofField := oFields[*field.OneofIndex] + tag := "protobuf:" + g.goTag(message, field, wiretype) + sf := oneofSubField{ + fieldCommon: fieldCommon{ + goName: fieldName, + getterName: fieldGetterName, + goType: typename, + tags: tag, + protoName: field.GetName(), + fullPath: fmt.Sprintf("%s,%d,%d", message.path, messageFieldPath, i), + }, + protoTypeName: field.GetTypeName(), + fieldNumber: int(*field.Number), + protoType: *field.Type, + getterDef: dvalue, + protoDef: field.GetDefaultValue(), + oneofTypeName: tname, + deprecated: fieldDeprecated, + } + oneofField.subFields = append(oneofField.subFields, &sf) + g.RecordTypeUse(field.GetTypeName()) + continue + } + + fieldFullPath := fmt.Sprintf("%s,%d,%d", message.path, messageFieldPath, i) + c, ok := g.makeComments(fieldFullPath) + if ok { + c += "\n" + } + rf := simpleField{ + fieldCommon: fieldCommon{ + goName: fieldName, + getterName: fieldGetterName, + goType: typename, + tags: tag, + protoName: field.GetName(), + fullPath: fieldFullPath, + }, + protoTypeName: field.GetTypeName(), + protoType: *field.Type, + deprecated: fieldDeprecated, + getterDef: dvalue, + protoDef: field.GetDefaultValue(), + comment: c, + } + var pf topLevelField = &rf + + topLevelFields = append(topLevelFields, pf) + g.RecordTypeUse(field.GetTypeName()) + } + + mc := &msgCtx{ + goName: goTypeName, + message: message, + } + + g.generateMessageStruct(mc, topLevelFields) + g.P() + g.generateCommonMethods(mc) + g.P() + g.generateDefaultConstants(mc, topLevelFields) + g.P() + g.generateGetters(mc, topLevelFields) + g.P() + g.generateSetters(mc, topLevelFields) + g.P() + g.generateOneofFuncs(mc, topLevelFields) + g.P() + + var oneofTypes []string + for _, f := range topLevelFields { + if of, ok := f.(*oneofField); ok { + for _, osf := range of.subFields { + oneofTypes = append(oneofTypes, osf.oneofTypeName) + } + } + } + + opts := message.Options + ms := &messageSymbol{ + sym: goTypeName, + hasExtensions: len(message.ExtensionRange) > 0, + isMessageSet: opts != nil && opts.GetMessageSetWireFormat(), + oneofTypes: oneofTypes, + } + g.file.addExport(message, ms) + + for _, ext := range message.ext { + g.generateExtension(ext) + } + + fullName := strings.Join(message.TypeName(), ".") + if g.file.Package != nil { + fullName = *g.file.Package + "." + fullName + } + + g.addInitf("%s.RegisterType((*%s)(nil), %q)", g.Pkg["proto"], goTypeName, fullName) + // Register types for native map types. + for _, k := range mapFieldKeys(mapFieldTypes) { + fullName := strings.TrimPrefix(*k.TypeName, ".") + g.addInitf("%s.RegisterMapType((%s)(nil), %q)", g.Pkg["proto"], mapFieldTypes[k], fullName) + } + +} + +type byTypeName []*descriptor.FieldDescriptorProto + +func (a byTypeName) Len() int { return len(a) } +func (a byTypeName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byTypeName) Less(i, j int) bool { return *a[i].TypeName < *a[j].TypeName } + +// mapFieldKeys returns the keys of m in a consistent order. +func mapFieldKeys(m map[*descriptor.FieldDescriptorProto]string) []*descriptor.FieldDescriptorProto { + keys := make([]*descriptor.FieldDescriptorProto, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + sort.Sort(byTypeName(keys)) + return keys +} + +var escapeChars = [256]byte{ + 'a': '\a', 'b': '\b', 'f': '\f', 'n': '\n', 'r': '\r', 't': '\t', 'v': '\v', '\\': '\\', '"': '"', '\'': '\'', '?': '?', +} + +// unescape reverses the "C" escaping that protoc does for default values of bytes fields. +// It is best effort in that it effectively ignores malformed input. Seemingly invalid escape +// sequences are conveyed, unmodified, into the decoded result. +func unescape(s string) string { + // NB: Sadly, we can't use strconv.Unquote because protoc will escape both + // single and double quotes, but strconv.Unquote only allows one or the + // other (based on actual surrounding quotes of its input argument). + + var out []byte + for len(s) > 0 { + // regular character, or too short to be valid escape + if s[0] != '\\' || len(s) < 2 { + out = append(out, s[0]) + s = s[1:] + } else if c := escapeChars[s[1]]; c != 0 { + // escape sequence + out = append(out, c) + s = s[2:] + } else if s[1] == 'x' || s[1] == 'X' { + // hex escape, e.g. "\x80 + if len(s) < 4 { + // too short to be valid + out = append(out, s[:2]...) + s = s[2:] + continue + } + v, err := strconv.ParseUint(s[2:4], 16, 8) + if err != nil { + out = append(out, s[:4]...) + } else { + out = append(out, byte(v)) + } + s = s[4:] + } else if '0' <= s[1] && s[1] <= '7' { + // octal escape, can vary from 1 to 3 octal digits; e.g., "\0" "\40" or "\164" + // so consume up to 2 more bytes or up to end-of-string + n := len(s[1:]) - len(strings.TrimLeft(s[1:], "01234567")) + if n > 3 { + n = 3 + } + v, err := strconv.ParseUint(s[1:1+n], 8, 8) + if err != nil { + out = append(out, s[:1+n]...) + } else { + out = append(out, byte(v)) + } + s = s[1+n:] + } else { + // bad escape, just propagate the slash as-is + out = append(out, s[0]) + s = s[1:] + } + } + + return string(out) +} + +func (g *Generator) generateExtension(ext *ExtensionDescriptor) { + ccTypeName := ext.DescName() + + extObj := g.ObjectNamed(*ext.Extendee) + var extDesc *Descriptor + if id, ok := extObj.(*ImportedDescriptor); ok { + // This is extending a publicly imported message. + // We need the underlying type for goTag. + extDesc = id.o.(*Descriptor) + } else { + extDesc = extObj.(*Descriptor) + } + extendedType := "*" + g.TypeName(extObj) // always use the original + field := ext.FieldDescriptorProto + fieldType, wireType := g.GoType(ext.parent, field) + tag := g.goTag(extDesc, field, wireType) + g.RecordTypeUse(*ext.Extendee) + if n := ext.FieldDescriptorProto.TypeName; n != nil { + // foreign extension type + g.RecordTypeUse(*n) + } + + typeName := ext.TypeName() + + // Special case for proto2 message sets: If this extension is extending + // proto2.bridge.MessageSet, and its final name component is "message_set_extension", + // then drop that last component. + // + // TODO: This should be implemented in the text formatter rather than the generator. + // In addition, the situation for when to apply this special case is implemented + // differently in other languages: + // https://github.com/google/protobuf/blob/aff10976/src/google/protobuf/text_format.cc#L1560 + if extDesc.GetOptions().GetMessageSetWireFormat() && typeName[len(typeName)-1] == "message_set_extension" { + typeName = typeName[:len(typeName)-1] + } + + // For text formatting, the package must be exactly what the .proto file declares, + // ignoring overrides such as the go_package option, and with no dot/underscore mapping. + extName := strings.Join(typeName, ".") + if g.file.Package != nil { + extName = *g.file.Package + "." + extName + } + + g.P("var ", ccTypeName, " = &", g.Pkg["proto"], ".ExtensionDesc{") + g.P("ExtendedType: (", extendedType, ")(nil),") + g.P("ExtensionType: (", fieldType, ")(nil),") + g.P("Field: ", field.Number, ",") + g.P(`Name: "`, extName, `",`) + g.P("Tag: ", tag, ",") + g.P(`Filename: "`, g.file.GetName(), `",`) + + g.P("}") + g.P() + + g.addInitf("%s.RegisterExtension(%s)", g.Pkg["proto"], ext.DescName()) + + g.file.addExport(ext, constOrVarSymbol{ccTypeName, "var", ""}) +} + +func (g *Generator) generateInitFunction() { + if len(g.init) == 0 { + return + } + g.P("func init() {") + for _, l := range g.init { + g.P(l) + } + g.P("}") + g.init = nil +} + +func (g *Generator) generateFileDescriptor(file *FileDescriptor) { + // Make a copy and trim source_code_info data. + // TODO: Trim this more when we know exactly what we need. + pb := proto.Clone(file.FileDescriptorProto).(*descriptor.FileDescriptorProto) + pb.SourceCodeInfo = nil + + b, err := proto.Marshal(pb) + if err != nil { + g.Fail(err.Error()) + } + + var buf bytes.Buffer + w, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression) + w.Write(b) + w.Close() + b = buf.Bytes() + + v := file.VarName() + g.P() + g.P("func init() { ", g.Pkg["proto"], ".RegisterFile(", strconv.Quote(*file.Name), ", ", v, ") }") + g.P("var ", v, " = []byte{") + g.P("// ", len(b), " bytes of a gzipped FileDescriptorProto") + for len(b) > 0 { + n := 16 + if n > len(b) { + n = len(b) + } + + s := "" + for _, c := range b[:n] { + s += fmt.Sprintf("0x%02x,", c) + } + g.P(s) + + b = b[n:] + } + g.P("}") +} + +func (g *Generator) generateEnumRegistration(enum *EnumDescriptor) { + // // We always print the full (proto-world) package name here. + pkg := enum.File().GetPackage() + if pkg != "" { + pkg += "." + } + // The full type name + typeName := enum.TypeName() + // The full type name, CamelCased. + ccTypeName := CamelCaseSlice(typeName) + g.addInitf("%s.RegisterEnum(%q, %[3]s_name, %[3]s_value)", g.Pkg["proto"], pkg+ccTypeName, ccTypeName) +} + +// And now lots of helper functions. + +// Is c an ASCII lower-case letter? +func isASCIILower(c byte) bool { + return 'a' <= c && c <= 'z' +} + +// Is c an ASCII digit? +func isASCIIDigit(c byte) bool { + return '0' <= c && c <= '9' +} + +// CamelCase returns the CamelCased name. +// If there is an interior underscore followed by a lower case letter, +// drop the underscore and convert the letter to upper case. +// There is a remote possibility of this rewrite causing a name collision, +// but it's so remote we're prepared to pretend it's nonexistent - since the +// C++ generator lowercases names, it's extremely unlikely to have two fields +// with different capitalizations. +// In short, _my_field_name_2 becomes XMyFieldName_2. +func CamelCase(s string) string { + if s == "" { + return "" + } + t := make([]byte, 0, 32) + i := 0 + if s[0] == '_' { + // Need a capital letter; drop the '_'. + t = append(t, 'X') + i++ + } + // Invariant: if the next letter is lower case, it must be converted + // to upper case. + // That is, we process a word at a time, where words are marked by _ or + // upper case letter. Digits are treated as words. + for ; i < len(s); i++ { + c := s[i] + if c == '_' && i+1 < len(s) && isASCIILower(s[i+1]) { + continue // Skip the underscore in s. + } + if isASCIIDigit(c) { + t = append(t, c) + continue + } + // Assume we have a letter now - if not, it's a bogus identifier. + // The next word is a sequence of characters that must start upper case. + if isASCIILower(c) { + c ^= ' ' // Make it a capital letter. + } + t = append(t, c) // Guaranteed not lower case. + // Accept lower case sequence that follows. + for i+1 < len(s) && isASCIILower(s[i+1]) { + i++ + t = append(t, s[i]) + } + } + return string(t) +} + +// CamelCaseSlice is like CamelCase, but the argument is a slice of strings to +// be joined with "_". +func CamelCaseSlice(elem []string) string { return CamelCase(strings.Join(elem, "_")) } + +// dottedSlice turns a sliced name into a dotted name. +func dottedSlice(elem []string) string { return strings.Join(elem, ".") } + +// Is this field optional? +func isOptional(field *descriptor.FieldDescriptorProto) bool { + return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_OPTIONAL +} + +// Is this field required? +func isRequired(field *descriptor.FieldDescriptorProto) bool { + return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REQUIRED +} + +// Is this field repeated? +func isRepeated(field *descriptor.FieldDescriptorProto) bool { + return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED +} + +// Is this field a scalar numeric type? +func isScalar(field *descriptor.FieldDescriptorProto) bool { + if field.Type == nil { + return false + } + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_DOUBLE, + descriptor.FieldDescriptorProto_TYPE_FLOAT, + descriptor.FieldDescriptorProto_TYPE_INT64, + descriptor.FieldDescriptorProto_TYPE_UINT64, + descriptor.FieldDescriptorProto_TYPE_INT32, + descriptor.FieldDescriptorProto_TYPE_FIXED64, + descriptor.FieldDescriptorProto_TYPE_FIXED32, + descriptor.FieldDescriptorProto_TYPE_BOOL, + descriptor.FieldDescriptorProto_TYPE_UINT32, + descriptor.FieldDescriptorProto_TYPE_ENUM, + descriptor.FieldDescriptorProto_TYPE_SFIXED32, + descriptor.FieldDescriptorProto_TYPE_SFIXED64, + descriptor.FieldDescriptorProto_TYPE_SINT32, + descriptor.FieldDescriptorProto_TYPE_SINT64: + return true + default: + return false + } +} + +// badToUnderscore is the mapping function used to generate Go names from package names, +// which can be dotted in the input .proto file. It replaces non-identifier characters such as +// dot or dash with underscore. +func badToUnderscore(r rune) rune { + if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' { + return r + } + return '_' +} + +// baseName returns the last path element of the name, with the last dotted suffix removed. +func baseName(name string) string { + // First, find the last element + if i := strings.LastIndex(name, "/"); i >= 0 { + name = name[i+1:] + } + // Now drop the suffix + if i := strings.LastIndex(name, "."); i >= 0 { + name = name[0:i] + } + return name +} + +// The SourceCodeInfo message describes the location of elements of a parsed +// .proto file by way of a "path", which is a sequence of integers that +// describe the route from a FileDescriptorProto to the relevant submessage. +// The path alternates between a field number of a repeated field, and an index +// into that repeated field. The constants below define the field numbers that +// are used. +// +// See descriptor.proto for more information about this. +const ( + // tag numbers in FileDescriptorProto + packagePath = 2 // package + messagePath = 4 // message_type + enumPath = 5 // enum_type + // tag numbers in DescriptorProto + messageFieldPath = 2 // field + messageMessagePath = 3 // nested_type + messageEnumPath = 4 // enum_type + messageOneofPath = 8 // oneof_decl + // tag numbers in EnumDescriptorProto + enumValuePath = 2 // value +) + +var supportTypeAliases bool + +func init() { + for _, tag := range build.Default.ReleaseTags { + if tag == "go1.9" { + supportTypeAliases = true + return + } + } +} diff --git a/pkg/golang-protobuf/protoc-gen-go/generator/internal/remap/remap.go b/pkg/golang-protobuf/protoc-gen-go/generator/internal/remap/remap.go new file mode 100644 index 000000000..e688c8941 --- /dev/null +++ b/pkg/golang-protobuf/protoc-gen-go/generator/internal/remap/remap.go @@ -0,0 +1,88 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package remap handles tracking the locations of Go tokens in a source text +// across a rewrite by the Go formatter. +package remap + +import ( + "fmt" + "go/scanner" + "go/token" +) + +// A Location represents a span of byte offsets in the source text. +type Location struct { + Pos, End int // End is exclusive +} + +// A Map represents a mapping between token locations in an input source text +// and locations in the correspnding output text. +type Map map[Location]Location + +// Find reports whether the specified span is recorded by m, and if so returns +// the new location it was mapped to. If the input span was not found, the +// returned location is the same as the input. +func (m Map) Find(pos, end int) (Location, bool) { + key := Location{ + Pos: pos, + End: end, + } + if loc, ok := m[key]; ok { + return loc, true + } + return key, false +} + +func (m Map) add(opos, oend, npos, nend int) { + m[Location{Pos: opos, End: oend}] = Location{Pos: npos, End: nend} +} + +// Compute constructs a location mapping from input to output. An error is +// reported if any of the tokens of output cannot be mapped. +func Compute(input, output []byte) (Map, error) { + itok := tokenize(input) + otok := tokenize(output) + if len(itok) != len(otok) { + return nil, fmt.Errorf("wrong number of tokens, %d ≠ %d", len(itok), len(otok)) + } + m := make(Map) + for i, ti := range itok { + to := otok[i] + if ti.Token != to.Token { + return nil, fmt.Errorf("token %d type mismatch: %s ≠ %s", i+1, ti, to) + } + m.add(ti.pos, ti.end, to.pos, to.end) + } + return m, nil +} + +// tokinfo records the span and type of a source token. +type tokinfo struct { + pos, end int + token.Token +} + +func tokenize(src []byte) []tokinfo { + fs := token.NewFileSet() + var s scanner.Scanner + s.Init(fs.AddFile("src", fs.Base(), len(src)), src, nil, scanner.ScanComments) + var info []tokinfo + for { + pos, next, lit := s.Scan() + switch next { + case token.SEMICOLON: + continue + } + info = append(info, tokinfo{ + pos: int(pos - 1), + end: int(pos + token.Pos(len(lit)) - 1), + Token: next, + }) + if next == token.EOF { + break + } + } + return info +} diff --git a/pkg/golang-protobuf/protoc-gen-go/generator/internal/remap/remap_test.go b/pkg/golang-protobuf/protoc-gen-go/generator/internal/remap/remap_test.go new file mode 100644 index 000000000..441ef57cb --- /dev/null +++ b/pkg/golang-protobuf/protoc-gen-go/generator/internal/remap/remap_test.go @@ -0,0 +1,55 @@ +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package remap + +import ( + "go/format" + "testing" +) + +func TestErrors(t *testing.T) { + tests := []struct { + in, out string + }{ + {"", "x"}, + {"x", ""}, + {"var x int = 5\n", "var x = 5\n"}, + {"these are \"one\" thing", "those are 'another' thing"}, + } + for _, test := range tests { + m, err := Compute([]byte(test.in), []byte(test.out)) + if err != nil { + t.Logf("Got expected error: %v", err) + continue + } + t.Errorf("Compute(%q, %q): got %+v, wanted error", test.in, test.out, m) + } +} + +func TestMatching(t *testing.T) { + // The input is a source text that will be rearranged by the formatter. + const input = `package foo +var s int +func main(){} +` + + output, err := format.Source([]byte(input)) + if err != nil { + t.Fatalf("Formatting failed: %v", err) + } + m, err := Compute([]byte(input), output) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + // Verify that the mapped locations have the same text. + for key, val := range m { + want := input[key.Pos:key.End] + got := string(output[val.Pos:val.End]) + if got != want { + t.Errorf("Token at %d:%d: got %q, want %q", key.Pos, key.End, got, want) + } + } +} diff --git a/pkg/golang-protobuf/protoc-gen-go/grpc/grpc.go b/pkg/golang-protobuf/protoc-gen-go/grpc/grpc.go new file mode 100644 index 000000000..40cba163b --- /dev/null +++ b/pkg/golang-protobuf/protoc-gen-go/grpc/grpc.go @@ -0,0 +1,521 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package grpc is deprecated. +// +// This package is excluded from the Go protocol buffer compatibility guarantee +// and may be deleted at some point in the future. +// +// Deprecated: Do not use. +package grpc + +import ( + "fmt" + "strconv" + "strings" + + pb "github.com/golang/protobuf/protoc-gen-go/descriptor" + "github.com/golang/protobuf/protoc-gen-go/generator" +) + +// generatedCodeVersion indicates a version of the generated code. +// It is incremented whenever an incompatibility between the generated code and +// the grpc package is introduced; the generated code references +// a constant, grpc.SupportPackageIsVersionN (where N is generatedCodeVersion). +const generatedCodeVersion = 6 + +// Paths for packages used by code generated in this file, +// relative to the import_prefix of the generator.Generator. +const ( + contextPkgPath = "context" + grpcPkgPath = "google.golang.org/grpc" + codePkgPath = "google.golang.org/grpc/codes" + statusPkgPath = "google.golang.org/grpc/status" +) + +func init() { + generator.RegisterPlugin(new(grpc)) +} + +// grpc is an implementation of the Go protocol buffer compiler's +// plugin architecture. It generates bindings for gRPC support. +type grpc struct { + gen *generator.Generator +} + +// Name returns the name of this plugin, "grpc". +func (g *grpc) Name() string { + return "grpc" +} + +// The names for packages imported in the generated code. +// They may vary from the final path component of the import path +// if the name is used by other packages. +var ( + contextPkg string + grpcPkg string +) + +// Init initializes the plugin. +func (g *grpc) Init(gen *generator.Generator) { + g.gen = gen +} + +// Given a type name defined in a .proto, return its object. +// Also record that we're using it, to guarantee the associated import. +func (g *grpc) objectNamed(name string) generator.Object { + g.gen.RecordTypeUse(name) + return g.gen.ObjectNamed(name) +} + +// Given a type name defined in a .proto, return its name as we will print it. +func (g *grpc) typeName(str string) string { + return g.gen.TypeName(g.objectNamed(str)) +} + +// P forwards to g.gen.P. +func (g *grpc) P(args ...interface{}) { g.gen.P(args...) } + +// Generate generates code for the services in the given file. +func (g *grpc) Generate(file *generator.FileDescriptor) { + if len(file.FileDescriptorProto.Service) == 0 { + return + } + + contextPkg = string(g.gen.AddImport(contextPkgPath)) + grpcPkg = string(g.gen.AddImport(grpcPkgPath)) + + g.P("// Reference imports to suppress errors if they are not otherwise used.") + g.P("var _ ", contextPkg, ".Context") + g.P("var _ ", grpcPkg, ".ClientConnInterface") + g.P() + + // Assert version compatibility. + g.P("// This is a compile-time assertion to ensure that this generated file") + g.P("// is compatible with the grpc package it is being compiled against.") + g.P("const _ = ", grpcPkg, ".SupportPackageIsVersion", generatedCodeVersion) + g.P() + + for i, service := range file.FileDescriptorProto.Service { + g.generateService(file, service, i) + } +} + +// GenerateImports generates the import declaration for this file. +func (g *grpc) GenerateImports(file *generator.FileDescriptor) { +} + +// reservedClientName records whether a client name is reserved on the client side. +var reservedClientName = map[string]bool{ + // TODO: do we need any in gRPC? +} + +func unexport(s string) string { return strings.ToLower(s[:1]) + s[1:] } + +// deprecationComment is the standard comment added to deprecated +// messages, fields, enums, and enum values. +var deprecationComment = "// Deprecated: Do not use." + +// generateService generates all the code for the named service. +func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.ServiceDescriptorProto, index int) { + path := fmt.Sprintf("6,%d", index) // 6 means service. + + origServName := service.GetName() + fullServName := origServName + if pkg := file.GetPackage(); pkg != "" { + fullServName = pkg + "." + fullServName + } + servName := generator.CamelCase(origServName) + deprecated := service.GetOptions().GetDeprecated() + + g.P() + g.P(fmt.Sprintf(`// %sClient is the client API for %s service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.`, servName, servName)) + + // Client interface. + if deprecated { + g.P("//") + g.P(deprecationComment) + } + g.P("type ", servName, "Client interface {") + for i, method := range service.Method { + g.gen.PrintComments(fmt.Sprintf("%s,2,%d", path, i)) // 2 means method in a service. + if method.GetOptions().GetDeprecated() { + g.P("//") + g.P(deprecationComment) + } + g.P(g.generateClientSignature(servName, method)) + } + g.P("}") + g.P() + + // Client structure. + g.P("type ", unexport(servName), "Client struct {") + g.P("cc ", grpcPkg, ".ClientConnInterface") + g.P("}") + g.P() + + // NewClient factory. + if deprecated { + g.P(deprecationComment) + } + g.P("func New", servName, "Client (cc ", grpcPkg, ".ClientConnInterface) ", servName, "Client {") + g.P("return &", unexport(servName), "Client{cc}") + g.P("}") + g.P() + + var methodIndex, streamIndex int + serviceDescVar := "_" + servName + "_serviceDesc" + // Client method implementations. + for _, method := range service.Method { + var descExpr string + if !method.GetServerStreaming() && !method.GetClientStreaming() { + // Unary RPC method + descExpr = fmt.Sprintf("&%s.Methods[%d]", serviceDescVar, methodIndex) + methodIndex++ + } else { + // Streaming RPC method + descExpr = fmt.Sprintf("&%s.Streams[%d]", serviceDescVar, streamIndex) + streamIndex++ + } + g.generateClientMethod(servName, fullServName, serviceDescVar, method, descExpr) + } + + // Server interface. + serverType := servName + "Server" + g.P("// ", serverType, " is the server API for ", servName, " service.") + if deprecated { + g.P("//") + g.P(deprecationComment) + } + g.P("type ", serverType, " interface {") + for i, method := range service.Method { + g.gen.PrintComments(fmt.Sprintf("%s,2,%d", path, i)) // 2 means method in a service. + if method.GetOptions().GetDeprecated() { + g.P("//") + g.P(deprecationComment) + } + g.P(g.generateServerSignature(servName, method)) + } + g.P("}") + g.P() + + // Server Unimplemented struct for forward compatibility. + if deprecated { + g.P(deprecationComment) + } + g.generateUnimplementedServer(servName, service) + + // Server registration. + if deprecated { + g.P(deprecationComment) + } + g.P("func Register", servName, "Server(s *", grpcPkg, ".Server, srv ", serverType, ") {") + g.P("s.RegisterService(&", serviceDescVar, `, srv)`) + g.P("}") + g.P() + + // Server handler implementations. + var handlerNames []string + for _, method := range service.Method { + hname := g.generateServerMethod(servName, fullServName, method) + handlerNames = append(handlerNames, hname) + } + + // Service descriptor. + g.P("var ", serviceDescVar, " = ", grpcPkg, ".ServiceDesc {") + g.P("ServiceName: ", strconv.Quote(fullServName), ",") + g.P("HandlerType: (*", serverType, ")(nil),") + g.P("Methods: []", grpcPkg, ".MethodDesc{") + for i, method := range service.Method { + if method.GetServerStreaming() || method.GetClientStreaming() { + continue + } + g.P("{") + g.P("MethodName: ", strconv.Quote(method.GetName()), ",") + g.P("Handler: ", handlerNames[i], ",") + g.P("},") + } + g.P("},") + g.P("Streams: []", grpcPkg, ".StreamDesc{") + for i, method := range service.Method { + if !method.GetServerStreaming() && !method.GetClientStreaming() { + continue + } + g.P("{") + g.P("StreamName: ", strconv.Quote(method.GetName()), ",") + g.P("Handler: ", handlerNames[i], ",") + if method.GetServerStreaming() { + g.P("ServerStreams: true,") + } + if method.GetClientStreaming() { + g.P("ClientStreams: true,") + } + g.P("},") + } + g.P("},") + g.P("Metadata: \"", file.GetName(), "\",") + g.P("}") + g.P() +} + +// generateUnimplementedServer creates the unimplemented server struct +func (g *grpc) generateUnimplementedServer(servName string, service *pb.ServiceDescriptorProto) { + serverType := servName + "Server" + g.P("// Unimplemented", serverType, " can be embedded to have forward compatible implementations.") + g.P("type Unimplemented", serverType, " struct {") + g.P("}") + g.P() + // UnimplementedServer's concrete methods + for _, method := range service.Method { + g.generateServerMethodConcrete(servName, method) + } + g.P() +} + +// generateServerMethodConcrete returns unimplemented methods which ensure forward compatibility +func (g *grpc) generateServerMethodConcrete(servName string, method *pb.MethodDescriptorProto) { + header := g.generateServerSignatureWithParamNames(servName, method) + g.P("func (*Unimplemented", servName, "Server) ", header, " {") + var nilArg string + if !method.GetServerStreaming() && !method.GetClientStreaming() { + nilArg = "nil, " + } + methName := generator.CamelCase(method.GetName()) + statusPkg := string(g.gen.AddImport(statusPkgPath)) + codePkg := string(g.gen.AddImport(codePkgPath)) + g.P("return ", nilArg, statusPkg, `.Errorf(`, codePkg, `.Unimplemented, "method `, methName, ` not implemented")`) + g.P("}") +} + +// generateClientSignature returns the client-side signature for a method. +func (g *grpc) generateClientSignature(servName string, method *pb.MethodDescriptorProto) string { + origMethName := method.GetName() + methName := generator.CamelCase(origMethName) + if reservedClientName[methName] { + methName += "_" + } + reqArg := ", in *" + g.typeName(method.GetInputType()) + if method.GetClientStreaming() { + reqArg = "" + } + respName := "*" + g.typeName(method.GetOutputType()) + if method.GetServerStreaming() || method.GetClientStreaming() { + respName = servName + "_" + generator.CamelCase(origMethName) + "Client" + } + return fmt.Sprintf("%s(ctx %s.Context%s, opts ...%s.CallOption) (%s, error)", methName, contextPkg, reqArg, grpcPkg, respName) +} + +func (g *grpc) generateClientMethod(servName, fullServName, serviceDescVar string, method *pb.MethodDescriptorProto, descExpr string) { + sname := fmt.Sprintf("/%s/%s", fullServName, method.GetName()) + methName := generator.CamelCase(method.GetName()) + inType := g.typeName(method.GetInputType()) + outType := g.typeName(method.GetOutputType()) + + if method.GetOptions().GetDeprecated() { + g.P(deprecationComment) + } + g.P("func (c *", unexport(servName), "Client) ", g.generateClientSignature(servName, method), "{") + if !method.GetServerStreaming() && !method.GetClientStreaming() { + g.P("out := new(", outType, ")") + // TODO: Pass descExpr to Invoke. + g.P(`err := c.cc.Invoke(ctx, "`, sname, `", in, out, opts...)`) + g.P("if err != nil { return nil, err }") + g.P("return out, nil") + g.P("}") + g.P() + return + } + streamType := unexport(servName) + methName + "Client" + g.P("stream, err := c.cc.NewStream(ctx, ", descExpr, `, "`, sname, `", opts...)`) + g.P("if err != nil { return nil, err }") + g.P("x := &", streamType, "{stream}") + if !method.GetClientStreaming() { + g.P("if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }") + g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }") + } + g.P("return x, nil") + g.P("}") + g.P() + + genSend := method.GetClientStreaming() + genRecv := method.GetServerStreaming() + genCloseAndRecv := !method.GetServerStreaming() + + // Stream auxiliary types and methods. + g.P("type ", servName, "_", methName, "Client interface {") + if genSend { + g.P("Send(*", inType, ") error") + } + if genRecv { + g.P("Recv() (*", outType, ", error)") + } + if genCloseAndRecv { + g.P("CloseAndRecv() (*", outType, ", error)") + } + g.P(grpcPkg, ".ClientStream") + g.P("}") + g.P() + + g.P("type ", streamType, " struct {") + g.P(grpcPkg, ".ClientStream") + g.P("}") + g.P() + + if genSend { + g.P("func (x *", streamType, ") Send(m *", inType, ") error {") + g.P("return x.ClientStream.SendMsg(m)") + g.P("}") + g.P() + } + if genRecv { + g.P("func (x *", streamType, ") Recv() (*", outType, ", error) {") + g.P("m := new(", outType, ")") + g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }") + g.P("return m, nil") + g.P("}") + g.P() + } + if genCloseAndRecv { + g.P("func (x *", streamType, ") CloseAndRecv() (*", outType, ", error) {") + g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }") + g.P("m := new(", outType, ")") + g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }") + g.P("return m, nil") + g.P("}") + g.P() + } +} + +// generateServerSignatureWithParamNames returns the server-side signature for a method with parameter names. +func (g *grpc) generateServerSignatureWithParamNames(servName string, method *pb.MethodDescriptorProto) string { + origMethName := method.GetName() + methName := generator.CamelCase(origMethName) + if reservedClientName[methName] { + methName += "_" + } + + var reqArgs []string + ret := "error" + if !method.GetServerStreaming() && !method.GetClientStreaming() { + reqArgs = append(reqArgs, "ctx "+contextPkg+".Context") + ret = "(*" + g.typeName(method.GetOutputType()) + ", error)" + } + if !method.GetClientStreaming() { + reqArgs = append(reqArgs, "req *"+g.typeName(method.GetInputType())) + } + if method.GetServerStreaming() || method.GetClientStreaming() { + reqArgs = append(reqArgs, "srv "+servName+"_"+generator.CamelCase(origMethName)+"Server") + } + + return methName + "(" + strings.Join(reqArgs, ", ") + ") " + ret +} + +// generateServerSignature returns the server-side signature for a method. +func (g *grpc) generateServerSignature(servName string, method *pb.MethodDescriptorProto) string { + origMethName := method.GetName() + methName := generator.CamelCase(origMethName) + if reservedClientName[methName] { + methName += "_" + } + + var reqArgs []string + ret := "error" + if !method.GetServerStreaming() && !method.GetClientStreaming() { + reqArgs = append(reqArgs, contextPkg+".Context") + ret = "(*" + g.typeName(method.GetOutputType()) + ", error)" + } + if !method.GetClientStreaming() { + reqArgs = append(reqArgs, "*"+g.typeName(method.GetInputType())) + } + if method.GetServerStreaming() || method.GetClientStreaming() { + reqArgs = append(reqArgs, servName+"_"+generator.CamelCase(origMethName)+"Server") + } + + return methName + "(" + strings.Join(reqArgs, ", ") + ") " + ret +} + +func (g *grpc) generateServerMethod(servName, fullServName string, method *pb.MethodDescriptorProto) string { + methName := generator.CamelCase(method.GetName()) + hname := fmt.Sprintf("_%s_%s_Handler", servName, methName) + inType := g.typeName(method.GetInputType()) + outType := g.typeName(method.GetOutputType()) + + if !method.GetServerStreaming() && !method.GetClientStreaming() { + g.P("func ", hname, "(srv interface{}, ctx ", contextPkg, ".Context, dec func(interface{}) error, interceptor ", grpcPkg, ".UnaryServerInterceptor) (interface{}, error) {") + g.P("in := new(", inType, ")") + g.P("if err := dec(in); err != nil { return nil, err }") + g.P("if interceptor == nil { return srv.(", servName, "Server).", methName, "(ctx, in) }") + g.P("info := &", grpcPkg, ".UnaryServerInfo{") + g.P("Server: srv,") + g.P("FullMethod: ", strconv.Quote(fmt.Sprintf("/%s/%s", fullServName, methName)), ",") + g.P("}") + g.P("handler := func(ctx ", contextPkg, ".Context, req interface{}) (interface{}, error) {") + g.P("return srv.(", servName, "Server).", methName, "(ctx, req.(*", inType, "))") + g.P("}") + g.P("return interceptor(ctx, in, info, handler)") + g.P("}") + g.P() + return hname + } + streamType := unexport(servName) + methName + "Server" + g.P("func ", hname, "(srv interface{}, stream ", grpcPkg, ".ServerStream) error {") + if !method.GetClientStreaming() { + g.P("m := new(", inType, ")") + g.P("if err := stream.RecvMsg(m); err != nil { return err }") + g.P("return srv.(", servName, "Server).", methName, "(m, &", streamType, "{stream})") + } else { + g.P("return srv.(", servName, "Server).", methName, "(&", streamType, "{stream})") + } + g.P("}") + g.P() + + genSend := method.GetServerStreaming() + genSendAndClose := !method.GetServerStreaming() + genRecv := method.GetClientStreaming() + + // Stream auxiliary types and methods. + g.P("type ", servName, "_", methName, "Server interface {") + if genSend { + g.P("Send(*", outType, ") error") + } + if genSendAndClose { + g.P("SendAndClose(*", outType, ") error") + } + if genRecv { + g.P("Recv() (*", inType, ", error)") + } + g.P(grpcPkg, ".ServerStream") + g.P("}") + g.P() + + g.P("type ", streamType, " struct {") + g.P(grpcPkg, ".ServerStream") + g.P("}") + g.P() + + if genSend { + g.P("func (x *", streamType, ") Send(m *", outType, ") error {") + g.P("return x.ServerStream.SendMsg(m)") + g.P("}") + g.P() + } + if genSendAndClose { + g.P("func (x *", streamType, ") SendAndClose(m *", outType, ") error {") + g.P("return x.ServerStream.SendMsg(m)") + g.P("}") + g.P() + } + if genRecv { + g.P("func (x *", streamType, ") Recv() (*", inType, ", error) {") + g.P("m := new(", inType, ")") + g.P("if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }") + g.P("return m, nil") + g.P("}") + g.P() + } + + return hname +} diff --git a/pkg/golang-protobuf/protoc-gen-go/main.go b/pkg/golang-protobuf/protoc-gen-go/main.go new file mode 100644 index 000000000..d45b719d1 --- /dev/null +++ b/pkg/golang-protobuf/protoc-gen-go/main.go @@ -0,0 +1,74 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// protoc-gen-go is a plugin for the Google protocol buffer compiler to generate +// Go code. Install it by building this program and making it accessible within +// your PATH with the name: +// protoc-gen-go +// +// The 'go' suffix becomes part of the argument for the protocol compiler, +// such that it can be invoked as: +// protoc --go_out=paths=source_relative:. path/to/file.proto +// +// This generates Go bindings for the protocol buffer defined by file.proto. +// With that input, the output will be written to: +// path/to/file.pb.go +// +// See the README and documentation for protocol buffers to learn more: +// https://developers.google.com/protocol-buffers/ +package main + +import ( + "flag" + "fmt" + "strings" + + "github.com/golang/protobuf/internal/gengogrpc" + gengo "google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo" + "google.golang.org/protobuf/compiler/protogen" +) + +func main() { + var ( + flags flag.FlagSet + plugins = flags.String("plugins", "", "list of plugins to enable (supported values: grpc)") + importPrefix = flags.String("import_prefix", "", "prefix to prepend to import paths") + ) + importRewriteFunc := func(importPath protogen.GoImportPath) protogen.GoImportPath { + switch importPath { + case "context", "fmt", "math": + return importPath + } + if *importPrefix != "" { + return protogen.GoImportPath(*importPrefix) + importPath + } + return importPath + } + protogen.Options{ + ParamFunc: flags.Set, + ImportRewriteFunc: importRewriteFunc, + }.Run(func(gen *protogen.Plugin) error { + grpc := false + for _, plugin := range strings.Split(*plugins, ",") { + switch plugin { + case "grpc": + grpc = true + case "": + default: + return fmt.Errorf("protoc-gen-go: unknown plugin %q", plugin) + } + } + for _, f := range gen.Files { + if !f.Generate { + continue + } + g := gengo.GenerateFile(gen, f) + if grpc { + gengogrpc.GenerateFileContent(gen, f, g) + } + } + gen.SupportedFeatures = gengo.SupportedFeatures + return nil + }) +} diff --git a/pkg/golang-protobuf/protoc-gen-go/plugin/plugin.pb.go b/pkg/golang-protobuf/protoc-gen-go/plugin/plugin.pb.go new file mode 100644 index 000000000..b7b4a2f94 --- /dev/null +++ b/pkg/golang-protobuf/protoc-gen-go/plugin/plugin.pb.go @@ -0,0 +1,75 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: github.com/golang/protobuf/protoc-gen-go/plugin/plugin.proto + +package plugin_go + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + pluginpb "google.golang.org/protobuf/types/pluginpb" + reflect "reflect" +) + +// Symbols defined in public import of google/protobuf/compiler/plugin.proto. + +type CodeGeneratorResponse_Feature = pluginpb.CodeGeneratorResponse_Feature + +const CodeGeneratorResponse_FEATURE_NONE = pluginpb.CodeGeneratorResponse_FEATURE_NONE +const CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL = pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL + +var CodeGeneratorResponse_Feature_name = pluginpb.CodeGeneratorResponse_Feature_name +var CodeGeneratorResponse_Feature_value = pluginpb.CodeGeneratorResponse_Feature_value + +type Version = pluginpb.Version +type CodeGeneratorRequest = pluginpb.CodeGeneratorRequest +type CodeGeneratorResponse = pluginpb.CodeGeneratorResponse +type CodeGeneratorResponse_File = pluginpb.CodeGeneratorResponse_File + +var File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto protoreflect.FileDescriptor + +var file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_rawDesc = []byte{ + 0x0a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, + 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, 0x6f, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, + 0x6e, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x25, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, + 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x67, + 0x6f, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x3b, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, + 0x67, 0x6f, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, +} + +var file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_goTypes = []interface{}{} +var file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_init() } +func file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_init() { + if File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_goTypes, + DependencyIndexes: file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_depIdxs, + }.Build() + File_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto = out.File + file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_rawDesc = nil + file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_goTypes = nil + file_github_com_golang_protobuf_protoc_gen_go_plugin_plugin_proto_depIdxs = nil +} diff --git a/pkg/golang-protobuf/ptypes/any.go b/pkg/golang-protobuf/ptypes/any.go new file mode 100644 index 000000000..85f9f5736 --- /dev/null +++ b/pkg/golang-protobuf/ptypes/any.go @@ -0,0 +1,179 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ptypes + +import ( + "fmt" + "strings" + + "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + + anypb "github.com/golang/protobuf/ptypes/any" +) + +const urlPrefix = "type.googleapis.com/" + +// AnyMessageName returns the message name contained in an anypb.Any message. +// Most type assertions should use the Is function instead. +// +// Deprecated: Call the any.MessageName method instead. +func AnyMessageName(any *anypb.Any) (string, error) { + name, err := anyMessageName(any) + return string(name), err +} +func anyMessageName(any *anypb.Any) (protoreflect.FullName, error) { + if any == nil { + return "", fmt.Errorf("message is nil") + } + name := protoreflect.FullName(any.TypeUrl) + if i := strings.LastIndex(any.TypeUrl, "/"); i >= 0 { + name = name[i+len("/"):] + } + if !name.IsValid() { + return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl) + } + return name, nil +} + +// MarshalAny marshals the given message m into an anypb.Any message. +// +// Deprecated: Call the anypb.New function instead. +func MarshalAny(m proto.Message) (*anypb.Any, error) { + switch dm := m.(type) { + case DynamicAny: + m = dm.Message + case *DynamicAny: + if dm == nil { + return nil, proto.ErrNil + } + m = dm.Message + } + b, err := proto.Marshal(m) + if err != nil { + return nil, err + } + return &anypb.Any{TypeUrl: urlPrefix + proto.MessageName(m), Value: b}, nil +} + +// Empty returns a new message of the type specified in an anypb.Any message. +// It returns protoregistry.NotFound if the corresponding message type could not +// be resolved in the global registry. +// +// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead +// to resolve the message name and create a new instance of it. +func Empty(any *anypb.Any) (proto.Message, error) { + name, err := anyMessageName(any) + if err != nil { + return nil, err + } + mt, err := protoregistry.GlobalTypes.FindMessageByName(name) + if err != nil { + return nil, err + } + return proto.MessageV1(mt.New().Interface()), nil +} + +// UnmarshalAny unmarshals the encoded value contained in the anypb.Any message +// into the provided message m. It returns an error if the target message +// does not match the type in the Any message or if an unmarshal error occurs. +// +// The target message m may be a *DynamicAny message. If the underlying message +// type could not be resolved, then this returns protoregistry.NotFound. +// +// Deprecated: Call the any.UnmarshalTo method instead. +func UnmarshalAny(any *anypb.Any, m proto.Message) error { + if dm, ok := m.(*DynamicAny); ok { + if dm.Message == nil { + var err error + dm.Message, err = Empty(any) + if err != nil { + return err + } + } + m = dm.Message + } + + anyName, err := AnyMessageName(any) + if err != nil { + return err + } + msgName := proto.MessageName(m) + if anyName != msgName { + return fmt.Errorf("mismatched message type: got %q want %q", anyName, msgName) + } + return proto.Unmarshal(any.Value, m) +} + +// Is reports whether the Any message contains a message of the specified type. +// +// Deprecated: Call the any.MessageIs method instead. +func Is(any *anypb.Any, m proto.Message) bool { + if any == nil || m == nil { + return false + } + name := proto.MessageName(m) + if !strings.HasSuffix(any.TypeUrl, name) { + return false + } + return len(any.TypeUrl) == len(name) || any.TypeUrl[len(any.TypeUrl)-len(name)-1] == '/' +} + +// DynamicAny is a value that can be passed to UnmarshalAny to automatically +// allocate a proto.Message for the type specified in an anypb.Any message. +// The allocated message is stored in the embedded proto.Message. +// +// Example: +// var x ptypes.DynamicAny +// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... } +// fmt.Printf("unmarshaled message: %v", x.Message) +// +// Deprecated: Use the any.UnmarshalNew method instead to unmarshal +// the any message contents into a new instance of the underlying message. +type DynamicAny struct{ proto.Message } + +func (m DynamicAny) String() string { + if m.Message == nil { + return "" + } + return m.Message.String() +} +func (m DynamicAny) Reset() { + if m.Message == nil { + return + } + m.Message.Reset() +} +func (m DynamicAny) ProtoMessage() { + return +} +func (m DynamicAny) ProtoReflect() protoreflect.Message { + if m.Message == nil { + return nil + } + return dynamicAny{proto.MessageReflect(m.Message)} +} + +type dynamicAny struct{ protoreflect.Message } + +func (m dynamicAny) Type() protoreflect.MessageType { + return dynamicAnyType{m.Message.Type()} +} +func (m dynamicAny) New() protoreflect.Message { + return dynamicAnyType{m.Message.Type()}.New() +} +func (m dynamicAny) Interface() protoreflect.ProtoMessage { + return DynamicAny{proto.MessageV1(m.Message.Interface())} +} + +type dynamicAnyType struct{ protoreflect.MessageType } + +func (t dynamicAnyType) New() protoreflect.Message { + return dynamicAny{t.MessageType.New()} +} +func (t dynamicAnyType) Zero() protoreflect.Message { + return dynamicAny{t.MessageType.Zero()} +} diff --git a/pkg/golang-protobuf/ptypes/any/any.pb.go b/pkg/golang-protobuf/ptypes/any/any.pb.go new file mode 100644 index 000000000..0ef27d33d --- /dev/null +++ b/pkg/golang-protobuf/ptypes/any/any.pb.go @@ -0,0 +1,62 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: github.com/golang/protobuf/ptypes/any/any.proto + +package any + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" + reflect "reflect" +) + +// Symbols defined in public import of google/protobuf/any.proto. + +type Any = anypb.Any + +var File_github_com_golang_protobuf_ptypes_any_any_proto protoreflect.FileDescriptor + +var file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = []byte{ + 0x0a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, + 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x2b, 0x5a, 0x29, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, + 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x3b, 0x61, 0x6e, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = []interface{}{} +var file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_github_com_golang_protobuf_ptypes_any_any_proto_init() } +func file_github_com_golang_protobuf_ptypes_any_any_proto_init() { + if File_github_com_golang_protobuf_ptypes_any_any_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes, + DependencyIndexes: file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs, + }.Build() + File_github_com_golang_protobuf_ptypes_any_any_proto = out.File + file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = nil + file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = nil + file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = nil +} diff --git a/pkg/golang-protobuf/ptypes/any_test.go b/pkg/golang-protobuf/ptypes/any_test.go new file mode 100644 index 000000000..c865e1ca5 --- /dev/null +++ b/pkg/golang-protobuf/ptypes/any_test.go @@ -0,0 +1,166 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ptypes + +import ( + "reflect" + "testing" + + "github.com/golang/protobuf/proto" + + descriptorpb "github.com/golang/protobuf/protoc-gen-go/descriptor" + anypb "github.com/golang/protobuf/ptypes/any" +) + +func TestMarshalUnmarshal(t *testing.T) { + orig := &anypb.Any{Value: []byte("test")} + + packed, err := MarshalAny(orig) + if err != nil { + t.Errorf("MarshalAny(%+v): got: _, %v exp: _, nil", orig, err) + } + + unpacked := &anypb.Any{} + err = UnmarshalAny(packed, unpacked) + if err != nil || !proto.Equal(unpacked, orig) { + t.Errorf("got: %v, %+v; want nil, %+v", err, unpacked, orig) + } +} + +func TestIs(t *testing.T) { + a, err := MarshalAny(&descriptorpb.FileDescriptorProto{}) + if err != nil { + t.Fatal(err) + } + if Is(a, &descriptorpb.DescriptorProto{}) { + // No spurious match for message names of different length. + t.Error("FileDescriptorProto is not a DescriptorProto, but Is says it is") + } + if Is(a, &descriptorpb.EnumDescriptorProto{}) { + // No spurious match for message names of equal length. + t.Error("FileDescriptorProto is not an EnumDescriptorProto, but Is says it is") + } + if !Is(a, &descriptorpb.FileDescriptorProto{}) { + t.Error("FileDescriptorProto is indeed a FileDescriptorProto, but Is says it is not") + } +} + +func TestIsDifferentUrlPrefixes(t *testing.T) { + m := &descriptorpb.FileDescriptorProto{} + a := &anypb.Any{TypeUrl: "foo/bar/" + proto.MessageName(m)} + if !Is(a, m) { + t.Errorf("message with type url %q didn't satisfy Is for type %q", a.TypeUrl, proto.MessageName(m)) + } +} + +func TestIsCornerCases(t *testing.T) { + m := &descriptorpb.FileDescriptorProto{} + if Is(nil, m) { + t.Errorf("message with nil type url incorrectly claimed to be %q", proto.MessageName(m)) + } + noPrefix := &anypb.Any{TypeUrl: proto.MessageName(m)} + if !Is(noPrefix, m) { + t.Errorf("message with type url %q didn't satisfy Is for type %q", noPrefix.TypeUrl, proto.MessageName(m)) + } + shortPrefix := &anypb.Any{TypeUrl: "/" + proto.MessageName(m)} + if !Is(shortPrefix, m) { + t.Errorf("message with type url %q didn't satisfy Is for type %q", shortPrefix.TypeUrl, proto.MessageName(m)) + } +} + +func TestUnmarshalDynamic(t *testing.T) { + want := &descriptorpb.FileDescriptorProto{Name: proto.String("foo")} + a, err := MarshalAny(want) + if err != nil { + t.Fatal(err) + } + var got DynamicAny + if err := UnmarshalAny(a, &got); err != nil { + t.Fatal(err) + } + if !proto.Equal(got.Message, want) { + t.Errorf("invalid result from UnmarshalAny, got %q want %q", got.Message, want) + } +} + +func TestEmpty(t *testing.T) { + want := &descriptorpb.FileDescriptorProto{} + a, err := MarshalAny(want) + if err != nil { + t.Fatal(err) + } + got, err := Empty(a) + if err != nil { + t.Fatal(err) + } + if !proto.Equal(got, want) { + t.Errorf("unequal empty message, got %q, want %q", got, want) + } + + // that's a valid type_url for a message which shouldn't be linked into this + // test binary. We want an error. + a.TypeUrl = "type.googleapis.com/google.protobuf.FieldMask" + if _, err := Empty(a); err == nil { + t.Errorf("got no error for an attempt to create a message of type %q, which shouldn't be linked in", a.TypeUrl) + } +} + +func TestEmptyCornerCases(t *testing.T) { + _, err := Empty(nil) + if err == nil { + t.Error("expected Empty for nil to fail") + } + want := &descriptorpb.FileDescriptorProto{} + noPrefix := &anypb.Any{TypeUrl: proto.MessageName(want)} + got, err := Empty(noPrefix) + if err != nil { + t.Errorf("Empty for any type %q failed: %s", noPrefix.TypeUrl, err) + } + if !proto.Equal(got, want) { + t.Errorf("Empty for any type %q differs, got %q, want %q", noPrefix.TypeUrl, got, want) + } + shortPrefix := &anypb.Any{TypeUrl: "/" + proto.MessageName(want)} + got, err = Empty(shortPrefix) + if err != nil { + t.Errorf("Empty for any type %q failed: %s", shortPrefix.TypeUrl, err) + } + if !proto.Equal(got, want) { + t.Errorf("Empty for any type %q differs, got %q, want %q", shortPrefix.TypeUrl, got, want) + } +} + +func TestAnyReflect(t *testing.T) { + want := &descriptorpb.FileDescriptorProto{Name: proto.String("foo")} + a, err := MarshalAny(want) + if err != nil { + t.Fatal(err) + } + var got DynamicAny + if err := UnmarshalAny(a, &got); err != nil { + t.Fatal(err) + } + wantName := want.ProtoReflect().Descriptor().FullName() + gotName := got.ProtoReflect().Descriptor().FullName() + if gotName != wantName { + t.Errorf("name mismatch: got %v, want %v", gotName, wantName) + } + wantType := reflect.TypeOf(got) + gotType := reflect.TypeOf(got.ProtoReflect().Interface()) + if gotType != wantType { + t.Errorf("ProtoReflect().Interface() round-trip type mismatch: got %v, want %v", gotType, wantType) + } + gotType = reflect.TypeOf(got.ProtoReflect().New().Interface()) + if gotType != wantType { + t.Errorf("ProtoReflect().New().Interface() type mismatch: got %v, want %v", gotType, wantType) + } + gotType = reflect.TypeOf(got.ProtoReflect().Type().New().Interface()) + if gotType != wantType { + t.Errorf("ProtoReflect().Type().New().Interface() type mismatch: got %v, want %v", gotType, wantType) + } + gotType = reflect.TypeOf(got.ProtoReflect().Type().Zero().Interface()) + if gotType != wantType { + t.Errorf("ProtoReflect().Type().Zero().Interface() type mismatch: got %v, want %v", gotType, wantType) + } +} diff --git a/pkg/golang-protobuf/ptypes/doc.go b/pkg/golang-protobuf/ptypes/doc.go new file mode 100644 index 000000000..d3c33259d --- /dev/null +++ b/pkg/golang-protobuf/ptypes/doc.go @@ -0,0 +1,10 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package ptypes provides functionality for interacting with well-known types. +// +// Deprecated: Well-known types have specialized functionality directly +// injected into the generated packages for each message type. +// See the deprecation notice for each function for the suggested alternative. +package ptypes diff --git a/pkg/golang-protobuf/ptypes/duration.go b/pkg/golang-protobuf/ptypes/duration.go new file mode 100644 index 000000000..b2b55dd85 --- /dev/null +++ b/pkg/golang-protobuf/ptypes/duration.go @@ -0,0 +1,76 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ptypes + +import ( + "errors" + "fmt" + "time" + + durationpb "github.com/golang/protobuf/ptypes/duration" +) + +// Range of google.protobuf.Duration as specified in duration.proto. +// This is about 10,000 years in seconds. +const ( + maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60) + minSeconds = -maxSeconds +) + +// Duration converts a durationpb.Duration to a time.Duration. +// Duration returns an error if dur is invalid or overflows a time.Duration. +// +// Deprecated: Call the dur.AsDuration and dur.CheckValid methods instead. +func Duration(dur *durationpb.Duration) (time.Duration, error) { + if err := validateDuration(dur); err != nil { + return 0, err + } + d := time.Duration(dur.Seconds) * time.Second + if int64(d/time.Second) != dur.Seconds { + return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur) + } + if dur.Nanos != 0 { + d += time.Duration(dur.Nanos) * time.Nanosecond + if (d < 0) != (dur.Nanos < 0) { + return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur) + } + } + return d, nil +} + +// DurationProto converts a time.Duration to a durationpb.Duration. +// +// Deprecated: Call the durationpb.New function instead. +func DurationProto(d time.Duration) *durationpb.Duration { + nanos := d.Nanoseconds() + secs := nanos / 1e9 + nanos -= secs * 1e9 + return &durationpb.Duration{ + Seconds: int64(secs), + Nanos: int32(nanos), + } +} + +// validateDuration determines whether the durationpb.Duration is valid +// according to the definition in google/protobuf/duration.proto. +// A valid durpb.Duration may still be too large to fit into a time.Duration +// Note that the range of durationpb.Duration is about 10,000 years, +// while the range of time.Duration is about 290 years. +func validateDuration(dur *durationpb.Duration) error { + if dur == nil { + return errors.New("duration: nil Duration") + } + if dur.Seconds < minSeconds || dur.Seconds > maxSeconds { + return fmt.Errorf("duration: %v: seconds out of range", dur) + } + if dur.Nanos <= -1e9 || dur.Nanos >= 1e9 { + return fmt.Errorf("duration: %v: nanos out of range", dur) + } + // Seconds and Nanos must have the same sign, unless d.Nanos is zero. + if (dur.Seconds < 0 && dur.Nanos > 0) || (dur.Seconds > 0 && dur.Nanos < 0) { + return fmt.Errorf("duration: %v: seconds and nanos have different signs", dur) + } + return nil +} diff --git a/pkg/golang-protobuf/ptypes/duration/duration.pb.go b/pkg/golang-protobuf/ptypes/duration/duration.pb.go new file mode 100644 index 000000000..d0079ee3e --- /dev/null +++ b/pkg/golang-protobuf/ptypes/duration/duration.pb.go @@ -0,0 +1,63 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: github.com/golang/protobuf/ptypes/duration/duration.proto + +package duration + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + durationpb "google.golang.org/protobuf/types/known/durationpb" + reflect "reflect" +) + +// Symbols defined in public import of google/protobuf/duration.proto. + +type Duration = durationpb.Duration + +var File_github_com_golang_protobuf_ptypes_duration_duration_proto protoreflect.FileDescriptor + +var file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = []byte{ + 0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, + 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x35, 0x5a, 0x33, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = []interface{}{} +var file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() } +func file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() { + if File_github_com_golang_protobuf_ptypes_duration_duration_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes, + DependencyIndexes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs, + }.Build() + File_github_com_golang_protobuf_ptypes_duration_duration_proto = out.File + file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = nil + file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = nil + file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = nil +} diff --git a/pkg/golang-protobuf/ptypes/duration_test.go b/pkg/golang-protobuf/ptypes/duration_test.go new file mode 100644 index 000000000..b11827c2c --- /dev/null +++ b/pkg/golang-protobuf/ptypes/duration_test.go @@ -0,0 +1,95 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ptypes + +import ( + "math" + "testing" + "time" + + "github.com/golang/protobuf/proto" + + durpb "github.com/golang/protobuf/ptypes/duration" +) + +const ( + minGoSeconds = math.MinInt64 / int64(1e9) + maxGoSeconds = math.MaxInt64 / int64(1e9) +) + +var durationTests = []struct { + proto *durpb.Duration + isValid bool + inRange bool + dur time.Duration +}{ + // The zero duration. + {&durpb.Duration{Seconds: 0, Nanos: 0}, true, true, 0}, + // Some ordinary non-zero durations. + {&durpb.Duration{Seconds: 100, Nanos: 0}, true, true, 100 * time.Second}, + {&durpb.Duration{Seconds: -100, Nanos: 0}, true, true, -100 * time.Second}, + {&durpb.Duration{Seconds: 100, Nanos: 987}, true, true, 100*time.Second + 987}, + {&durpb.Duration{Seconds: -100, Nanos: -987}, true, true, -(100*time.Second + 987)}, + // The largest duration representable in Go. + {&durpb.Duration{Seconds: maxGoSeconds, Nanos: int32(math.MaxInt64 - 1e9*maxGoSeconds)}, true, true, math.MaxInt64}, + // The smallest duration representable in Go. + {&durpb.Duration{Seconds: minGoSeconds, Nanos: int32(math.MinInt64 - 1e9*minGoSeconds)}, true, true, math.MinInt64}, + {nil, false, false, 0}, + {&durpb.Duration{Seconds: -100, Nanos: 987}, false, false, 0}, + {&durpb.Duration{Seconds: 100, Nanos: -987}, false, false, 0}, + {&durpb.Duration{Seconds: math.MinInt64, Nanos: 0}, false, false, 0}, + {&durpb.Duration{Seconds: math.MaxInt64, Nanos: 0}, false, false, 0}, + // The largest valid duration. + {&durpb.Duration{Seconds: maxSeconds, Nanos: 1e9 - 1}, true, false, 0}, + // The smallest valid duration. + {&durpb.Duration{Seconds: minSeconds, Nanos: -(1e9 - 1)}, true, false, 0}, + // The smallest invalid duration above the valid range. + {&durpb.Duration{Seconds: maxSeconds + 1, Nanos: 0}, false, false, 0}, + // The largest invalid duration below the valid range. + {&durpb.Duration{Seconds: minSeconds - 1, Nanos: -(1e9 - 1)}, false, false, 0}, + // One nanosecond past the largest duration representable in Go. + {&durpb.Duration{Seconds: maxGoSeconds, Nanos: int32(math.MaxInt64-1e9*maxGoSeconds) + 1}, true, false, 0}, + // One nanosecond past the smallest duration representable in Go. + {&durpb.Duration{Seconds: minGoSeconds, Nanos: int32(math.MinInt64-1e9*minGoSeconds) - 1}, true, false, 0}, + // One second past the largest duration representable in Go. + {&durpb.Duration{Seconds: maxGoSeconds + 1, Nanos: int32(math.MaxInt64 - 1e9*maxGoSeconds)}, true, false, 0}, + // One second past the smallest duration representable in Go. + {&durpb.Duration{Seconds: minGoSeconds - 1, Nanos: int32(math.MinInt64 - 1e9*minGoSeconds)}, true, false, 0}, +} + +func TestValidateDuration(t *testing.T) { + for _, test := range durationTests { + err := validateDuration(test.proto) + gotValid := (err == nil) + if gotValid != test.isValid { + t.Errorf("validateDuration(%v) = %t, want %t", test.proto, gotValid, test.isValid) + } + } +} + +func TestDuration(t *testing.T) { + for _, test := range durationTests { + got, err := Duration(test.proto) + gotOK := (err == nil) + wantOK := test.isValid && test.inRange + if gotOK != wantOK { + t.Errorf("Duration(%v) ok = %t, want %t", test.proto, gotOK, wantOK) + } + if err == nil && got != test.dur { + t.Errorf("Duration(%v) = %v, want %v", test.proto, got, test.dur) + } + } +} + +func TestDurationProto(t *testing.T) { + for _, test := range durationTests { + if test.isValid && test.inRange { + got := DurationProto(test.dur) + if !proto.Equal(got, test.proto) { + t.Errorf("DurationProto(%v) = %v, want %v", test.dur, got, test.proto) + } + } + } +} diff --git a/pkg/golang-protobuf/ptypes/empty/empty.pb.go b/pkg/golang-protobuf/ptypes/empty/empty.pb.go new file mode 100644 index 000000000..16686a655 --- /dev/null +++ b/pkg/golang-protobuf/ptypes/empty/empty.pb.go @@ -0,0 +1,62 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: github.com/golang/protobuf/ptypes/empty/empty.proto + +package empty + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + reflect "reflect" +) + +// Symbols defined in public import of google/protobuf/empty.proto. + +type Empty = emptypb.Empty + +var File_github_com_golang_protobuf_ptypes_empty_empty_proto protoreflect.FileDescriptor + +var file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc = []byte{ + 0x0a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, + 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3b, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = []interface{}{} +var file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_github_com_golang_protobuf_ptypes_empty_empty_proto_init() } +func file_github_com_golang_protobuf_ptypes_empty_empty_proto_init() { + if File_github_com_golang_protobuf_ptypes_empty_empty_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes, + DependencyIndexes: file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs, + }.Build() + File_github_com_golang_protobuf_ptypes_empty_empty_proto = out.File + file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc = nil + file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = nil + file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = nil +} diff --git a/pkg/golang-protobuf/ptypes/struct/struct.pb.go b/pkg/golang-protobuf/ptypes/struct/struct.pb.go new file mode 100644 index 000000000..8d82abe21 --- /dev/null +++ b/pkg/golang-protobuf/ptypes/struct/struct.pb.go @@ -0,0 +1,78 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: github.com/golang/protobuf/ptypes/struct/struct.proto + +package structpb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + structpb "google.golang.org/protobuf/types/known/structpb" + reflect "reflect" +) + +// Symbols defined in public import of google/protobuf/struct.proto. + +type NullValue = structpb.NullValue + +const NullValue_NULL_VALUE = structpb.NullValue_NULL_VALUE + +var NullValue_name = structpb.NullValue_name +var NullValue_value = structpb.NullValue_value + +type Struct = structpb.Struct +type Value = structpb.Value +type Value_NullValue = structpb.Value_NullValue +type Value_NumberValue = structpb.Value_NumberValue +type Value_StringValue = structpb.Value_StringValue +type Value_BoolValue = structpb.Value_BoolValue +type Value_StructValue = structpb.Value_StructValue +type Value_ListValue = structpb.Value_ListValue +type ListValue = structpb.ListValue + +var File_github_com_golang_protobuf_ptypes_struct_struct_proto protoreflect.FileDescriptor + +var file_github_com_golang_protobuf_ptypes_struct_struct_proto_rawDesc = []byte{ + 0x0a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, + 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x33, 0x5a, 0x31, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x3b, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x70, 0x62, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var file_github_com_golang_protobuf_ptypes_struct_struct_proto_goTypes = []interface{}{} +var file_github_com_golang_protobuf_ptypes_struct_struct_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_github_com_golang_protobuf_ptypes_struct_struct_proto_init() } +func file_github_com_golang_protobuf_ptypes_struct_struct_proto_init() { + if File_github_com_golang_protobuf_ptypes_struct_struct_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_golang_protobuf_ptypes_struct_struct_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_golang_protobuf_ptypes_struct_struct_proto_goTypes, + DependencyIndexes: file_github_com_golang_protobuf_ptypes_struct_struct_proto_depIdxs, + }.Build() + File_github_com_golang_protobuf_ptypes_struct_struct_proto = out.File + file_github_com_golang_protobuf_ptypes_struct_struct_proto_rawDesc = nil + file_github_com_golang_protobuf_ptypes_struct_struct_proto_goTypes = nil + file_github_com_golang_protobuf_ptypes_struct_struct_proto_depIdxs = nil +} diff --git a/pkg/golang-protobuf/ptypes/timestamp.go b/pkg/golang-protobuf/ptypes/timestamp.go new file mode 100644 index 000000000..8368a3f70 --- /dev/null +++ b/pkg/golang-protobuf/ptypes/timestamp.go @@ -0,0 +1,112 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ptypes + +import ( + "errors" + "fmt" + "time" + + timestamppb "github.com/golang/protobuf/ptypes/timestamp" +) + +// Range of google.protobuf.Duration as specified in timestamp.proto. +const ( + // Seconds field of the earliest valid Timestamp. + // This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). + minValidSeconds = -62135596800 + // Seconds field just after the latest valid Timestamp. + // This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). + maxValidSeconds = 253402300800 +) + +// Timestamp converts a timestamppb.Timestamp to a time.Time. +// It returns an error if the argument is invalid. +// +// Unlike most Go functions, if Timestamp returns an error, the first return +// value is not the zero time.Time. Instead, it is the value obtained from the +// time.Unix function when passed the contents of the Timestamp, in the UTC +// locale. This may or may not be a meaningful time; many invalid Timestamps +// do map to valid time.Times. +// +// A nil Timestamp returns an error. The first return value in that case is +// undefined. +// +// Deprecated: Call the ts.AsTime and ts.CheckValid methods instead. +func Timestamp(ts *timestamppb.Timestamp) (time.Time, error) { + // Don't return the zero value on error, because corresponds to a valid + // timestamp. Instead return whatever time.Unix gives us. + var t time.Time + if ts == nil { + t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp + } else { + t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC() + } + return t, validateTimestamp(ts) +} + +// TimestampNow returns a google.protobuf.Timestamp for the current time. +// +// Deprecated: Call the timestamppb.Now function instead. +func TimestampNow() *timestamppb.Timestamp { + ts, err := TimestampProto(time.Now()) + if err != nil { + panic("ptypes: time.Now() out of Timestamp range") + } + return ts +} + +// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto. +// It returns an error if the resulting Timestamp is invalid. +// +// Deprecated: Call the timestamppb.New function instead. +func TimestampProto(t time.Time) (*timestamppb.Timestamp, error) { + ts := ×tamppb.Timestamp{ + Seconds: t.Unix(), + Nanos: int32(t.Nanosecond()), + } + if err := validateTimestamp(ts); err != nil { + return nil, err + } + return ts, nil +} + +// TimestampString returns the RFC 3339 string for valid Timestamps. +// For invalid Timestamps, it returns an error message in parentheses. +// +// Deprecated: Call the ts.AsTime method instead, +// followed by a call to the Format method on the time.Time value. +func TimestampString(ts *timestamppb.Timestamp) string { + t, err := Timestamp(ts) + if err != nil { + return fmt.Sprintf("(%v)", err) + } + return t.Format(time.RFC3339Nano) +} + +// validateTimestamp determines whether a Timestamp is valid. +// A valid timestamp represents a time in the range [0001-01-01, 10000-01-01) +// and has a Nanos field in the range [0, 1e9). +// +// If the Timestamp is valid, validateTimestamp returns nil. +// Otherwise, it returns an error that describes the problem. +// +// Every valid Timestamp can be represented by a time.Time, +// but the converse is not true. +func validateTimestamp(ts *timestamppb.Timestamp) error { + if ts == nil { + return errors.New("timestamp: nil Timestamp") + } + if ts.Seconds < minValidSeconds { + return fmt.Errorf("timestamp: %v before 0001-01-01", ts) + } + if ts.Seconds >= maxValidSeconds { + return fmt.Errorf("timestamp: %v after 10000-01-01", ts) + } + if ts.Nanos < 0 || ts.Nanos >= 1e9 { + return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts) + } + return nil +} diff --git a/pkg/golang-protobuf/ptypes/timestamp/timestamp.pb.go b/pkg/golang-protobuf/ptypes/timestamp/timestamp.pb.go new file mode 100644 index 000000000..a76f80760 --- /dev/null +++ b/pkg/golang-protobuf/ptypes/timestamp/timestamp.pb.go @@ -0,0 +1,64 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: github.com/golang/protobuf/ptypes/timestamp/timestamp.proto + +package timestamp + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" +) + +// Symbols defined in public import of google/protobuf/timestamp.proto. + +type Timestamp = timestamppb.Timestamp + +var File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto protoreflect.FileDescriptor + +var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc = []byte{ + 0x0a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, + 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2f, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x37, + 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, + 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x3b, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = []interface{}{} +var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init() } +func file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init() { + if File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes, + DependencyIndexes: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs, + }.Build() + File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto = out.File + file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc = nil + file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = nil + file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = nil +} diff --git a/pkg/golang-protobuf/ptypes/timestamp_test.go b/pkg/golang-protobuf/ptypes/timestamp_test.go new file mode 100644 index 000000000..07efdfd82 --- /dev/null +++ b/pkg/golang-protobuf/ptypes/timestamp_test.go @@ -0,0 +1,126 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ptypes + +import ( + "math" + "testing" + "time" + + "github.com/golang/protobuf/proto" + + tspb "github.com/golang/protobuf/ptypes/timestamp" +) + +var tests = []struct { + ts *tspb.Timestamp + valid bool + t time.Time +}{ + // The timestamp representing the Unix epoch date. + {&tspb.Timestamp{Seconds: 0, Nanos: 0}, true, utcDate(1970, 1, 1)}, + // The smallest representable timestamp. + {&tspb.Timestamp{Seconds: math.MinInt64, Nanos: math.MinInt32}, false, + time.Unix(math.MinInt64, math.MinInt32).UTC()}, + // The smallest representable timestamp with non-negative nanos. + {&tspb.Timestamp{Seconds: math.MinInt64, Nanos: 0}, false, time.Unix(math.MinInt64, 0).UTC()}, + // The earliest valid timestamp. + {&tspb.Timestamp{Seconds: minValidSeconds, Nanos: 0}, true, utcDate(1, 1, 1)}, + //"0001-01-01T00:00:00Z"}, + // The largest representable timestamp. + {&tspb.Timestamp{Seconds: math.MaxInt64, Nanos: math.MaxInt32}, false, + time.Unix(math.MaxInt64, math.MaxInt32).UTC()}, + // The largest representable timestamp with nanos in range. + {&tspb.Timestamp{Seconds: math.MaxInt64, Nanos: 1e9 - 1}, false, + time.Unix(math.MaxInt64, 1e9-1).UTC()}, + // The largest valid timestamp. + {&tspb.Timestamp{Seconds: maxValidSeconds - 1, Nanos: 1e9 - 1}, true, + time.Date(9999, 12, 31, 23, 59, 59, 1e9-1, time.UTC)}, + // The smallest invalid timestamp that is larger than the valid range. + {&tspb.Timestamp{Seconds: maxValidSeconds, Nanos: 0}, false, time.Unix(maxValidSeconds, 0).UTC()}, + // A date before the epoch. + {&tspb.Timestamp{Seconds: -281836800, Nanos: 0}, true, utcDate(1961, 1, 26)}, + // A date after the epoch. + {&tspb.Timestamp{Seconds: 1296000000, Nanos: 0}, true, utcDate(2011, 1, 26)}, + // A date after the epoch, in the middle of the day. + {&tspb.Timestamp{Seconds: 1296012345, Nanos: 940483}, true, + time.Date(2011, 1, 26, 3, 25, 45, 940483, time.UTC)}, +} + +func TestValidateTimestamp(t *testing.T) { + for _, s := range tests { + got := validateTimestamp(s.ts) + if (got == nil) != s.valid { + t.Errorf("validateTimestamp(%v) = %v, want %v", s.ts, got, s.valid) + } + } +} + +func TestTimestamp(t *testing.T) { + for _, s := range tests { + got, err := Timestamp(s.ts) + if (err == nil) != s.valid { + t.Errorf("Timestamp(%v) error = %v, but valid = %t", s.ts, err, s.valid) + } else if s.valid && got != s.t { + t.Errorf("Timestamp(%v) = %v, want %v", s.ts, got, s.t) + } + } + // Special case: a nil Timestamp is an error, but returns the 0 Unix time. + got, err := Timestamp(nil) + want := time.Unix(0, 0).UTC() + if got != want { + t.Errorf("Timestamp(nil) = %v, want %v", got, want) + } + if err == nil { + t.Errorf("Timestamp(nil) error = nil, expected error") + } +} + +func TestTimestampProto(t *testing.T) { + for _, s := range tests { + got, err := TimestampProto(s.t) + if (err == nil) != s.valid { + t.Errorf("TimestampProto(%v) error = %v, but valid = %t", s.t, err, s.valid) + } else if s.valid && !proto.Equal(got, s.ts) { + t.Errorf("TimestampProto(%v) = %v, want %v", s.t, got, s.ts) + } + } + // No corresponding special case here: no time.Time results in a nil Timestamp. +} + +func TestTimestampString(t *testing.T) { + for _, test := range []struct { + ts *tspb.Timestamp + want string + }{ + // Not much testing needed because presumably time.Format is + // well-tested. + {&tspb.Timestamp{Seconds: 0, Nanos: 0}, "1970-01-01T00:00:00Z"}, + } { + got := TimestampString(test.ts) + if got != test.want { + t.Errorf("TimestampString(%v) = %q, want %q", test.ts, got, test.want) + } + } +} + +func utcDate(year, month, day int) time.Time { + return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC) +} + +func TestTimestampNow(t *testing.T) { + // Bracket the expected time. + before := time.Now() + ts := TimestampNow() + after := time.Now() + + tm, err := Timestamp(ts) + if err != nil { + t.Errorf("between %v and %v\nTimestampNow() = %v\nwhich is invalid (%v)", before, after, ts, err) + } + if tm.Before(before) || tm.After(after) { + t.Errorf("between %v and %v\nTimestamp(TimestampNow()) = %v", before, after, tm) + } +} diff --git a/pkg/golang-protobuf/ptypes/wrappers/wrappers.pb.go b/pkg/golang-protobuf/ptypes/wrappers/wrappers.pb.go new file mode 100644 index 000000000..cc40f27ad --- /dev/null +++ b/pkg/golang-protobuf/ptypes/wrappers/wrappers.pb.go @@ -0,0 +1,71 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: github.com/golang/protobuf/ptypes/wrappers/wrappers.proto + +package wrappers + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" +) + +// Symbols defined in public import of google/protobuf/wrappers.proto. + +type DoubleValue = wrapperspb.DoubleValue +type FloatValue = wrapperspb.FloatValue +type Int64Value = wrapperspb.Int64Value +type UInt64Value = wrapperspb.UInt64Value +type Int32Value = wrapperspb.Int32Value +type UInt32Value = wrapperspb.UInt32Value +type BoolValue = wrapperspb.BoolValue +type StringValue = wrapperspb.StringValue +type BytesValue = wrapperspb.BytesValue + +var File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto protoreflect.FileDescriptor + +var file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawDesc = []byte{ + 0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, + 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2f, 0x77, 0x72, 0x61, + 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, + 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x35, 0x5a, 0x33, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x3b, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, + 0x72, 0x73, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_goTypes = []interface{}{} +var file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_init() } +func file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_init() { + if File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_goTypes, + DependencyIndexes: file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_depIdxs, + }.Build() + File_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto = out.File + file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_rawDesc = nil + file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_goTypes = nil + file_github_com_golang_protobuf_ptypes_wrappers_wrappers_proto_depIdxs = nil +} diff --git a/pkg/golang-protobuf/regenerate.bash b/pkg/golang-protobuf/regenerate.bash new file mode 100755 index 000000000..f6c35c5af --- /dev/null +++ b/pkg/golang-protobuf/regenerate.bash @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright 2018 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +cd "$(git rev-parse --show-toplevel)" +set -e +go run ./internal/cmd/generate-alias -execute +go test ./protoc-gen-go -regenerate diff --git a/pkg/golang-protobuf/test.bash b/pkg/golang-protobuf/test.bash new file mode 100755 index 000000000..c213adebd --- /dev/null +++ b/pkg/golang-protobuf/test.bash @@ -0,0 +1,41 @@ +#!/bin/bash +# Copyright 2018 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +cd "$(git rev-parse --show-toplevel)" + +BOLD="\x1b[1mRunning: " +PASS="\x1b[32mPASS" +FAIL="\x1b[31mFAIL" +RESET="\x1b[0m" + +echo -e "${BOLD}go test ./...${RESET}" +RET_TEST0=$(go test ./... | egrep -v "^(ok|[?])\s+") +if [[ ! -z "$RET_TEST0" ]]; then echo "$RET_TEST0"; echo; fi + +echo -e "${BOLD}go test -tags purego ./...${RESET}" +RET_TEST1=$(go test -tags purego ./... | egrep -v "^(ok|[?])\s+") +if [[ ! -z "$RET_TEST1" ]]; then echo "$RET_TEST1"; echo; fi + +echo -e "${BOLD}go generate${RESET}" +RET_GEN=$(go run ./internal/cmd/generate-alias 2>&1) +if [[ ! -z "$RET_GEN" ]]; then echo "$RET_GEN"; echo; fi + +echo -e "${BOLD}go fmt${RESET}" +RET_FMT=$(gofmt -d $(git ls-files *.go) 2>&1) +if [[ ! -z "$RET_FMT" ]]; then echo "$RET_FMT"; echo; fi + +echo -e "${BOLD}git diff${RESET}" +RET_DIFF=$(git diff --no-prefix HEAD 2>&1) +if [[ ! -z "$RET_DIFF" ]]; then echo "$RET_DIFF"; echo; fi + +echo -e "${BOLD}git ls-files${RESET}" +RET_FILES=$(git ls-files --others --exclude-standard 2>&1) +if [[ ! -z "$RET_FILES" ]]; then echo "$RET_FILES"; echo; fi + +if [[ ! -z "$RET_TEST0" ]] || [[ ! -z "$RET_TEST1" ]] || [[ ! -z "$RET_GEN" ]] || [ ! -z "$RET_FMT" ] || [[ ! -z "$RET_DIFF" ]] || [[ ! -z "$RET_FILES" ]]; then + echo -e "${FAIL}${RESET}"; exit 1 +else + echo -e "${PASS}${RESET}"; exit 0 +fi diff --git a/plugins/notifications/dummy/go.mod b/plugins/notifications/dummy/go.mod new file mode 100644 index 000000000..0899c9a8b --- /dev/null +++ b/plugins/notifications/dummy/go.mod @@ -0,0 +1,28 @@ +module github.com/crowdsecurity/dummy-plugin + +go 1.19 + +require ( + github.com/crowdsecurity/crowdsec v1.4.1 + github.com/hashicorp/go-hclog v1.3.1 + github.com/hashicorp/go-plugin v1.4.5 + gopkg.in/yaml.v2 v2.4.0 +) + +require ( + github.com/fatih/color v1.13.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mitchellh/go-testing-interface v1.0.0 // indirect + github.com/oklog/run v1.0.0 // indirect + golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2 // indirect + golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a // indirect + golang.org/x/text v0.3.7 // indirect + google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4 // indirect + google.golang.org/grpc v1.45.0 // indirect + google.golang.org/protobuf v1.28.0 // indirect +) + +replace github.com/golang/protobuf => ../../../pkg/golang-protobuf \ No newline at end of file diff --git a/plugins/notifications/dummy/go.sum b/plugins/notifications/dummy/go.sum new file mode 100644 index 000000000..0c2a50bd8 --- /dev/null +++ b/plugins/notifications/dummy/go.sum @@ -0,0 +1,169 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/crowdsecurity/crowdsec v1.4.1 h1:GNmOO3Thh710hSYEW0H+7BJCkMsrpafnM6et4cezxAc= +github.com/crowdsecurity/crowdsec v1.4.1/go.mod h1:du34G8w0vTwVucLoPoI5s1SiZoA7a8ZDAYlzV0ZInRM= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/go-hclog v1.3.1 h1:vDwF1DFNZhntP4DAjuTpOw3uEgMUpXh1pB5fW9DqHpo= +github.com/hashicorp/go-hclog v1.3.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-plugin v1.4.5 h1:oTE/oQR4eghggRg8VY7PAz3dr++VwDNBGCcOfIvHpBo= +github.com/hashicorp/go-plugin v1.4.5/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2 h1:6mzvA99KwZxbOrxww4EvWVQUnN1+xEu9tafK5ZxkYeA= +golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a h1:N2T1jUrTQE9Re6TFF5PhvEHXHCguynGhKjWVsIUt5cY= +golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4 h1:myaecH64R0bIEDjNORIel4iXubqzaHU1K2z8ajBwWcM= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/plugins/notifications/email/go.mod b/plugins/notifications/email/go.mod index 3d374e6a3..590289a3b 100644 --- a/plugins/notifications/email/go.mod +++ b/plugins/notifications/email/go.mod @@ -25,3 +25,5 @@ require ( google.golang.org/grpc v1.45.0 // indirect google.golang.org/protobuf v1.28.0 // indirect ) + +replace github.com/golang/protobuf => ../../../pkg/golang-protobuf \ No newline at end of file diff --git a/plugins/notifications/http/go.mod b/plugins/notifications/http/go.mod index dc3c68c69..30c418299 100644 --- a/plugins/notifications/http/go.mod +++ b/plugins/notifications/http/go.mod @@ -24,3 +24,5 @@ require ( google.golang.org/grpc v1.45.0 // indirect google.golang.org/protobuf v1.28.0 // indirect ) + +replace github.com/golang/protobuf => ../../../pkg/golang-protobuf \ No newline at end of file diff --git a/plugins/notifications/slack/go.mod b/plugins/notifications/slack/go.mod index 8f415c85a..d22566f2a 100644 --- a/plugins/notifications/slack/go.mod +++ b/plugins/notifications/slack/go.mod @@ -27,3 +27,5 @@ require ( google.golang.org/grpc v1.45.0 // indirect google.golang.org/protobuf v1.28.0 // indirect ) + +replace github.com/golang/protobuf => ../../../pkg/golang-protobuf \ No newline at end of file diff --git a/plugins/notifications/splunk/go.mod b/plugins/notifications/splunk/go.mod index 9283808bc..39fbcd995 100644 --- a/plugins/notifications/splunk/go.mod +++ b/plugins/notifications/splunk/go.mod @@ -24,3 +24,5 @@ require ( google.golang.org/grpc v1.45.0 // indirect google.golang.org/protobuf v1.28.0 // indirect ) + +replace github.com/golang/protobuf => ../../../pkg/golang-protobuf \ No newline at end of file