update vendor/ dir to latest w/o heroku, moby

had to lock a lot of things in place
This commit is contained in:
Reed Allman
2017-08-03 02:38:15 -07:00
parent 780791da1c
commit 30f3c45dbc
5637 changed files with 191713 additions and 1133103 deletions

View File

@@ -1,6 +1,5 @@
.DS_Store
*.[568ao]
*.pb.go
*.ao
*.so
*.pyc
@@ -13,5 +12,5 @@ core
_obj
_test
_testmain.go
compiler/protoc-gen-go
compiler/testdata/extension_test
protoc-gen-go/testdata/multi/*.pb.go
_conformance/_conformance

17
vendor/github.com/golang/protobuf/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,17 @@
sudo: false
language: go
go:
- 1.6.x
- 1.7.x
- 1.8.x
install:
- go get -v -d -t github.com/golang/protobuf/...
- curl -L https://github.com/google/protobuf/releases/download/v3.3.0/protoc-3.3.0-linux-x86_64.zip -o /tmp/protoc.zip
- unzip /tmp/protoc.zip -d $HOME/protoc
env:
- PATH=$HOME/protoc/bin:$PATH
script:
- make all test

View File

@@ -33,13 +33,11 @@
all: install
install:
go install ./proto
go install ./jsonpb
go install ./proto ./jsonpb ./ptypes
go install ./protoc-gen-go
test:
go test ./proto
go test ./jsonpb
go test ./proto ./jsonpb ./ptypes
make -C protoc-gen-go/testdata test
clean:
@@ -54,3 +52,4 @@ regenerate:
make -C protoc-gen-go/testdata regenerate
make -C proto/testdata regenerate
make -C jsonpb/jsonpb_test_proto regenerate
make -C _conformance regenerate

View File

@@ -1,5 +1,7 @@
# Go support for Protocol Buffers
[![Build Status](https://travis-ci.org/golang/protobuf.svg?branch=master)](https://travis-ci.org/golang/protobuf)
Google's data interchange format.
Copyright 2010 The Go Authors.
https://github.com/golang/protobuf
@@ -22,7 +24,7 @@ To use this software, you must:
for details or, if you are using gccgo, follow the instructions at
https://golang.org/doc/install/gccgo
- Grab the code from the repository and install the proto package.
The simplest way is to run `go get -u github.com/golang/protobuf/{proto,protoc-gen-go}`.
The simplest way is to run `go get -u github.com/golang/protobuf/protoc-gen-go`.
The compiler plugin, protoc-gen-go, will be installed in $GOBIN,
defaulting to $GOPATH/bin. It must be in your $PATH for the protocol
compiler, protoc, to find it.
@@ -104,7 +106,6 @@ for a protocol buffer variable v:
When the .proto file specifies `syntax="proto3"`, there are some differences:
- Non-repeated fields of non-message type are values instead of pointers.
- Getters are only generated for message and oneof fields.
- Enum types do not get an Enum method.
Consider file test.proto, containing
@@ -140,6 +141,7 @@ To create and play with a Test object from the example package,
test := &example.Test {
Label: proto.String("hello"),
Type: proto.Int32(17),
Reps: []int64{1, 2, 3},
Optionalgroup: &example.Test_OptionalGroup {
RequiredField: proto.String("good bye"),
},
@@ -190,3 +192,51 @@ the `plugins` parameter to protoc-gen-go; the usual way is to insert it into
the --go_out argument to protoc:
protoc --go_out=plugins=grpc:. *.proto
## Compatibility ##
The library 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 security issues.
- Unspecified behavior. There are some aspects of the Protocol Buffers
specification that are undefined. Programs that depend on such unspecified
behavior may break in future releases.
- Specification errors or changes. If it becomes necessary to address an
inconsistency, incompleteness, or change in the Protocol Buffers
specification, resolving the issue could affect the meaning or legality of
existing programs. We reserve the right to address such issues, including
updating the implementations.
- Bugs. If the library has a bug that violates the specification, a program
that depends on the buggy behavior may break if the bug is fixed. We reserve
the right to fix such bugs.
- Adding methods or fields to generated structs. These may conflict with field
names that already exist in a schema, causing applications to break. When the
code generator encounters a field in the schema that would collide with a
generated field or method name, the code generator will append an underscore
to the generated field or method name.
- Adding, removing, or changing methods or fields in generated structs that
start with `XXX`. These parts of the generated code are exported out of
necessity, but should not be considered part of the public API.
- Adding, removing, or changing unexported symbols in generated code.
Any breaking changes outside of these will be announced 6 months in advance to
protobuf@googlegroups.com.
You should, whenever possible, use generated code created by the `protoc-gen-go`
tool built at the same commit as the `proto` package. The `proto` package
declares package-level constants in the form `ProtoPackageIsVersionX`.
Application code and generated code may depend on one of these constants to
ensure that compilation will fail if the available version of the proto library
is too old. Whenever we make a change to the generated code that requires newer
library support, in the same commit we will increment the version number of the
generated code and declare a new package-level constant whose name incorporates
the latest version number. Removing a compatibility constant is considered a
breaking change and would be subject to the announcement policy stated above.
The `protoc-gen-go/generator` package exposes a plugin interface,
which is used by the gRPC code generation. This interface is not
supported and is subject to incompatible changes without notice.

View File

@@ -0,0 +1,33 @@
# Go support for Protocol Buffers - Google's data interchange format
#
# Copyright 2016 The Go Authors. All rights reserved.
# https://github.com/golang/protobuf
#
# 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.
regenerate:
protoc --go_out=Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any,Mgoogle/protobuf/duration.proto=github.com/golang/protobuf/ptypes/duration,Mgoogle/protobuf/struct.proto=github.com/golang/protobuf/ptypes/struct,Mgoogle/protobuf/timestamp.proto=github.com/golang/protobuf/ptypes/timestamp,Mgoogle/protobuf/wrappers.proto=github.com/golang/protobuf/ptypes/wrappers,Mgoogle/protobuf/field_mask.proto=google.golang.org/genproto/protobuf:. conformance_proto/conformance.proto

View File

@@ -0,0 +1,161 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// 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.
// conformance implements the conformance test subprocess protocol as
// documented in conformance.proto.
package main
import (
"encoding/binary"
"fmt"
"io"
"os"
pb "github.com/golang/protobuf/_conformance/conformance_proto"
"github.com/golang/protobuf/jsonpb"
"github.com/golang/protobuf/proto"
)
func main() {
var sizeBuf [4]byte
inbuf := make([]byte, 0, 4096)
outbuf := proto.NewBuffer(nil)
for {
if _, err := io.ReadFull(os.Stdin, sizeBuf[:]); err == io.EOF {
break
} else if err != nil {
fmt.Fprintln(os.Stderr, "go conformance: read request:", err)
os.Exit(1)
}
size := binary.LittleEndian.Uint32(sizeBuf[:])
if int(size) > cap(inbuf) {
inbuf = make([]byte, size)
}
inbuf = inbuf[:size]
if _, err := io.ReadFull(os.Stdin, inbuf); err != nil {
fmt.Fprintln(os.Stderr, "go conformance: read request:", err)
os.Exit(1)
}
req := new(pb.ConformanceRequest)
if err := proto.Unmarshal(inbuf, req); err != nil {
fmt.Fprintln(os.Stderr, "go conformance: parse request:", err)
os.Exit(1)
}
res := handle(req)
if err := outbuf.Marshal(res); err != nil {
fmt.Fprintln(os.Stderr, "go conformance: marshal response:", err)
os.Exit(1)
}
binary.LittleEndian.PutUint32(sizeBuf[:], uint32(len(outbuf.Bytes())))
if _, err := os.Stdout.Write(sizeBuf[:]); err != nil {
fmt.Fprintln(os.Stderr, "go conformance: write response:", err)
os.Exit(1)
}
if _, err := os.Stdout.Write(outbuf.Bytes()); err != nil {
fmt.Fprintln(os.Stderr, "go conformance: write response:", err)
os.Exit(1)
}
outbuf.Reset()
}
}
var jsonMarshaler = jsonpb.Marshaler{
OrigName: true,
}
func handle(req *pb.ConformanceRequest) *pb.ConformanceResponse {
var err error
var msg pb.TestAllTypes
switch p := req.Payload.(type) {
case *pb.ConformanceRequest_ProtobufPayload:
err = proto.Unmarshal(p.ProtobufPayload, &msg)
case *pb.ConformanceRequest_JsonPayload:
err = jsonpb.UnmarshalString(p.JsonPayload, &msg)
if err != nil && err.Error() == "unmarshaling Any not supported yet" {
return &pb.ConformanceResponse{
Result: &pb.ConformanceResponse_Skipped{
Skipped: err.Error(),
},
}
}
default:
return &pb.ConformanceResponse{
Result: &pb.ConformanceResponse_RuntimeError{
RuntimeError: "unknown request payload type",
},
}
}
if err != nil {
return &pb.ConformanceResponse{
Result: &pb.ConformanceResponse_ParseError{
ParseError: err.Error(),
},
}
}
switch req.RequestedOutputFormat {
case pb.WireFormat_PROTOBUF:
p, err := proto.Marshal(&msg)
if err != nil {
return &pb.ConformanceResponse{
Result: &pb.ConformanceResponse_SerializeError{
SerializeError: err.Error(),
},
}
}
return &pb.ConformanceResponse{
Result: &pb.ConformanceResponse_ProtobufPayload{
ProtobufPayload: p,
},
}
case pb.WireFormat_JSON:
p, err := jsonMarshaler.MarshalToString(&msg)
if err != nil {
return &pb.ConformanceResponse{
Result: &pb.ConformanceResponse_SerializeError{
SerializeError: err.Error(),
},
}
}
return &pb.ConformanceResponse{
Result: &pb.ConformanceResponse_JsonPayload{
JsonPayload: p,
},
}
default:
return &pb.ConformanceResponse{
Result: &pb.ConformanceResponse_RuntimeError{
RuntimeError: "unknown output format",
},
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,285 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
syntax = "proto3";
package conformance;
option java_package = "com.google.protobuf.conformance";
import "google/protobuf/any.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
// This defines the conformance testing protocol. This protocol exists between
// the conformance test suite itself and the code being tested. For each test,
// the suite will send a ConformanceRequest message and expect a
// ConformanceResponse message.
//
// You can either run the tests in two different ways:
//
// 1. in-process (using the interface in conformance_test.h).
//
// 2. as a sub-process communicating over a pipe. Information about how to
// do this is in conformance_test_runner.cc.
//
// Pros/cons of the two approaches:
//
// - running as a sub-process is much simpler for languages other than C/C++.
//
// - running as a sub-process may be more tricky in unusual environments like
// iOS apps, where fork/stdin/stdout are not available.
enum WireFormat {
UNSPECIFIED = 0;
PROTOBUF = 1;
JSON = 2;
}
// Represents a single test case's input. The testee should:
//
// 1. parse this proto (which should always succeed)
// 2. parse the protobuf or JSON payload in "payload" (which may fail)
// 3. if the parse succeeded, serialize the message in the requested format.
message ConformanceRequest {
// The payload (whether protobuf of JSON) is always for a TestAllTypes proto
// (see below).
oneof payload {
bytes protobuf_payload = 1;
string json_payload = 2;
}
// Which format should the testee serialize its message to?
WireFormat requested_output_format = 3;
}
// Represents a single test case's output.
message ConformanceResponse {
oneof result {
// This string should be set to indicate parsing failed. The string can
// provide more information about the parse error if it is available.
//
// Setting this string does not necessarily mean the testee failed the
// test. Some of the test cases are intentionally invalid input.
string parse_error = 1;
// If the input was successfully parsed but errors occurred when
// serializing it to the requested output format, set the error message in
// this field.
string serialize_error = 6;
// This should be set if some other error occurred. This will always
// indicate that the test failed. The string can provide more information
// about the failure.
string runtime_error = 2;
// If the input was successfully parsed and the requested output was
// protobuf, serialize it to protobuf and set it in this field.
bytes protobuf_payload = 3;
// If the input was successfully parsed and the requested output was JSON,
// serialize to JSON and set it in this field.
string json_payload = 4;
// For when the testee skipped the test, likely because a certain feature
// wasn't supported, like JSON input/output.
string skipped = 5;
}
}
// This proto includes every type of field in both singular and repeated
// forms.
message TestAllTypes {
message NestedMessage {
int32 a = 1;
TestAllTypes corecursive = 2;
}
enum NestedEnum {
FOO = 0;
BAR = 1;
BAZ = 2;
NEG = -1; // Intentionally negative.
}
// Singular
int32 optional_int32 = 1;
int64 optional_int64 = 2;
uint32 optional_uint32 = 3;
uint64 optional_uint64 = 4;
sint32 optional_sint32 = 5;
sint64 optional_sint64 = 6;
fixed32 optional_fixed32 = 7;
fixed64 optional_fixed64 = 8;
sfixed32 optional_sfixed32 = 9;
sfixed64 optional_sfixed64 = 10;
float optional_float = 11;
double optional_double = 12;
bool optional_bool = 13;
string optional_string = 14;
bytes optional_bytes = 15;
NestedMessage optional_nested_message = 18;
ForeignMessage optional_foreign_message = 19;
NestedEnum optional_nested_enum = 21;
ForeignEnum optional_foreign_enum = 22;
string optional_string_piece = 24 [ctype=STRING_PIECE];
string optional_cord = 25 [ctype=CORD];
TestAllTypes recursive_message = 27;
// Repeated
repeated int32 repeated_int32 = 31;
repeated int64 repeated_int64 = 32;
repeated uint32 repeated_uint32 = 33;
repeated uint64 repeated_uint64 = 34;
repeated sint32 repeated_sint32 = 35;
repeated sint64 repeated_sint64 = 36;
repeated fixed32 repeated_fixed32 = 37;
repeated fixed64 repeated_fixed64 = 38;
repeated sfixed32 repeated_sfixed32 = 39;
repeated sfixed64 repeated_sfixed64 = 40;
repeated float repeated_float = 41;
repeated double repeated_double = 42;
repeated bool repeated_bool = 43;
repeated string repeated_string = 44;
repeated bytes repeated_bytes = 45;
repeated NestedMessage repeated_nested_message = 48;
repeated ForeignMessage repeated_foreign_message = 49;
repeated NestedEnum repeated_nested_enum = 51;
repeated ForeignEnum repeated_foreign_enum = 52;
repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
repeated string repeated_cord = 55 [ctype=CORD];
// Map
map < int32, int32> map_int32_int32 = 56;
map < int64, int64> map_int64_int64 = 57;
map < uint32, uint32> map_uint32_uint32 = 58;
map < uint64, uint64> map_uint64_uint64 = 59;
map < sint32, sint32> map_sint32_sint32 = 60;
map < sint64, sint64> map_sint64_sint64 = 61;
map < fixed32, fixed32> map_fixed32_fixed32 = 62;
map < fixed64, fixed64> map_fixed64_fixed64 = 63;
map <sfixed32, sfixed32> map_sfixed32_sfixed32 = 64;
map <sfixed64, sfixed64> map_sfixed64_sfixed64 = 65;
map < int32, float> map_int32_float = 66;
map < int32, double> map_int32_double = 67;
map < bool, bool> map_bool_bool = 68;
map < string, string> map_string_string = 69;
map < string, bytes> map_string_bytes = 70;
map < string, NestedMessage> map_string_nested_message = 71;
map < string, ForeignMessage> map_string_foreign_message = 72;
map < string, NestedEnum> map_string_nested_enum = 73;
map < string, ForeignEnum> map_string_foreign_enum = 74;
oneof oneof_field {
uint32 oneof_uint32 = 111;
NestedMessage oneof_nested_message = 112;
string oneof_string = 113;
bytes oneof_bytes = 114;
bool oneof_bool = 115;
uint64 oneof_uint64 = 116;
float oneof_float = 117;
double oneof_double = 118;
NestedEnum oneof_enum = 119;
}
// Well-known types
google.protobuf.BoolValue optional_bool_wrapper = 201;
google.protobuf.Int32Value optional_int32_wrapper = 202;
google.protobuf.Int64Value optional_int64_wrapper = 203;
google.protobuf.UInt32Value optional_uint32_wrapper = 204;
google.protobuf.UInt64Value optional_uint64_wrapper = 205;
google.protobuf.FloatValue optional_float_wrapper = 206;
google.protobuf.DoubleValue optional_double_wrapper = 207;
google.protobuf.StringValue optional_string_wrapper = 208;
google.protobuf.BytesValue optional_bytes_wrapper = 209;
repeated google.protobuf.BoolValue repeated_bool_wrapper = 211;
repeated google.protobuf.Int32Value repeated_int32_wrapper = 212;
repeated google.protobuf.Int64Value repeated_int64_wrapper = 213;
repeated google.protobuf.UInt32Value repeated_uint32_wrapper = 214;
repeated google.protobuf.UInt64Value repeated_uint64_wrapper = 215;
repeated google.protobuf.FloatValue repeated_float_wrapper = 216;
repeated google.protobuf.DoubleValue repeated_double_wrapper = 217;
repeated google.protobuf.StringValue repeated_string_wrapper = 218;
repeated google.protobuf.BytesValue repeated_bytes_wrapper = 219;
google.protobuf.Duration optional_duration = 301;
google.protobuf.Timestamp optional_timestamp = 302;
google.protobuf.FieldMask optional_field_mask = 303;
google.protobuf.Struct optional_struct = 304;
google.protobuf.Any optional_any = 305;
google.protobuf.Value optional_value = 306;
repeated google.protobuf.Duration repeated_duration = 311;
repeated google.protobuf.Timestamp repeated_timestamp = 312;
repeated google.protobuf.FieldMask repeated_fieldmask = 313;
repeated google.protobuf.Struct repeated_struct = 324;
repeated google.protobuf.Any repeated_any = 315;
repeated google.protobuf.Value repeated_value = 316;
// Test field-name-to-JSON-name convention.
// (protobuf says names can be any valid C/C++ identifier.)
int32 fieldname1 = 401;
int32 field_name2 = 402;
int32 _field_name3 = 403;
int32 field__name4_ = 404;
int32 field0name5 = 405;
int32 field_0_name6 = 406;
int32 fieldName7 = 407;
int32 FieldName8 = 408;
int32 field_Name9 = 409;
int32 Field_Name10 = 410;
int32 FIELD_NAME11 = 411;
int32 FIELD_name12 = 412;
int32 __field_name13 = 413;
int32 __Field_name14 = 414;
int32 field__name15 = 415;
int32 field__Name16 = 416;
int32 field_name17__ = 417;
int32 Field_name18__ = 418;
}
message ForeignMessage {
int32 c = 1;
}
enum ForeignEnum {
FOREIGN_FOO = 0;
FOREIGN_BAR = 1;
FOREIGN_BAZ = 2;
}

View File

@@ -0,0 +1,93 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// 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.
// Package descriptor provides functions for obtaining protocol buffer
// descriptors for generated Go types.
//
// These functions cannot go in package proto because they depend on the
// generated protobuf descriptor messages, which themselves depend on proto.
package descriptor
import (
"bytes"
"compress/gzip"
"fmt"
"io/ioutil"
"github.com/golang/protobuf/proto"
protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor"
)
// extractFile extracts a FileDescriptorProto from a gzip'd buffer.
func extractFile(gz []byte) (*protobuf.FileDescriptorProto, error) {
r, err := gzip.NewReader(bytes.NewReader(gz))
if err != nil {
return nil, fmt.Errorf("failed to open gzip reader: %v", err)
}
defer r.Close()
b, err := ioutil.ReadAll(r)
if err != nil {
return nil, fmt.Errorf("failed to uncompress descriptor: %v", err)
}
fd := new(protobuf.FileDescriptorProto)
if err := proto.Unmarshal(b, fd); err != nil {
return nil, fmt.Errorf("malformed FileDescriptorProto: %v", err)
}
return fd, nil
}
// Message is a proto.Message with a method to return its descriptor.
//
// Message types generated by the protocol compiler always satisfy
// the Message interface.
type Message interface {
proto.Message
Descriptor() ([]byte, []int)
}
// ForMessage returns a FileDescriptorProto and a DescriptorProto from within it
// describing the given message.
func ForMessage(msg Message) (fd *protobuf.FileDescriptorProto, md *protobuf.DescriptorProto) {
gz, path := msg.Descriptor()
fd, err := extractFile(gz)
if err != nil {
panic(fmt.Sprintf("invalid FileDescriptorProto for %T: %v", msg, err))
}
md = fd.MessageType[path[0]]
for _, i := range path[1:] {
md = md.NestedType[i]
}
return fd, md
}

View File

@@ -0,0 +1,32 @@
package descriptor_test
import (
"fmt"
"testing"
"github.com/golang/protobuf/descriptor"
tpb "github.com/golang/protobuf/proto/testdata"
protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor"
)
func TestMessage(t *testing.T) {
var msg *protobuf.DescriptorProto
fd, md := descriptor.ForMessage(msg)
if pkg, want := fd.GetPackage(), "google.protobuf"; pkg != want {
t.Errorf("descriptor.ForMessage(%T).GetPackage() = %q; want %q", msg, pkg, want)
}
if name, want := md.GetName(), "DescriptorProto"; name != want {
t.Fatalf("descriptor.ForMessage(%T).GetName() = %q; want %q", msg, name, want)
}
}
func Example_Options() {
var msg *tpb.MyMessageSet
_, md := descriptor.ForMessage(msg)
if md.GetOptions().GetMessageSetWireFormat() {
fmt.Printf("%v uses option message_set_wire_format.\n", md.GetName())
}
// Output:
// MyMessageSet uses option message_set_wire_format.
}

View File

@@ -30,49 +30,71 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/*
Package jsonpb provides marshaling/unmarshaling functionality between
protocol buffer and JSON objects.
Package jsonpb provides marshaling and unmarshaling between protocol buffers and JSON.
It follows the specification at https://developers.google.com/protocol-buffers/docs/proto3#json.
Compared to encoding/json, this library:
- encodes int64, uint64 as strings
- optionally encodes enums as integers
This package produces a different output than the standard "encoding/json" package,
which does not operate correctly on protocol buffers.
*/
package jsonpb
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"math"
"reflect"
"sort"
"strconv"
"strings"
"time"
"github.com/golang/protobuf/proto"
)
var (
byteArrayType = reflect.TypeOf([]byte{})
stpb "github.com/golang/protobuf/ptypes/struct"
)
// Marshaler is a configurable object for converting between
// protocol buffer objects and a JSON representation for them
// protocol buffer objects and a JSON representation for them.
type Marshaler struct {
// Whether to render enum values as integers, as opposed to string values.
EnumsAsInts bool
// Whether to render fields with zero values.
EmitDefaults bool
// A string to indent each level by. The presence of this field will
// also cause a space to appear between the field separator and
// value, and for newlines to be appear between fields and array
// elements.
Indent string
// Whether to use the original (.proto) name for fields.
OrigName bool
}
// 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.
type JSONPBMarshaler interface {
MarshalJSONPB(*Marshaler) ([]byte, error)
}
// 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.
type JSONPBUnmarshaler interface {
UnmarshalJSONPB(*Unmarshaler, []byte) error
}
// Marshal marshals a protocol buffer into JSON.
func (m *Marshaler) Marshal(out io.Writer, pb proto.Message) error {
writer := &errWriter{writer: out}
return m.marshalObject(writer, pb, "")
return m.marshalObject(writer, pb, "", "")
}
// MarshalToString converts a protocol buffer object to JSON string.
@@ -86,20 +108,119 @@ func (m *Marshaler) MarshalToString(pb proto.Message) (string, error) {
type int32Slice []int32
var nonFinite = map[string]float64{
`"NaN"`: math.NaN(),
`"Infinity"`: math.Inf(1),
`"-Infinity"`: math.Inf(-1),
}
// For sorting extensions ids to ensure stable output.
func (s int32Slice) Len() int { return len(s) }
func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
type wkt interface {
XXX_WellKnownType() string
}
// marshalObject writes a struct to the Writer.
func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent string) error {
func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent, typeURL string) error {
if jsm, ok := v.(JSONPBMarshaler); ok {
b, err := jsm.MarshalJSONPB(m)
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", v, 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
}
}
out.write(string(b))
return out.err
}
s := reflect.ValueOf(v).Elem()
// Handle well-known types.
if wkt, ok := v.(wkt); ok {
switch wkt.XXX_WellKnownType() {
case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value",
"Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue":
// "Wrappers use the same representation in JSON
// as the wrapped primitive type, ..."
sprop := proto.GetProperties(s.Type())
return m.marshalValue(out, sprop.Prop[0], s.Field(0), indent)
case "Any":
// Any is a bit more involved.
return m.marshalAny(out, v, indent)
case "Duration":
// "Generated output always contains 3, 6, or 9 fractional digits,
// depending on required precision."
s, ns := s.Field(0).Int(), s.Field(1).Int()
d := time.Duration(s)*time.Second + time.Duration(ns)*time.Nanosecond
x := fmt.Sprintf("%.9f", d.Seconds())
x = strings.TrimSuffix(x, "000")
x = strings.TrimSuffix(x, "000")
out.write(`"`)
out.write(x)
out.write(`s"`)
return out.err
case "Struct", "ListValue":
// Let marshalValue handle the `Struct.fields` map or the `ListValue.values` slice.
// TODO: pass the correct Properties if needed.
return m.marshalValue(out, &proto.Properties{}, s.Field(0), indent)
case "Timestamp":
// "RFC 3339, where generated output will always be Z-normalized
// and uses 3, 6 or 9 fractional digits."
s, ns := s.Field(0).Int(), s.Field(1).Int()
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")
out.write(`"`)
out.write(x)
out.write(`Z"`)
return out.err
case "Value":
// Value has a single oneof.
kind := s.Field(0)
if kind.IsNil() {
// "absence of any variant indicates an error"
return errors.New("nil Value")
}
// oneof -> *T -> T -> T.F
x := kind.Elem().Elem().Field(0)
// TODO: pass the correct Properties if needed.
return m.marshalValue(out, &proto.Properties{}, x, indent)
}
}
out.write("{")
if m.Indent != "" {
out.write("\n")
}
s := reflect.ValueOf(v).Elem()
firstField := true
if typeURL != "" {
if err := m.marshalTypeURL(out, indent, typeURL); err != nil {
return err
}
firstField = false
}
for i := 0; i < s.NumField(); i++ {
value := s.Field(i)
valueField := s.Type().Field(i)
@@ -107,16 +228,43 @@ func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent string
continue
}
// TODO: proto3 objects should have default values omitted.
// IsNil will panic on most value kinds.
switch value.Kind() {
case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
case reflect.Chan, reflect.Func, reflect.Interface:
if value.IsNil() {
continue
}
}
if !m.EmitDefaults {
switch value.Kind() {
case reflect.Bool:
if !value.Bool() {
continue
}
case reflect.Int32, reflect.Int64:
if value.Int() == 0 {
continue
}
case reflect.Uint32, reflect.Uint64:
if value.Uint() == 0 {
continue
}
case reflect.Float32, reflect.Float64:
if value.Float() == 0 {
continue
}
case reflect.String:
if value.Len() == 0 {
continue
}
case reflect.Map, reflect.Ptr, reflect.Slice:
if value.IsNil() {
continue
}
}
}
// Oneof fields need special handling.
if valueField.Tag.Get("protobuf_oneof") != "" {
// value is an interface containing &T{real_value}.
@@ -124,7 +272,7 @@ func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent string
value = sv.Field(0)
valueField = sv.Type().Field(0)
}
prop := jsonProperties(valueField)
prop := jsonProperties(valueField, m.OrigName)
if !firstField {
m.writeSep(out)
}
@@ -135,12 +283,14 @@ func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent string
}
// Handle proto2 extensions.
if ep, ok := v.(extendableProto); ok {
if ep, ok := v.(proto.Message); ok {
extensions := proto.RegisteredExtensions(v)
extensionMap := ep.ExtensionMap()
// Sort extensions for stable output.
ids := make([]int32, 0, len(extensionMap))
for id := range extensionMap {
ids := make([]int32, 0, len(extensions))
for id, desc := range extensions {
if !proto.HasExtension(ep, desc) {
continue
}
ids = append(ids, id)
}
sort.Sort(int32Slice(ids))
@@ -157,7 +307,7 @@ func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent string
value := reflect.ValueOf(ext)
var prop proto.Properties
prop.Parse(desc.Tag)
prop.OrigName = fmt.Sprintf("[%s]", desc.Name)
prop.JSONName = fmt.Sprintf("[%s]", desc.Name)
if !firstField {
m.writeSep(out)
}
@@ -185,6 +335,76 @@ func (m *Marshaler) writeSep(out *errWriter) {
}
}
func (m *Marshaler) marshalAny(out *errWriter, any proto.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."
v := reflect.ValueOf(any).Elem()
turl := v.Field(0).String()
val := v.Field(1).Bytes()
// Only the part of type_url after the last slash is relevant.
mname := turl
if slash := strings.LastIndex(mname, "/"); slash >= 0 {
mname = mname[slash+1:]
}
mt := proto.MessageType(mname)
if mt == nil {
return fmt.Errorf("unknown message type %q", mname)
}
msg := reflect.New(mt.Elem()).Interface().(proto.Message)
if err := proto.Unmarshal(val, msg); err != nil {
return err
}
if _, ok := msg.(wkt); ok {
out.write("{")
if m.Indent != "" {
out.write("\n")
}
if err := m.marshalTypeURL(out, indent, turl); err != nil {
return err
}
m.writeSep(out)
if m.Indent != "" {
out.write(indent)
out.write(m.Indent)
out.write(`"value": `)
} else {
out.write(`"value":`)
}
if err := m.marshalObject(out, msg, indent+m.Indent, ""); err != nil {
return err
}
if m.Indent != "" {
out.write("\n")
out.write(indent)
}
out.write("}")
return out.err
}
return m.marshalObject(out, msg, indent, turl)
}
func (m *Marshaler) marshalTypeURL(out *errWriter, indent, typeURL string) error {
if m.Indent != "" {
out.write(indent)
out.write(m.Indent)
}
out.write(`"@type":`)
if m.Indent != "" {
out.write(" ")
}
b, err := json.Marshal(typeURL)
if err != nil {
return err
}
out.write(string(b))
return out.err
}
// marshalField writes field description and value to the Writer.
func (m *Marshaler) marshalField(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error {
if m.Indent != "" {
@@ -192,7 +412,7 @@ func (m *Marshaler) marshalField(out *errWriter, prop *proto.Properties, v refle
out.write(m.Indent)
}
out.write(`"`)
out.write(prop.OrigName)
out.write(prop.JSONName)
out.write(`":`)
if m.Indent != "" {
out.write(" ")
@@ -205,12 +425,17 @@ func (m *Marshaler) marshalField(out *errWriter, prop *proto.Properties, v refle
// marshalValue writes the value to the Writer.
func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error {
var err error
v = reflect.Indirect(v)
// Handle nil pointer
if v.Kind() == reflect.Invalid {
out.write("null")
return out.err
}
// Handle repeated elements.
if v.Type() != byteArrayType && v.Kind() == reflect.Slice {
if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 {
out.write("[")
comma := ""
for i := 0; i < v.Len(); i++ {
@@ -222,7 +447,9 @@ func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v refle
out.write(m.Indent)
out.write(m.Indent)
}
m.marshalValue(out, prop, sliceVal, indent+m.Indent)
if err := m.marshalValue(out, prop, sliceVal, indent+m.Indent); err != nil {
return err
}
comma = ","
}
if m.Indent != "" {
@@ -234,6 +461,16 @@ func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v refle
return out.err
}
// Handle well-known types.
// Most are handled up in marshalObject (because 99% are messages).
if wkt, ok := v.Interface().(wkt); ok {
switch wkt.XXX_WellKnownType() {
case "NullValue":
out.write("null")
return out.err
}
}
// Handle enumerations.
if !m.EnumsAsInts && prop.Enum != "" {
// Unknown enum values will are stringified by the proto library as their
@@ -259,7 +496,7 @@ func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v refle
// Handle nested messages.
if v.Kind() == reflect.Struct {
return m.marshalObject(out, v.Addr().Interface().(proto.Message), indent+m.Indent)
return m.marshalObject(out, v.Addr().Interface().(proto.Message), indent+m.Indent, "")
}
// Handle maps.
@@ -313,6 +550,24 @@ func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v refle
return out.err
}
// Handle non-finite floats, e.g. NaN, Infinity and -Infinity.
if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {
f := v.Float()
var sval string
switch {
case math.IsInf(f, 1):
sval = `"Infinity"`
case math.IsInf(f, -1):
sval = `"-Infinity"`
case math.IsNaN(f):
sval = `"NaN"`
}
if sval != "" {
out.write(sval)
return out.err
}
}
// Default handling defers to the encoding/json library.
b, err := json.Marshal(v.Interface())
if err != nil {
@@ -329,32 +584,242 @@ func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v refle
return out.err
}
// Unmarshaler is a configurable object for converting from a JSON
// representation to a protocol buffer object.
type Unmarshaler struct {
// Whether to allow messages to contain unknown fields, as opposed to
// failing to unmarshal.
AllowUnknownFields bool
}
// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream.
// This function is lenient and will decode any options permutations of the
// related Marshaler.
func (u *Unmarshaler) UnmarshalNext(dec *json.Decoder, pb proto.Message) error {
inputValue := json.RawMessage{}
if err := dec.Decode(&inputValue); err != nil {
return err
}
return u.unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue, nil)
}
// Unmarshal unmarshals a JSON object stream into a protocol
// buffer. This function is lenient and will decode any options
// permutations of the related Marshaler.
func (u *Unmarshaler) Unmarshal(r io.Reader, pb proto.Message) error {
dec := json.NewDecoder(r)
return u.UnmarshalNext(dec, pb)
}
// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream.
// This function is lenient and will decode any options permutations of the
// related Marshaler.
func UnmarshalNext(dec *json.Decoder, pb proto.Message) error {
return new(Unmarshaler).UnmarshalNext(dec, pb)
}
// Unmarshal unmarshals a JSON object stream into a protocol
// buffer. This function is lenient and will decode any options
// permutations of the related Marshaler.
func Unmarshal(r io.Reader, pb proto.Message) error {
inputValue := json.RawMessage{}
if err := json.NewDecoder(r).Decode(&inputValue); err != nil {
return err
}
return unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue)
return new(Unmarshaler).Unmarshal(r, pb)
}
// UnmarshalString will populate the fields of a protocol buffer based
// on a JSON string. This function is lenient and will decode any options
// permutations of the related Marshaler.
func UnmarshalString(str string, pb proto.Message) error {
return Unmarshal(strings.NewReader(str), pb)
return new(Unmarshaler).Unmarshal(strings.NewReader(str), pb)
}
// unmarshalValue converts/copies a value into the target.
func unmarshalValue(target reflect.Value, inputValue json.RawMessage) error {
// prop may be nil.
func (u *Unmarshaler) unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *proto.Properties) error {
targetType := target.Type()
// Allocate memory for pointer fields.
if targetType.Kind() == reflect.Ptr {
// If input value is "null" and target is a pointer type, then the field should be treated as not set
// UNLESS the target is structpb.Value, in which case it should be set to structpb.NullValue.
if string(inputValue) == "null" && targetType != reflect.TypeOf(&stpb.Value{}) {
return nil
}
target.Set(reflect.New(targetType.Elem()))
return unmarshalValue(target.Elem(), inputValue)
return u.unmarshalValue(target.Elem(), inputValue, prop)
}
if jsu, ok := target.Addr().Interface().(JSONPBUnmarshaler); ok {
return jsu.UnmarshalJSONPB(u, []byte(inputValue))
}
// Handle well-known types that are not pointers.
if w, ok := target.Addr().Interface().(wkt); ok {
switch w.XXX_WellKnownType() {
case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value",
"Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue":
return u.unmarshalValue(target.Field(0), inputValue, prop)
case "Any":
// Use json.RawMessage pointer type instead of value to support pre-1.8 version.
// 1.8 changed RawMessage.MarshalJSON from pointer type to value type, see
// https://github.com/golang/go/issues/14493
var jsonFields map[string]*json.RawMessage
if err := json.Unmarshal(inputValue, &jsonFields); err != nil {
return err
}
val, ok := jsonFields["@type"]
if !ok || val == nil {
return errors.New("Any JSON doesn't have '@type'")
}
var turl string
if err := json.Unmarshal([]byte(*val), &turl); err != nil {
return fmt.Errorf("can't unmarshal Any's '@type': %q", *val)
}
target.Field(0).SetString(turl)
mname := turl
if slash := strings.LastIndex(mname, "/"); slash >= 0 {
mname = mname[slash+1:]
}
mt := proto.MessageType(mname)
if mt == nil {
return fmt.Errorf("unknown message type %q", mname)
}
m := reflect.New(mt.Elem()).Interface().(proto.Message)
if _, ok := m.(wkt); ok {
val, ok := jsonFields["value"]
if !ok {
return errors.New("Any JSON doesn't have 'value'")
}
if err := u.unmarshalValue(reflect.ValueOf(m).Elem(), *val, nil); err != nil {
return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err)
}
} else {
delete(jsonFields, "@type")
nestedProto, err := json.Marshal(jsonFields)
if err != nil {
return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err)
}
if err = u.unmarshalValue(reflect.ValueOf(m).Elem(), nestedProto, nil); err != nil {
return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err)
}
}
b, err := proto.Marshal(m)
if err != nil {
return fmt.Errorf("can't marshal proto %T into Any.Value: %v", m, err)
}
target.Field(1).SetBytes(b)
return nil
case "Duration":
unq, err := strconv.Unquote(string(inputValue))
if err != nil {
return err
}
d, err := time.ParseDuration(unq)
if err != nil {
return fmt.Errorf("bad Duration: %v", err)
}
ns := d.Nanoseconds()
s := ns / 1e9
ns %= 1e9
target.Field(0).SetInt(s)
target.Field(1).SetInt(ns)
return nil
case "Timestamp":
unq, err := strconv.Unquote(string(inputValue))
if err != nil {
return err
}
t, err := time.Parse(time.RFC3339Nano, unq)
if err != nil {
return fmt.Errorf("bad Timestamp: %v", err)
}
target.Field(0).SetInt(t.Unix())
target.Field(1).SetInt(int64(t.Nanosecond()))
return nil
case "Struct":
var m map[string]json.RawMessage
if err := json.Unmarshal(inputValue, &m); err != nil {
return fmt.Errorf("bad StructValue: %v", err)
}
target.Field(0).Set(reflect.ValueOf(map[string]*stpb.Value{}))
for k, jv := range m {
pv := &stpb.Value{}
if err := u.unmarshalValue(reflect.ValueOf(pv).Elem(), jv, prop); err != nil {
return fmt.Errorf("bad value in StructValue for key %q: %v", k, err)
}
target.Field(0).SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(pv))
}
return nil
case "ListValue":
var s []json.RawMessage
if err := json.Unmarshal(inputValue, &s); err != nil {
return fmt.Errorf("bad ListValue: %v", err)
}
target.Field(0).Set(reflect.ValueOf(make([]*stpb.Value, len(s), len(s))))
for i, sv := range s {
if err := u.unmarshalValue(target.Field(0).Index(i), sv, prop); err != nil {
return err
}
}
return nil
case "Value":
ivStr := string(inputValue)
if ivStr == "null" {
target.Field(0).Set(reflect.ValueOf(&stpb.Value_NullValue{}))
} else if v, err := strconv.ParseFloat(ivStr, 0); err == nil {
target.Field(0).Set(reflect.ValueOf(&stpb.Value_NumberValue{v}))
} else if v, err := strconv.Unquote(ivStr); err == nil {
target.Field(0).Set(reflect.ValueOf(&stpb.Value_StringValue{v}))
} else if v, err := strconv.ParseBool(ivStr); err == nil {
target.Field(0).Set(reflect.ValueOf(&stpb.Value_BoolValue{v}))
} else if err := json.Unmarshal(inputValue, &[]json.RawMessage{}); err == nil {
lv := &stpb.ListValue{}
target.Field(0).Set(reflect.ValueOf(&stpb.Value_ListValue{lv}))
return u.unmarshalValue(reflect.ValueOf(lv).Elem(), inputValue, prop)
} else if err := json.Unmarshal(inputValue, &map[string]json.RawMessage{}); err == nil {
sv := &stpb.Struct{}
target.Field(0).Set(reflect.ValueOf(&stpb.Value_StructValue{sv}))
return u.unmarshalValue(reflect.ValueOf(sv).Elem(), inputValue, prop)
} else {
return fmt.Errorf("unrecognized type for Value %q", ivStr)
}
return nil
}
}
// Handle enums, which have an underlying type of int32,
// and may appear as strings.
// The case of an enum appearing as a number is handled
// at the bottom of this function.
if inputValue[0] == '"' && prop != nil && prop.Enum != "" {
vmap := proto.EnumValueMap(prop.Enum)
// Don't need to do unquoting; valid enum names
// are from a limited character set.
s := inputValue[1 : len(inputValue)-1]
n, ok := vmap[string(s)]
if !ok {
return fmt.Errorf("unknown value %q for enum %s", s, prop.Enum)
}
if target.Kind() == reflect.Ptr { // proto2
target.Set(reflect.New(targetType.Elem()))
target = target.Elem()
}
target.SetInt(int64(n))
return nil
}
// Handle nested messages.
@@ -364,59 +829,79 @@ func unmarshalValue(target reflect.Value, inputValue json.RawMessage) error {
return err
}
consumeField := func(prop *proto.Properties) (json.RawMessage, bool) {
// Be liberal in what names we accept; both orig_name and camelName are okay.
fieldNames := acceptedJSONFieldNames(prop)
vOrig, okOrig := jsonFields[fieldNames.orig]
vCamel, okCamel := jsonFields[fieldNames.camel]
if !okOrig && !okCamel {
return nil, false
}
// If, for some reason, both are present in the data, favour the camelName.
var raw json.RawMessage
if okOrig {
raw = vOrig
delete(jsonFields, fieldNames.orig)
}
if okCamel {
raw = vCamel
delete(jsonFields, fieldNames.camel)
}
return raw, true
}
sprops := proto.GetProperties(targetType)
for i := 0; i < target.NumField(); i++ {
ft := target.Type().Field(i)
if strings.HasPrefix(ft.Name, "XXX_") {
continue
}
fieldName := jsonProperties(ft).OrigName
valueForField, ok := jsonFields[fieldName]
valueForField, ok := consumeField(sprops.Prop[i])
if !ok {
continue
}
delete(jsonFields, fieldName)
// Handle enums, which have an underlying type of int32,
// and may appear as strings. We do this while handling
// the struct so we have access to the enum info.
// The case of an enum appearing as a number is handled
// by the recursive call to unmarshalValue.
if enum := sprops.Prop[i].Enum; valueForField[0] == '"' && enum != "" {
vmap := proto.EnumValueMap(enum)
// Don't need to do unquoting; valid enum names
// are from a limited character set.
s := valueForField[1 : len(valueForField)-1]
n, ok := vmap[string(s)]
if !ok {
return fmt.Errorf("unknown value %q for enum %s", s, enum)
}
f := target.Field(i)
if f.Kind() == reflect.Ptr { // proto2
f.Set(reflect.New(f.Type().Elem()))
f = f.Elem()
}
f.SetInt(int64(n))
continue
}
if err := unmarshalValue(target.Field(i), valueForField); err != nil {
if err := u.unmarshalValue(target.Field(i), valueForField, sprops.Prop[i]); err != nil {
return err
}
}
// Check for any oneof fields.
for fname, raw := range jsonFields {
if oop, ok := sprops.OneofTypes[fname]; ok {
if len(jsonFields) > 0 {
for _, oop := range sprops.OneofTypes {
raw, ok := consumeField(oop.Prop)
if !ok {
continue
}
nv := reflect.New(oop.Type.Elem())
target.Field(oop.Field).Set(nv)
if err := unmarshalValue(nv.Elem().Field(0), raw); err != nil {
if err := u.unmarshalValue(nv.Elem().Field(0), raw, oop.Prop); err != nil {
return err
}
delete(jsonFields, fname)
}
}
// Handle proto2 extensions.
if len(jsonFields) > 0 {
if ep, ok := target.Addr().Interface().(proto.Message); ok {
for _, ext := range proto.RegisteredExtensions(ep) {
name := fmt.Sprintf("[%s]", ext.Name)
raw, ok := jsonFields[name]
if !ok {
continue
}
delete(jsonFields, name)
nv := reflect.New(reflect.TypeOf(ext.ExtensionType).Elem())
if err := u.unmarshalValue(nv.Elem(), raw, nil); err != nil {
return err
}
if err := proto.SetExtension(ep, ext, nv.Interface()); err != nil {
return err
}
}
}
}
if !u.AllowUnknownFields && len(jsonFields) > 0 {
// Pick any field to be the scapegoat.
var f string
for fname := range jsonFields {
@@ -429,7 +914,7 @@ func unmarshalValue(target reflect.Value, inputValue json.RawMessage) error {
}
// Handle arrays (which aren't encoded bytes)
if targetType != byteArrayType && targetType.Kind() == reflect.Slice {
if targetType.Kind() == reflect.Slice && targetType.Elem().Kind() != reflect.Uint8 {
var slc []json.RawMessage
if err := json.Unmarshal(inputValue, &slc); err != nil {
return err
@@ -437,7 +922,7 @@ func unmarshalValue(target reflect.Value, inputValue json.RawMessage) error {
len := len(slc)
target.Set(reflect.MakeSlice(targetType, len, len))
for i := 0; i < len; i++ {
if err := unmarshalValue(target.Index(i), slc[i]); err != nil {
if err := u.unmarshalValue(target.Index(i), slc[i], prop); err != nil {
return err
}
}
@@ -451,6 +936,13 @@ func unmarshalValue(target reflect.Value, inputValue json.RawMessage) error {
return err
}
target.Set(reflect.MakeMap(targetType))
var keyprop, valprop *proto.Properties
if prop != nil {
// These could still be nil if the protobuf metadata is broken somehow.
// TODO: This won't work because the fields are unexported.
// We should probably just reparse them.
//keyprop, valprop = prop.mkeyprop, prop.mvalprop
}
for ks, raw := range mp {
// Unmarshal map key. The core json library already decoded the key into a
// string, so we handle that specially. Other types were quoted post-serialization.
@@ -459,14 +951,14 @@ func unmarshalValue(target reflect.Value, inputValue json.RawMessage) error {
k = reflect.ValueOf(ks)
} else {
k = reflect.New(targetType.Key()).Elem()
if err := unmarshalValue(k, json.RawMessage(ks)); err != nil {
if err := u.unmarshalValue(k, json.RawMessage(ks), keyprop); err != nil {
return err
}
}
// Unmarshal map value.
v := reflect.New(targetType.Elem()).Elem()
if err := unmarshalValue(v, raw); err != nil {
if err := u.unmarshalValue(v, raw, valprop); err != nil {
return err
}
target.SetMapIndex(k, v)
@@ -481,22 +973,39 @@ func unmarshalValue(target reflect.Value, inputValue json.RawMessage) error {
inputValue = inputValue[1 : len(inputValue)-1]
}
// Non-finite numbers can be encoded as strings.
isFloat := targetType.Kind() == reflect.Float32 || targetType.Kind() == reflect.Float64
if isFloat {
if num, ok := nonFinite[string(inputValue)]; ok {
target.SetFloat(num)
return nil
}
}
// Use the encoding/json for parsing other value types.
return json.Unmarshal(inputValue, target.Addr().Interface())
}
// jsonProperties returns parsed proto.Properties for the field.
func jsonProperties(f reflect.StructField) *proto.Properties {
// jsonProperties returns parsed proto.Properties for the field and corrects JSONName attribute.
func jsonProperties(f reflect.StructField, origName bool) *proto.Properties {
var prop proto.Properties
prop.Init(f.Type, f.Name, f.Tag.Get("protobuf"), &f)
if origName || prop.JSONName == "" {
prop.JSONName = prop.OrigName
}
return &prop
}
// extendableProto is an interface implemented by any protocol buffer that may be extended.
type extendableProto interface {
proto.Message
ExtensionRangeArray() []proto.ExtensionRange
ExtensionMap() map[int32]proto.Extension
type fieldNames struct {
orig, camel string
}
func acceptedJSONFieldNames(prop *proto.Properties) fieldNames {
opts := fieldNames{orig: prop.OrigName, camel: prop.OrigName}
if prop.JSONName != "" {
opts.camel = prop.JSONName
}
return opts
}
// Writer wrapper inspired by https://blog.golang.org/errors-are-values
@@ -516,10 +1025,21 @@ func (w *errWriter) write(str string) {
// The easiest way to sort them in some deterministic order is to use fmt.
// If this turns out to be inefficient we can always consider other options,
// such as doing a Schwartzian transform.
//
// Numeric keys are sorted in numeric order per
// https://developers.google.com/protocol-buffers/docs/proto#maps.
type mapKeys []reflect.Value
func (s mapKeys) Len() int { return len(s) }
func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s mapKeys) Less(i, j int) bool {
if k := s[i].Kind(); k == s[j].Kind() {
switch k {
case reflect.Int32, reflect.Int64:
return s[i].Int() < s[j].Int()
case reflect.Uint32, reflect.Uint64:
return s[i].Uint() < s[j].Uint()
}
}
return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface())
}

View File

@@ -32,12 +32,24 @@
package jsonpb
import (
"bytes"
"encoding/json"
"io"
"math"
"reflect"
"strings"
"testing"
pb "github.com/golang/protobuf/jsonpb/jsonpb_test_proto"
"github.com/golang/protobuf/proto"
pb "github.com/golang/protobuf/jsonpb/jsonpb_test_proto"
proto3pb "github.com/golang/protobuf/proto/proto3_proto"
"github.com/golang/protobuf/ptypes"
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 (
@@ -62,31 +74,31 @@ var (
}
simpleObjectJSON = `{` +
`"o_bool":true,` +
`"o_int32":-32,` +
`"o_int64":"-6400000000",` +
`"o_uint32":32,` +
`"o_uint64":"6400000000",` +
`"o_sint32":-13,` +
`"o_sint64":"-2600000000",` +
`"o_float":3.14,` +
`"o_double":6.02214179e+23,` +
`"o_string":"hello \"there\"",` +
`"o_bytes":"YmVlcCBib29w"` +
`"oBool":true,` +
`"oInt32":-32,` +
`"oInt64":"-6400000000",` +
`"oUint32":32,` +
`"oUint64":"6400000000",` +
`"oSint32":-13,` +
`"oSint64":"-2600000000",` +
`"oFloat":3.14,` +
`"oDouble":6.02214179e+23,` +
`"oString":"hello \"there\"",` +
`"oBytes":"YmVlcCBib29w"` +
`}`
simpleObjectPrettyJSON = `{
"o_bool": true,
"o_int32": -32,
"o_int64": "-6400000000",
"o_uint32": 32,
"o_uint64": "6400000000",
"o_sint32": -13,
"o_sint64": "-2600000000",
"o_float": 3.14,
"o_double": 6.02214179e+23,
"o_string": "hello \"there\"",
"o_bytes": "YmVlcCBib29w"
"oBool": true,
"oInt32": -32,
"oInt64": "-6400000000",
"oUint32": 32,
"oUint64": "6400000000",
"oSint32": -13,
"oSint64": "-2600000000",
"oFloat": 3.14,
"oDouble": 6.02214179e+23,
"oString": "hello \"there\"",
"oBytes": "YmVlcCBib29w"
}`
repeatsObject = &pb.Repeats{
@@ -98,71 +110,71 @@ var (
RSint32: []int32{-1, -2, -3},
RSint64: []int64{-6789012345, -3456789012},
RFloat: []float32{3.14, 6.28},
RDouble: []float64{299792458, 6.62606957e-34},
RDouble: []float64{299792458 * 1e20, 6.62606957e-34},
RString: []string{"happy", "days"},
RBytes: [][]byte{[]byte("skittles"), []byte("m&m's")},
}
repeatsObjectJSON = `{` +
`"r_bool":[true,false,true],` +
`"r_int32":[-3,-4,-5],` +
`"r_int64":["-123456789","-987654321"],` +
`"r_uint32":[1,2,3],` +
`"r_uint64":["6789012345","3456789012"],` +
`"r_sint32":[-1,-2,-3],` +
`"r_sint64":["-6789012345","-3456789012"],` +
`"r_float":[3.14,6.28],` +
`"r_double":[2.99792458e+08,6.62606957e-34],` +
`"r_string":["happy","days"],` +
`"r_bytes":["c2tpdHRsZXM=","bSZtJ3M="]` +
`"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 = `{
"r_bool": [
"rBool": [
true,
false,
true
],
"r_int32": [
"rInt32": [
-3,
-4,
-5
],
"r_int64": [
"rInt64": [
"-123456789",
"-987654321"
],
"r_uint32": [
"rUint32": [
1,
2,
3
],
"r_uint64": [
"rUint64": [
"6789012345",
"3456789012"
],
"r_sint32": [
"rSint32": [
-1,
-2,
-3
],
"r_sint64": [
"rSint64": [
"-6789012345",
"-3456789012"
],
"r_float": [
"rFloat": [
3.14,
6.28
],
"r_double": [
2.99792458e+08,
"rDouble": [
2.99792458e+28,
6.62606957e-34
],
"r_string": [
"rString": [
"happy",
"days"
],
"r_bytes": [
"rBytes": [
"c2tpdHRsZXM=",
"bSZtJ3M="
]
@@ -182,46 +194,46 @@ var (
}
complexObjectJSON = `{"color":"GREEN",` +
`"r_color":["RED","GREEN","BLUE"],` +
`"simple":{"o_int32":-32},` +
`"r_simple":[{"o_int32":-32},{"o_int64":"25"}],` +
`"repeats":{"r_string":["roses","red"]},` +
`"r_repeats":[{"r_string":["roses","red"]},{"r_string":["violets","blue"]}]` +
`"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",
"r_color": [
"rColor": [
"RED",
"GREEN",
"BLUE"
],
"simple": {
"o_int32": -32
"oInt32": -32
},
"r_simple": [
"rSimple": [
{
"o_int32": -32
"oInt32": -32
},
{
"o_int64": "25"
"oInt64": "25"
}
],
"repeats": {
"r_string": [
"rString": [
"roses",
"red"
]
},
"r_repeats": [
"rRepeats": [
{
"r_string": [
"rString": [
"roses",
"red"
]
},
{
"r_string": [
"rString": [
"violets",
"blue"
]
@@ -235,7 +247,7 @@ var (
colorListPrettyJSON = `{
"color": 1000,
"r_color": [
"rColor": [
"RED"
]
}`
@@ -262,6 +274,58 @@ var (
`"[jsonpb.Complex.real_extension]":{"imaginary":0.5772156649},` +
`"[jsonpb.name]":"Pi"` +
`}`
anySimple = &pb.KnownTypes{
An: &anypb.Any{
TypeUrl: "something.example.com/jsonpb.Simple",
Value: []byte{
// &pb.Simple{OBool:true}
1 << 3, 1,
},
},
}
anySimpleJSON = `{"an":{"@type":"something.example.com/jsonpb.Simple","oBool":true}}`
anySimplePrettyJSON = `{
"an": {
"@type": "something.example.com/jsonpb.Simple",
"oBool": true
}
}`
anyWellKnown = &pb.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 = &pb.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() {
@@ -281,6 +345,7 @@ var marshalingTests = []struct {
}{
{"simple flat object", marshaler, simpleObject, simpleObjectJSON},
{"simple pretty object", marshalerAllOptions, simpleObject, simpleObjectPrettyJSON},
{"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},
@@ -291,7 +356,23 @@ var marshalingTests = []struct {
&pb.Widget{Color: pb.Widget_BLUE.Enum()}, colorPrettyJSON},
{"unknown enum value object", marshalerAllOptions,
&pb.Widget{Color: pb.Widget_Color(1000).Enum(), RColor: []pb.Widget_Color{pb.Widget_RED}}, colorListPrettyJSON},
{"proto3 object with empty value", marshaler, &pb.Simple3{}, `{"dub":0}`},
{"repeated proto3 enum", Marshaler{},
&proto3pb.Message{RFunny: []proto3pb.Message_Humour{
proto3pb.Message_PUNS,
proto3pb.Message_SLAPSTICK,
}},
`{"rFunny":["PUNS","SLAPSTICK"]}`},
{"repeated proto3 enum as int", Marshaler{EnumsAsInts: true},
&proto3pb.Message{RFunny: []proto3pb.Message_Humour{
proto3pb.Message_PUNS,
proto3pb.Message_SLAPSTICK,
}},
`{"rFunny":[1,2]}`},
{"empty value", marshaler, &pb.Simple3{}, `{}`},
{"empty value emitted", Marshaler{EmitDefaults: true}, &pb.Simple3{}, `{"dub":0}`},
{"empty repeated emitted", Marshaler{EmitDefaults: true}, &pb.SimpleSlice3{}, `{"slices":[]}`},
{"empty map emitted", Marshaler{EmitDefaults: true}, &pb.SimpleMap3{}, `{"stringy":{}}`},
{"nested struct null", Marshaler{EmitDefaults: true}, &pb.SimpleNull3{}, `{"simple":null}`},
{"map<int64, int32>", marshaler, &pb.Mappy{Nummy: map[int64]int32{1: 2, 3: 4}}, `{"nummy":{"1":2,"3":4}}`},
{"map<int64, int32>", marshalerAllOptions, &pb.Mappy{Nummy: map[int64]int32{1: 2, 3: 4}}, nummyPrettyJSON},
{"map<string, string>", marshaler,
@@ -304,14 +385,70 @@ var marshalingTests = []struct {
{"map<int64, string>", marshaler, &pb.Mappy{Buggy: map[int64]string{1234: "yup"}},
`{"buggy":{"1234":"yup"}}`},
{"map<bool, bool>", marshaler, &pb.Mappy{Booly: map[bool]bool{false: true}}, `{"booly":{"false":true}}`},
// TODO: This is broken.
//{"map<string, enum>", marshaler, &pb.Mappy{Enumy: map[string]pb.Numeral{"XIV": pb.Numeral_ROMAN}}, `{"enumy":{"XIV":"ROMAN"}`},
{"map<string, enum as int>", Marshaler{EnumsAsInts: true}, &pb.Mappy{Enumy: map[string]pb.Numeral{"XIV": pb.Numeral_ROMAN}}, `{"enumy":{"XIV":2}}`},
{"map<int32, bool>", marshaler, &pb.Mappy{S32Booly: map[int32]bool{1: true, 3: false, 10: true, 12: false}}, `{"s32booly":{"1":true,"3":false,"10":true,"12":false}}`},
{"map<int64, bool>", marshaler, &pb.Mappy{S64Booly: map[int64]bool{1: true, 3: false, 10: true, 12: false}}, `{"s64booly":{"1":true,"3":false,"10":true,"12":false}}`},
{"map<uint32, bool>", marshaler, &pb.Mappy{U32Booly: map[uint32]bool{1: true, 3: false, 10: true, 12: false}}, `{"u32booly":{"1":true,"3":false,"10":true,"12":false}}`},
{"map<uint64, bool>", marshaler, &pb.Mappy{U64Booly: map[uint64]bool{1: true, 3: false, 10: true, 12: false}}, `{"u64booly":{"1":true,"3":false,"10":true,"12":false}}`},
{"proto2 map<int64, string>", marshaler, &pb.Maps{MInt64Str: map[int64]string{213: "cat"}},
`{"m_int64_str":{"213":"cat"}}`},
`{"mInt64Str":{"213":"cat"}}`},
{"proto2 map<bool, Object>", marshaler,
&pb.Maps{MBoolSimple: map[bool]*pb.Simple{true: &pb.Simple{OInt32: proto.Int32(1)}}},
`{"m_bool_simple":{"true":{"o_int32":1}}}`},
`{"mBoolSimple":{"true":{"oInt32":1}}}`},
{"oneof, not set", marshaler, &pb.MsgWithOneof{}, `{}`},
{"oneof, set", marshaler, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_Title{"Grand Poobah"}}, `{"title":"Grand Poobah"}`},
{"force orig_name", Marshaler{OrigName: true}, &pb.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", marshaler, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3}}, `{"dur":"3.000s"}`},
{"Struct", marshaler, &pb.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, &pb.KnownTypes{Lv: &stpb.ListValue{}}, `{"lv":[]}`},
{"basic ListValue", marshaler, &pb.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, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 21e6}}, `{"ts":"2014-05-13T16:53:20.021Z"}`},
{"number Value", marshaler, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_NumberValue{1}}}, `{"val":1}`},
{"null Value", marshaler, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_NullValue{stpb.NullValue_NULL_VALUE}}}, `{"val":null}`},
{"string number value", marshaler, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_StringValue{"9223372036854775807"}}}, `{"val":"9223372036854775807"}`},
{"list of lists Value", marshaler, &pb.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, &pb.KnownTypes{Dbl: &wpb.DoubleValue{Value: 1.2}}, `{"dbl":1.2}`},
{"FloatValue", marshaler, &pb.KnownTypes{Flt: &wpb.FloatValue{Value: 1.2}}, `{"flt":1.2}`},
{"Int64Value", marshaler, &pb.KnownTypes{I64: &wpb.Int64Value{Value: -3}}, `{"i64":"-3"}`},
{"UInt64Value", marshaler, &pb.KnownTypes{U64: &wpb.UInt64Value{Value: 3}}, `{"u64":"3"}`},
{"Int32Value", marshaler, &pb.KnownTypes{I32: &wpb.Int32Value{Value: -4}}, `{"i32":-4}`},
{"UInt32Value", marshaler, &pb.KnownTypes{U32: &wpb.UInt32Value{Value: 4}}, `{"u32":4}`},
{"BoolValue", marshaler, &pb.KnownTypes{Bool: &wpb.BoolValue{Value: true}}, `{"bool":true}`},
{"StringValue", marshaler, &pb.KnownTypes{Str: &wpb.StringValue{Value: "plush"}}, `{"str":"plush"}`},
{"BytesValue", marshaler, &pb.KnownTypes{Bytes: &wpb.BytesValue{Value: []byte("wow")}}, `{"bytes":"d293"}`},
}
func TestMarshaling(t *testing.T) {
@@ -325,30 +462,167 @@ func TestMarshaling(t *testing.T) {
}
}
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 occurred when marshalling JSONPBMarshaler: %v", err)
}
if str != rawJson {
t.Errorf("marshalling 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 occurred when marshalling to Any: %v", err)
}
str, err := new(Marshaler).MarshalToString(a)
if err != nil {
t.Errorf("an unexpected error occurred when marshalling 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
expected := `{"@type":"type.googleapis.com/` + dynamicMessageName +`","baz":[0,1,2,3],"foo":"bar"}`
if str != expected {
t.Errorf("marshalling JSON produced incorrect output: got %s, wanted %s", str, expected)
}
}
var unmarshalingTests = []struct {
desc string
json string
pb proto.Message
desc string
unmarshaler Unmarshaler
json string
pb proto.Message
}{
{"simple flat object", simpleObjectJSON, simpleObject},
{"simple pretty object", simpleObjectPrettyJSON, simpleObject},
{"repeated fields flat object", repeatsObjectJSON, repeatsObject},
{"repeated fields pretty object", repeatsObjectPrettyJSON, repeatsObject},
{"nested message/enum flat object", complexObjectJSON, complexObject},
{"nested message/enum pretty object", complexObjectPrettyJSON, complexObject},
{"enum-string object", `{"color":"BLUE"}`, &pb.Widget{Color: pb.Widget_BLUE.Enum()}},
{"enum-value object", "{\n \"color\": 2\n}", &pb.Widget{Color: pb.Widget_BLUE.Enum()}},
{"proto3 enum string", `{"hilarity":"PUNS"}`, &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}},
{"proto3 enum value", `{"hilarity":1}`, &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}},
{"simple flat object", Unmarshaler{}, simpleObjectJSON, simpleObject},
{"simple pretty object", Unmarshaler{}, simpleObjectPrettyJSON, 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"}`, &pb.Widget{Color: pb.Widget_BLUE.Enum()}},
{"enum-value object", Unmarshaler{}, "{\n \"color\": 2\n}", &pb.Widget{Color: pb.Widget_BLUE.Enum()}},
{"unknown field with allowed option", Unmarshaler{AllowUnknownFields: true}, `{"unknown": "foo"}`, new(pb.Simple)},
{"proto3 enum string", Unmarshaler{}, `{"hilarity":"PUNS"}`, &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}},
{"proto3 enum value", Unmarshaler{}, `{"hilarity":1}`, &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}},
{"unknown enum value object",
Unmarshaler{},
"{\n \"color\": 1000,\n \"r_color\": [\n \"RED\"\n ]\n}",
&pb.Widget{Color: pb.Widget_Color(1000).Enum(), RColor: []pb.Widget_Color{pb.Widget_RED}}},
{"unquoted int64 object", `{"o_int64":-314}`, &pb.Simple{OInt64: proto.Int64(-314)}},
{"unquoted uint64 object", `{"o_uint64":123}`, &pb.Simple{OUint64: proto.Uint64(123)}},
{"map<int64, int32>", `{"nummy":{"1":2,"3":4}}`, &pb.Mappy{Nummy: map[int64]int32{1: 2, 3: 4}}},
{"map<string, string>", `{"strry":{"\"one\"":"two","three":"four"}}`, &pb.Mappy{Strry: map[string]string{`"one"`: "two", "three": "four"}}},
{"map<int32, Object>", `{"objjy":{"1":{"dub":1}}}`, &pb.Mappy{Objjy: map[int32]*pb.Simple3{1: &pb.Simple3{Dub: 1}}}},
{"oneof", `{"salary":31000}`, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_Salary{31000}}},
{"repeated proto3 enum", Unmarshaler{}, `{"rFunny":["PUNS","SLAPSTICK"]}`,
&proto3pb.Message{RFunny: []proto3pb.Message_Humour{
proto3pb.Message_PUNS,
proto3pb.Message_SLAPSTICK,
}}},
{"repeated proto3 enum as int", Unmarshaler{}, `{"rFunny":[1,2]}`,
&proto3pb.Message{RFunny: []proto3pb.Message_Humour{
proto3pb.Message_PUNS,
proto3pb.Message_SLAPSTICK,
}}},
{"repeated proto3 enum as mix of strings and ints", Unmarshaler{}, `{"rFunny":["PUNS",2]}`,
&proto3pb.Message{RFunny: []proto3pb.Message_Humour{
proto3pb.Message_PUNS,
proto3pb.Message_SLAPSTICK,
}}},
{"unquoted int64 object", Unmarshaler{}, `{"oInt64":-314}`, &pb.Simple{OInt64: proto.Int64(-314)}},
{"unquoted uint64 object", Unmarshaler{}, `{"oUint64":123}`, &pb.Simple{OUint64: proto.Uint64(123)}},
{"NaN", Unmarshaler{}, `{"oDouble":"NaN"}`, &pb.Simple{ODouble: proto.Float64(math.NaN())}},
{"Inf", Unmarshaler{}, `{"oFloat":"Infinity"}`, &pb.Simple{OFloat: proto.Float32(float32(math.Inf(1)))}},
{"-Inf", Unmarshaler{}, `{"oDouble":"-Infinity"}`, &pb.Simple{ODouble: proto.Float64(math.Inf(-1))}},
{"map<int64, int32>", Unmarshaler{}, `{"nummy":{"1":2,"3":4}}`, &pb.Mappy{Nummy: map[int64]int32{1: 2, 3: 4}}},
{"map<string, string>", Unmarshaler{}, `{"strry":{"\"one\"":"two","three":"four"}}`, &pb.Mappy{Strry: map[string]string{`"one"`: "two", "three": "four"}}},
{"map<int32, Object>", Unmarshaler{}, `{"objjy":{"1":{"dub":1}}}`, &pb.Mappy{Objjy: map[int32]*pb.Simple3{1: &pb.Simple3{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},
// TODO: This is broken.
//{"map<string, enum>", Unmarshaler{}, `{"enumy":{"XIV":"ROMAN"}`, &pb.Mappy{Enumy: map[string]pb.Numeral{"XIV": pb.Numeral_ROMAN}}},
{"map<string, enum as int>", Unmarshaler{}, `{"enumy":{"XIV":2}}`, &pb.Mappy{Enumy: map[string]pb.Numeral{"XIV": pb.Numeral_ROMAN}}},
{"oneof", Unmarshaler{}, `{"salary":31000}`, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_Salary{31000}}},
{"oneof spec name", Unmarshaler{}, `{"Country":"Australia"}`, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_Country{"Australia"}}},
{"oneof orig_name", Unmarshaler{}, `{"Country":"Australia"}`, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_Country{"Australia"}}},
{"oneof spec name2", Unmarshaler{}, `{"homeAddress":"Australia"}`, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_HomeAddress{"Australia"}}},
{"oneof orig_name2", Unmarshaler{}, `{"home_address":"Australia"}`, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_HomeAddress{"Australia"}}},
{"orig_name input", Unmarshaler{}, `{"o_bool":true}`, &pb.Simple{OBool: proto.Bool(true)}},
{"camelName input", Unmarshaler{}, `{"oBool":true}`, &pb.Simple{OBool: proto.Bool(true)}},
{"Duration", Unmarshaler{}, `{"dur":"3.000s"}`, &pb.KnownTypes{Dur: &durpb.Duration{Seconds: 3}}},
{"null Duration", Unmarshaler{}, `{"dur":null}`, &pb.KnownTypes{Dur: nil}},
{"Timestamp", Unmarshaler{}, `{"ts":"2014-05-13T16:53:20.021Z"}`, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: 14e8, Nanos: 21e6}}},
{"PreEpochTimestamp", Unmarshaler{}, `{"ts":"1969-12-31T23:59:58.999999995Z"}`, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: -2, Nanos: 999999995}}},
{"ZeroTimeTimestamp", Unmarshaler{}, `{"ts":"0001-01-01T00:00:00Z"}`, &pb.KnownTypes{Ts: &tspb.Timestamp{Seconds: -62135596800, Nanos: 0}}},
{"null Timestamp", Unmarshaler{}, `{"ts":null}`, &pb.KnownTypes{Ts: nil}},
{"null Struct", Unmarshaler{}, `{"st": null}`, &pb.KnownTypes{St: nil}},
{"empty Struct", Unmarshaler{}, `{"st": {}}`, &pb.KnownTypes{St: &stpb.Struct{}}},
{"basic Struct", Unmarshaler{}, `{"st": {"a": "x", "b": null, "c": 3, "d": true}}`, &pb.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"]}}}`, &pb.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}`, &pb.KnownTypes{Lv: nil}},
{"empty ListValue", Unmarshaler{}, `{"lv": []}`, &pb.KnownTypes{Lv: &stpb.ListValue{}}},
{"basic ListValue", Unmarshaler{}, `{"lv": ["x", null, 3, true]}`, &pb.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}`, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_NumberValue{1}}}},
{"null Value", Unmarshaler{}, `{"val":null}`, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_NullValue{stpb.NullValue_NULL_VALUE}}}},
{"bool Value", Unmarshaler{}, `{"val":true}`, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_BoolValue{true}}}},
{"string Value", Unmarshaler{}, `{"val":"x"}`, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_StringValue{"x"}}}},
{"string number value", Unmarshaler{}, `{"val":"9223372036854775807"}`, &pb.KnownTypes{Val: &stpb.Value{Kind: &stpb.Value_StringValue{"9223372036854775807"}}}},
{"list of lists Value", Unmarshaler{}, `{"val":["x", [["y"], "z"]]}`, &pb.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}`, &pb.KnownTypes{Dbl: &wpb.DoubleValue{Value: 1.2}}},
{"FloatValue", Unmarshaler{}, `{"flt":1.2}`, &pb.KnownTypes{Flt: &wpb.FloatValue{Value: 1.2}}},
{"Int64Value", Unmarshaler{}, `{"i64":"-3"}`, &pb.KnownTypes{I64: &wpb.Int64Value{Value: -3}}},
{"UInt64Value", Unmarshaler{}, `{"u64":"3"}`, &pb.KnownTypes{U64: &wpb.UInt64Value{Value: 3}}},
{"Int32Value", Unmarshaler{}, `{"i32":-4}`, &pb.KnownTypes{I32: &wpb.Int32Value{Value: -4}}},
{"UInt32Value", Unmarshaler{}, `{"u32":4}`, &pb.KnownTypes{U32: &wpb.UInt32Value{Value: 4}}},
{"BoolValue", Unmarshaler{}, `{"bool":true}`, &pb.KnownTypes{Bool: &wpb.BoolValue{Value: true}}},
{"StringValue", Unmarshaler{}, `{"str":"plush"}`, &pb.KnownTypes{Str: &wpb.StringValue{Value: "plush"}}},
{"BytesValue", Unmarshaler{}, `{"bytes":"d293"}`, &pb.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}`, &pb.KnownTypes{Dbl: nil}},
{"null FloatValue", Unmarshaler{}, `{"flt":null}`, &pb.KnownTypes{Flt: nil}},
{"null Int64Value", Unmarshaler{}, `{"i64":null}`, &pb.KnownTypes{I64: nil}},
{"null UInt64Value", Unmarshaler{}, `{"u64":null}`, &pb.KnownTypes{U64: nil}},
{"null Int32Value", Unmarshaler{}, `{"i32":null}`, &pb.KnownTypes{I32: nil}},
{"null UInt32Value", Unmarshaler{}, `{"u32":null}`, &pb.KnownTypes{U32: nil}},
{"null BoolValue", Unmarshaler{}, `{"bool":null}`, &pb.KnownTypes{Bool: nil}},
{"null StringValue", Unmarshaler{}, `{"str":null}`, &pb.KnownTypes{Str: nil}},
{"null BytesValue", Unmarshaler{}, `{"bytes":null}`, &pb.KnownTypes{Bytes: nil}},
}
func TestUnmarshaling(t *testing.T) {
@@ -356,9 +630,9 @@ func TestUnmarshaling(t *testing.T) {
// Make a new instance of the type of our expected object.
p := reflect.New(reflect.TypeOf(tt.pb).Elem()).Interface().(proto.Message)
err := UnmarshalString(tt.json, p)
err := tt.unmarshaler.Unmarshal(strings.NewReader(tt.json), p)
if err != nil {
t.Error(err)
t.Errorf("%s: %v", tt.desc, err)
continue
}
@@ -371,6 +645,42 @@ func TestUnmarshaling(t *testing.T) {
}
}
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 expected 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 := &pb.Simple{}
err := new(Unmarshaler).UnmarshalNext(dec, p)
if err != io.EOF {
t.Errorf("eof: got %v, expected io.EOF", err)
}
}
var unmarshalingShouldError = []struct {
desc string
in string
@@ -378,6 +688,7 @@ var unmarshalingShouldError = []struct {
}{
{"a value", "666", new(pb.Simple)},
{"gibberish", "{adskja123;l23=-=", new(pb.Simple)},
{"unknown field", `{"unknown": "foo"}`, new(pb.Simple)},
{"unknown enum name", `{"hilarity":"DAVE"}`, new(proto3pb.Message)},
}
@@ -389,3 +700,69 @@ func TestUnmarshalingBadInput(t *testing.T) {
}
}
}
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 occurred when parsing into JSONPBUnmarshaler: %v", err)
}
if msg.rawJson != rawJson {
t.Errorf("message contents not set correctly after unmarshalling JSON: got %s, wanted %s", msg.rawJson, rawJson)
}
}
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 occurred when 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 occurred when 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 unmarshalling JSON: got %s, wanted %s", got, want)
}
}
const (
dynamicMessageName = "google.protobuf.jsonpb.testing.dynamicMessage"
)
func init() {
// we register the custom type below so that we can use it in Any types
proto.RegisterType((*dynamicMessage)(nil), dynamicMessageName)
}
// 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"`
}
func (m *dynamicMessage) Reset() {
m.rawJson = "{}"
}
func (m *dynamicMessage) String() string {
return m.rawJson
}
func (m *dynamicMessage) ProtoMessage() {
}
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
}

View File

@@ -30,4 +30,4 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
regenerate:
protoc --go_out=. *.proto
protoc --go_out=Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any,Mgoogle/protobuf/duration.proto=github.com/golang/protobuf/ptypes/duration,Mgoogle/protobuf/struct.proto=github.com/golang/protobuf/ptypes/struct,Mgoogle/protobuf/timestamp.proto=github.com/golang/protobuf/ptypes/timestamp,Mgoogle/protobuf/wrappers.proto=github.com/golang/protobuf/ptypes/wrappers:. *.proto

View File

@@ -0,0 +1,266 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: more_test_objects.proto
/*
Package jsonpb is a generated protocol buffer package.
It is generated from these files:
more_test_objects.proto
test_objects.proto
It has these top-level messages:
Simple3
SimpleSlice3
SimpleMap3
SimpleNull3
Mappy
Simple
NonFinites
Repeats
Widget
Maps
MsgWithOneof
Real
Complex
KnownTypes
*/
package jsonpb
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import 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.ProtoPackageIsVersion2 // 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 fileDescriptor0, []int{0} }
type Simple3 struct {
Dub float64 `protobuf:"fixed64,1,opt,name=dub" json:"dub,omitempty"`
}
func (m *Simple3) Reset() { *m = Simple3{} }
func (m *Simple3) String() string { return proto.CompactTextString(m) }
func (*Simple3) ProtoMessage() {}
func (*Simple3) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *Simple3) GetDub() float64 {
if m != nil {
return m.Dub
}
return 0
}
type SimpleSlice3 struct {
Slices []string `protobuf:"bytes,1,rep,name=slices" json:"slices,omitempty"`
}
func (m *SimpleSlice3) Reset() { *m = SimpleSlice3{} }
func (m *SimpleSlice3) String() string { return proto.CompactTextString(m) }
func (*SimpleSlice3) ProtoMessage() {}
func (*SimpleSlice3) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
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" json:"stringy,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
}
func (m *SimpleMap3) Reset() { *m = SimpleMap3{} }
func (m *SimpleMap3) String() string { return proto.CompactTextString(m) }
func (*SimpleMap3) ProtoMessage() {}
func (*SimpleMap3) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
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" json:"simple,omitempty"`
}
func (m *SimpleNull3) Reset() { *m = SimpleNull3{} }
func (m *SimpleNull3) String() string { return proto.CompactTextString(m) }
func (*SimpleNull3) ProtoMessage() {}
func (*SimpleNull3) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
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" json:"nummy,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
Strry map[string]string `protobuf:"bytes,2,rep,name=strry" json:"strry,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
Objjy map[int32]*Simple3 `protobuf:"bytes,3,rep,name=objjy" json:"objjy,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
Buggy map[int64]string `protobuf:"bytes,4,rep,name=buggy" json:"buggy,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
Booly map[bool]bool `protobuf:"bytes,5,rep,name=booly" json:"booly,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
Enumy map[string]Numeral `protobuf:"bytes,6,rep,name=enumy" json:"enumy,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value,enum=jsonpb.Numeral"`
S32Booly map[int32]bool `protobuf:"bytes,7,rep,name=s32booly" json:"s32booly,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
S64Booly map[int64]bool `protobuf:"bytes,8,rep,name=s64booly" json:"s64booly,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
U32Booly map[uint32]bool `protobuf:"bytes,9,rep,name=u32booly" json:"u32booly,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
U64Booly map[uint64]bool `protobuf:"bytes,10,rep,name=u64booly" json:"u64booly,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
}
func (m *Mappy) Reset() { *m = Mappy{} }
func (m *Mappy) String() string { return proto.CompactTextString(m) }
func (*Mappy) ProtoMessage() {}
func (*Mappy) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
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.RegisterType((*Simple3)(nil), "jsonpb.Simple3")
proto.RegisterType((*SimpleSlice3)(nil), "jsonpb.SimpleSlice3")
proto.RegisterType((*SimpleMap3)(nil), "jsonpb.SimpleMap3")
proto.RegisterType((*SimpleNull3)(nil), "jsonpb.SimpleNull3")
proto.RegisterType((*Mappy)(nil), "jsonpb.Mappy")
proto.RegisterEnum("jsonpb.Numeral", Numeral_name, Numeral_value)
}
func init() { proto.RegisterFile("more_test_objects.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 526 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0xdd, 0x6b, 0xdb, 0x3c,
0x14, 0x87, 0x5f, 0x27, 0xf5, 0xd7, 0x49, 0xfb, 0x2e, 0x88, 0xb1, 0x99, 0xf4, 0x62, 0xc5, 0xb0,
0xad, 0x0c, 0xe6, 0x8b, 0x78, 0x74, 0x5d, 0x77, 0x95, 0x8e, 0x5e, 0x94, 0x11, 0x07, 0x1c, 0xc2,
0x2e, 0x4b, 0xdc, 0x99, 0x90, 0xcc, 0x5f, 0xd8, 0xd6, 0xc0, 0xd7, 0xfb, 0xbb, 0x07, 0xe3, 0x48,
0x72, 0x2d, 0x07, 0x85, 0x6c, 0x77, 0x52, 0x7e, 0xcf, 0xe3, 0x73, 0x24, 0x1d, 0x02, 0x2f, 0xd3,
0xbc, 0x8c, 0x1f, 0xea, 0xb8, 0xaa, 0x1f, 0xf2, 0x68, 0x17, 0x3f, 0xd6, 0x95, 0x57, 0x94, 0x79,
0x9d, 0x13, 0x63, 0x57, 0xe5, 0x59, 0x11, 0xb9, 0xe7, 0x60, 0x2e, 0xb7, 0x69, 0x91, 0xc4, 0x3e,
0x19, 0xc3, 0xf0, 0x3b, 0x8d, 0x1c, 0xed, 0x42, 0xbb, 0xd4, 0x42, 0x5c, 0xba, 0x6f, 0xe0, 0x94,
0x87, 0xcb, 0x64, 0xfb, 0x18, 0xfb, 0xe4, 0x05, 0x18, 0x15, 0xae, 0x2a, 0x47, 0xbb, 0x18, 0x5e,
0xda, 0xa1, 0xd8, 0xb9, 0xbf, 0x34, 0x00, 0x0e, 0xce, 0xd7, 0x85, 0x4f, 0x3e, 0x81, 0x59, 0xd5,
0xe5, 0x36, 0xdb, 0x34, 0x8c, 0x1b, 0x4d, 0x5f, 0x79, 0xbc, 0x9a, 0xd7, 0x41, 0xde, 0x92, 0x13,
0x77, 0x59, 0x5d, 0x36, 0x61, 0xcb, 0x4f, 0x6e, 0xe0, 0x54, 0x0e, 0xb0, 0xa7, 0x1f, 0x71, 0xc3,
0x7a, 0xb2, 0x43, 0x5c, 0x92, 0xe7, 0xa0, 0xff, 0x5c, 0x27, 0x34, 0x76, 0x06, 0xec, 0x37, 0xbe,
0xb9, 0x19, 0x5c, 0x6b, 0xee, 0x15, 0x8c, 0xf8, 0xf7, 0x03, 0x9a, 0x24, 0x3e, 0x79, 0x0b, 0x46,
0xc5, 0xb6, 0xcc, 0x1e, 0x4d, 0x9f, 0xf5, 0x9b, 0xf0, 0x43, 0x11, 0xbb, 0xbf, 0x2d, 0xd0, 0xe7,
0xeb, 0xa2, 0x68, 0x88, 0x07, 0x7a, 0x46, 0xd3, 0xb4, 0x6d, 0xdb, 0x69, 0x0d, 0x96, 0x7a, 0x01,
0x46, 0xbc, 0x5f, 0x8e, 0x21, 0x5f, 0xd5, 0x65, 0xd9, 0x38, 0x03, 0x15, 0xbf, 0xc4, 0x48, 0xf0,
0x0c, 0x43, 0x3e, 0x8f, 0x76, 0xbb, 0xc6, 0x19, 0xaa, 0xf8, 0x05, 0x46, 0x82, 0x67, 0x18, 0xf2,
0x11, 0xdd, 0x6c, 0x1a, 0xe7, 0x44, 0xc5, 0xdf, 0x62, 0x24, 0x78, 0x86, 0x31, 0x3e, 0xcf, 0x93,
0xc6, 0xd1, 0x95, 0x3c, 0x46, 0x2d, 0x8f, 0x6b, 0xe4, 0xe3, 0x8c, 0xa6, 0x8d, 0x63, 0xa8, 0xf8,
0x3b, 0x8c, 0x04, 0xcf, 0x30, 0xf2, 0x11, 0xac, 0xca, 0x9f, 0xf2, 0x12, 0x26, 0x53, 0xce, 0xf7,
0x8e, 0x2c, 0x52, 0x6e, 0x3d, 0xc1, 0x4c, 0xbc, 0xfa, 0xc0, 0x45, 0x4b, 0x29, 0x8a, 0xb4, 0x15,
0xc5, 0x16, 0x45, 0xda, 0x56, 0xb4, 0x55, 0xe2, 0xaa, 0x5f, 0x91, 0x4a, 0x15, 0x69, 0x5b, 0x11,
0x94, 0x62, 0xbf, 0x62, 0x0b, 0x4f, 0xae, 0x01, 0xba, 0x87, 0x96, 0xe7, 0x6f, 0xa8, 0x98, 0x3f,
0x5d, 0x9a, 0x3f, 0x34, 0xbb, 0x27, 0xff, 0x97, 0xc9, 0x9d, 0xdc, 0x03, 0x74, 0x8f, 0x2f, 0x9b,
0x3a, 0x37, 0x5f, 0xcb, 0xa6, 0x62, 0x92, 0xfb, 0x4d, 0x74, 0x73, 0x71, 0xac, 0x7d, 0x7b, 0xdf,
0x7c, 0xba, 0x10, 0xd9, 0xb4, 0x14, 0xa6, 0xb5, 0xd7, 0x7e, 0x37, 0x2b, 0x8a, 0x83, 0xf7, 0xda,
0xff, 0xbf, 0x6b, 0x3f, 0xa0, 0x69, 0x5c, 0xae, 0x13, 0xf9, 0x53, 0x9f, 0xe1, 0xac, 0x37, 0x43,
0x8a, 0xcb, 0x38, 0xdc, 0x07, 0xca, 0xf2, 0xab, 0x1e, 0x3b, 0xfe, 0xbe, 0xbc, 0x3a, 0x54, 0xf9,
0xec, 0x6f, 0xe4, 0x43, 0x95, 0x4f, 0x8e, 0xc8, 0xef, 0xde, 0x83, 0x29, 0x6e, 0x82, 0x8c, 0xc0,
0x5c, 0x05, 0x5f, 0x83, 0xc5, 0xb7, 0x60, 0xfc, 0x1f, 0x01, 0x30, 0x66, 0xe1, 0xec, 0xf6, 0xfe,
0xcb, 0x58, 0x23, 0x36, 0xe8, 0xe1, 0x62, 0x3e, 0x0b, 0xc6, 0x83, 0xc8, 0x60, 0x7f, 0xe0, 0xfe,
0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdc, 0x84, 0x34, 0xaf, 0xdb, 0x05, 0x00, 0x00,
}

View File

@@ -37,10 +37,33 @@ message Simple3 {
double dub = 1;
}
message SimpleSlice3 {
repeated string slices = 1;
}
message SimpleMap3 {
map<string,string> stringy = 1;
}
message SimpleNull3 {
Simple3 simple = 1;
}
enum Numeral {
UNKNOWN = 0;
ARABIC = 1;
ROMAN = 2;
}
message Mappy {
map<int64, int32> nummy = 1;
map<string, string> strry = 2;
map<int32, Simple3> objjy = 3;
map<int64, string> buggy = 4;
map<bool, bool> booly = 5;
map<string, Numeral> enumy = 6;
map<int32, bool> s32booly = 7;
map<int64, bool> s64booly = 8;
map<uint32, bool> u32booly = 9;
map<uint64, bool> u64booly = 10;
}

View File

@@ -0,0 +1,852 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: test_objects.proto
package jsonpb
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import google_protobuf "github.com/golang/protobuf/ptypes/any"
import google_protobuf1 "github.com/golang/protobuf/ptypes/duration"
import google_protobuf2 "github.com/golang/protobuf/ptypes/struct"
import google_protobuf3 "github.com/golang/protobuf/ptypes/timestamp"
import google_protobuf4 "github.com/golang/protobuf/ptypes/wrappers"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
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 fileDescriptor1, []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"`
OInt64 *int64 `protobuf:"varint,3,opt,name=o_int64,json=oInt64" json:"o_int64,omitempty"`
OUint32 *uint32 `protobuf:"varint,4,opt,name=o_uint32,json=oUint32" json:"o_uint32,omitempty"`
OUint64 *uint64 `protobuf:"varint,5,opt,name=o_uint64,json=oUint64" json:"o_uint64,omitempty"`
OSint32 *int32 `protobuf:"zigzag32,6,opt,name=o_sint32,json=oSint32" json:"o_sint32,omitempty"`
OSint64 *int64 `protobuf:"zigzag64,7,opt,name=o_sint64,json=oSint64" json:"o_sint64,omitempty"`
OFloat *float32 `protobuf:"fixed32,8,opt,name=o_float,json=oFloat" json:"o_float,omitempty"`
ODouble *float64 `protobuf:"fixed64,9,opt,name=o_double,json=oDouble" json:"o_double,omitempty"`
OString *string `protobuf:"bytes,10,opt,name=o_string,json=oString" json:"o_string,omitempty"`
OBytes []byte `protobuf:"bytes,11,opt,name=o_bytes,json=oBytes" json:"o_bytes,omitempty"`
XXX_unrecognized []byte `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 fileDescriptor1, []int{0} }
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) GetOInt64() int64 {
if m != nil && m.OInt64 != nil {
return *m.OInt64
}
return 0
}
func (m *Simple) GetOUint32() uint32 {
if m != nil && m.OUint32 != nil {
return *m.OUint32
}
return 0
}
func (m *Simple) GetOUint64() uint64 {
if m != nil && m.OUint64 != nil {
return *m.OUint64
}
return 0
}
func (m *Simple) GetOSint32() int32 {
if m != nil && m.OSint32 != nil {
return *m.OSint32
}
return 0
}
func (m *Simple) GetOSint64() int64 {
if m != nil && m.OSint64 != nil {
return *m.OSint64
}
return 0
}
func (m *Simple) GetOFloat() float32 {
if m != nil && m.OFloat != nil {
return *m.OFloat
}
return 0
}
func (m *Simple) GetODouble() float64 {
if m != nil && m.ODouble != nil {
return *m.ODouble
}
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_unrecognized []byte `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 fileDescriptor1, []int{1} }
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_unrecognized []byte `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 fileDescriptor1, []int{2} }
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.Widget_Color" json:"color,omitempty"`
RColor []Widget_Color `protobuf:"varint,2,rep,name=r_color,json=rColor,enum=jsonpb.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_unrecognized []byte `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 fileDescriptor1, []int{3} }
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_unrecognized []byte `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 fileDescriptor1, []int{4} }
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
Union isMsgWithOneof_Union `protobuf_oneof:"union"`
XXX_unrecognized []byte `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 fileDescriptor1, []int{5} }
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"`
}
func (*MsgWithOneof_Title) isMsgWithOneof_Union() {}
func (*MsgWithOneof_Salary) isMsgWithOneof_Union() {}
func (*MsgWithOneof_Country) isMsgWithOneof_Union() {}
func (*MsgWithOneof_HomeAddress) 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 ""
}
// XXX_OneofFuncs is for the internal use of the proto package.
func (*MsgWithOneof) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
return _MsgWithOneof_OneofMarshaler, _MsgWithOneof_OneofUnmarshaler, _MsgWithOneof_OneofSizer, []interface{}{
(*MsgWithOneof_Title)(nil),
(*MsgWithOneof_Salary)(nil),
(*MsgWithOneof_Country)(nil),
(*MsgWithOneof_HomeAddress)(nil),
}
}
func _MsgWithOneof_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
m := msg.(*MsgWithOneof)
// union
switch x := m.Union.(type) {
case *MsgWithOneof_Title:
b.EncodeVarint(1<<3 | proto.WireBytes)
b.EncodeStringBytes(x.Title)
case *MsgWithOneof_Salary:
b.EncodeVarint(2<<3 | proto.WireVarint)
b.EncodeVarint(uint64(x.Salary))
case *MsgWithOneof_Country:
b.EncodeVarint(3<<3 | proto.WireBytes)
b.EncodeStringBytes(x.Country)
case *MsgWithOneof_HomeAddress:
b.EncodeVarint(4<<3 | proto.WireBytes)
b.EncodeStringBytes(x.HomeAddress)
case nil:
default:
return fmt.Errorf("MsgWithOneof.Union has unexpected type %T", x)
}
return nil
}
func _MsgWithOneof_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
m := msg.(*MsgWithOneof)
switch tag {
case 1: // union.title
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeStringBytes()
m.Union = &MsgWithOneof_Title{x}
return true, err
case 2: // union.salary
if wire != proto.WireVarint {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeVarint()
m.Union = &MsgWithOneof_Salary{int64(x)}
return true, err
case 3: // union.Country
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeStringBytes()
m.Union = &MsgWithOneof_Country{x}
return true, err
case 4: // union.home_address
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeStringBytes()
m.Union = &MsgWithOneof_HomeAddress{x}
return true, err
default:
return false, nil
}
}
func _MsgWithOneof_OneofSizer(msg proto.Message) (n int) {
m := msg.(*MsgWithOneof)
// union
switch x := m.Union.(type) {
case *MsgWithOneof_Title:
n += proto.SizeVarint(1<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.Title)))
n += len(x.Title)
case *MsgWithOneof_Salary:
n += proto.SizeVarint(2<<3 | proto.WireVarint)
n += proto.SizeVarint(uint64(x.Salary))
case *MsgWithOneof_Country:
n += proto.SizeVarint(3<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.Country)))
n += len(x.Country)
case *MsgWithOneof_HomeAddress:
n += proto.SizeVarint(4<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.HomeAddress)))
n += len(x.HomeAddress)
case nil:
default:
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
}
return n
}
type Real struct {
Value *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"`
proto.XXX_InternalExtensions `json:"-"`
XXX_unrecognized []byte `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 fileDescriptor1, []int{6} }
var extRange_Real = []proto.ExtensionRange{
{100, 536870911},
}
func (*Real) ExtensionRangeArray() []proto.ExtensionRange {
return extRange_Real
}
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"`
proto.XXX_InternalExtensions `json:"-"`
XXX_unrecognized []byte `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 fileDescriptor1, []int{7} }
var extRange_Complex = []proto.ExtensionRange{
{100, 536870911},
}
func (*Complex) ExtensionRangeArray() []proto.ExtensionRange {
return extRange_Complex
}
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.Complex.real_extension",
Tag: "bytes,123,opt,name=real_extension,json=realExtension",
Filename: "test_objects.proto",
}
type KnownTypes struct {
An *google_protobuf.Any `protobuf:"bytes,14,opt,name=an" json:"an,omitempty"`
Dur *google_protobuf1.Duration `protobuf:"bytes,1,opt,name=dur" json:"dur,omitempty"`
St *google_protobuf2.Struct `protobuf:"bytes,12,opt,name=st" json:"st,omitempty"`
Ts *google_protobuf3.Timestamp `protobuf:"bytes,2,opt,name=ts" json:"ts,omitempty"`
Lv *google_protobuf2.ListValue `protobuf:"bytes,15,opt,name=lv" json:"lv,omitempty"`
Val *google_protobuf2.Value `protobuf:"bytes,16,opt,name=val" json:"val,omitempty"`
Dbl *google_protobuf4.DoubleValue `protobuf:"bytes,3,opt,name=dbl" json:"dbl,omitempty"`
Flt *google_protobuf4.FloatValue `protobuf:"bytes,4,opt,name=flt" json:"flt,omitempty"`
I64 *google_protobuf4.Int64Value `protobuf:"bytes,5,opt,name=i64" json:"i64,omitempty"`
U64 *google_protobuf4.UInt64Value `protobuf:"bytes,6,opt,name=u64" json:"u64,omitempty"`
I32 *google_protobuf4.Int32Value `protobuf:"bytes,7,opt,name=i32" json:"i32,omitempty"`
U32 *google_protobuf4.UInt32Value `protobuf:"bytes,8,opt,name=u32" json:"u32,omitempty"`
Bool *google_protobuf4.BoolValue `protobuf:"bytes,9,opt,name=bool" json:"bool,omitempty"`
Str *google_protobuf4.StringValue `protobuf:"bytes,10,opt,name=str" json:"str,omitempty"`
Bytes *google_protobuf4.BytesValue `protobuf:"bytes,11,opt,name=bytes" json:"bytes,omitempty"`
XXX_unrecognized []byte `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 fileDescriptor1, []int{8} }
func (m *KnownTypes) GetAn() *google_protobuf.Any {
if m != nil {
return m.An
}
return nil
}
func (m *KnownTypes) GetDur() *google_protobuf1.Duration {
if m != nil {
return m.Dur
}
return nil
}
func (m *KnownTypes) GetSt() *google_protobuf2.Struct {
if m != nil {
return m.St
}
return nil
}
func (m *KnownTypes) GetTs() *google_protobuf3.Timestamp {
if m != nil {
return m.Ts
}
return nil
}
func (m *KnownTypes) GetLv() *google_protobuf2.ListValue {
if m != nil {
return m.Lv
}
return nil
}
func (m *KnownTypes) GetVal() *google_protobuf2.Value {
if m != nil {
return m.Val
}
return nil
}
func (m *KnownTypes) GetDbl() *google_protobuf4.DoubleValue {
if m != nil {
return m.Dbl
}
return nil
}
func (m *KnownTypes) GetFlt() *google_protobuf4.FloatValue {
if m != nil {
return m.Flt
}
return nil
}
func (m *KnownTypes) GetI64() *google_protobuf4.Int64Value {
if m != nil {
return m.I64
}
return nil
}
func (m *KnownTypes) GetU64() *google_protobuf4.UInt64Value {
if m != nil {
return m.U64
}
return nil
}
func (m *KnownTypes) GetI32() *google_protobuf4.Int32Value {
if m != nil {
return m.I32
}
return nil
}
func (m *KnownTypes) GetU32() *google_protobuf4.UInt32Value {
if m != nil {
return m.U32
}
return nil
}
func (m *KnownTypes) GetBool() *google_protobuf4.BoolValue {
if m != nil {
return m.Bool
}
return nil
}
func (m *KnownTypes) GetStr() *google_protobuf4.StringValue {
if m != nil {
return m.Str
}
return nil
}
func (m *KnownTypes) GetBytes() *google_protobuf4.BytesValue {
if m != nil {
return m.Bytes
}
return nil
}
var E_Name = &proto.ExtensionDesc{
ExtendedType: (*Real)(nil),
ExtensionType: (*string)(nil),
Field: 124,
Name: "jsonpb.name",
Tag: "bytes,124,opt,name=name",
Filename: "test_objects.proto",
}
func init() {
proto.RegisterType((*Simple)(nil), "jsonpb.Simple")
proto.RegisterType((*NonFinites)(nil), "jsonpb.NonFinites")
proto.RegisterType((*Repeats)(nil), "jsonpb.Repeats")
proto.RegisterType((*Widget)(nil), "jsonpb.Widget")
proto.RegisterType((*Maps)(nil), "jsonpb.Maps")
proto.RegisterType((*MsgWithOneof)(nil), "jsonpb.MsgWithOneof")
proto.RegisterType((*Real)(nil), "jsonpb.Real")
proto.RegisterType((*Complex)(nil), "jsonpb.Complex")
proto.RegisterType((*KnownTypes)(nil), "jsonpb.KnownTypes")
proto.RegisterEnum("jsonpb.Widget_Color", Widget_Color_name, Widget_Color_value)
proto.RegisterExtension(E_Complex_RealExtension)
proto.RegisterExtension(E_Name)
}
func init() { proto.RegisterFile("test_objects.proto", fileDescriptor1) }
var fileDescriptor1 = []byte{
// 1160 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x95, 0x41, 0x73, 0xdb, 0x44,
0x14, 0xc7, 0x23, 0xc9, 0x92, 0xed, 0x75, 0x92, 0x9a, 0x6d, 0xda, 0x2a, 0x26, 0x80, 0xc6, 0x94,
0x22, 0x0a, 0x75, 0x07, 0xc7, 0xe3, 0x61, 0x0a, 0x97, 0xa4, 0x71, 0x29, 0x43, 0x13, 0x98, 0x4d,
0x43, 0x8f, 0x1e, 0x39, 0x5a, 0xbb, 0x2a, 0xf2, 0xae, 0x67, 0x77, 0x95, 0xd4, 0x03, 0x87, 0x9c,
0x39, 0x32, 0x7c, 0x05, 0xf8, 0x08, 0x1c, 0xf8, 0x74, 0xcc, 0xdb, 0x95, 0xac, 0xc4, 0x8e, 0x4f,
0xf1, 0x7b, 0xef, 0xff, 0xfe, 0x59, 0xed, 0x6f, 0x77, 0x1f, 0xc2, 0x8a, 0x4a, 0x35, 0xe4, 0xa3,
0x77, 0xf4, 0x5c, 0xc9, 0xce, 0x4c, 0x70, 0xc5, 0xb1, 0xf7, 0x4e, 0x72, 0x36, 0x1b, 0xb5, 0x76,
0x27, 0x9c, 0x4f, 0x52, 0xfa, 0x54, 0x67, 0x47, 0xd9, 0xf8, 0x69, 0xc4, 0xe6, 0x46, 0xd2, 0xfa,
0x78, 0xb9, 0x14, 0x67, 0x22, 0x52, 0x09, 0x67, 0x79, 0x7d, 0x6f, 0xb9, 0x2e, 0x95, 0xc8, 0xce,
0x55, 0x5e, 0xfd, 0x64, 0xb9, 0xaa, 0x92, 0x29, 0x95, 0x2a, 0x9a, 0xce, 0xd6, 0xd9, 0x5f, 0x8a,
0x68, 0x36, 0xa3, 0x22, 0x5f, 0x61, 0xfb, 0x6f, 0x1b, 0x79, 0xa7, 0xc9, 0x74, 0x96, 0x52, 0x7c,
0x0f, 0x79, 0x7c, 0x38, 0xe2, 0x3c, 0xf5, 0xad, 0xc0, 0x0a, 0x6b, 0xc4, 0xe5, 0x87, 0x9c, 0xa7,
0xf8, 0x01, 0xaa, 0xf2, 0x61, 0xc2, 0xd4, 0x7e, 0xd7, 0xb7, 0x03, 0x2b, 0x74, 0x89, 0xc7, 0x7f,
0x80, 0x68, 0x51, 0xe8, 0xf7, 0x7c, 0x27, 0xb0, 0x42, 0xc7, 0x14, 0xfa, 0x3d, 0xbc, 0x8b, 0x6a,
0x7c, 0x98, 0x99, 0x96, 0x4a, 0x60, 0x85, 0x5b, 0xa4, 0xca, 0xcf, 0x74, 0x58, 0x96, 0xfa, 0x3d,
0xdf, 0x0d, 0xac, 0xb0, 0x92, 0x97, 0x8a, 0x2e, 0x69, 0xba, 0xbc, 0xc0, 0x0a, 0x3f, 0x20, 0x55,
0x7e, 0x7a, 0xad, 0x4b, 0x9a, 0xae, 0x6a, 0x60, 0x85, 0x38, 0x2f, 0xf5, 0x7b, 0x66, 0x11, 0xe3,
0x94, 0x47, 0xca, 0xaf, 0x05, 0x56, 0x68, 0x13, 0x8f, 0xbf, 0x80, 0xc8, 0xf4, 0xc4, 0x3c, 0x1b,
0xa5, 0xd4, 0xaf, 0x07, 0x56, 0x68, 0x91, 0x2a, 0x3f, 0xd2, 0x61, 0x6e, 0xa7, 0x44, 0xc2, 0x26,
0x3e, 0x0a, 0xac, 0xb0, 0x0e, 0x76, 0x3a, 0x34, 0x76, 0xa3, 0xb9, 0xa2, 0xd2, 0x6f, 0x04, 0x56,
0xb8, 0x49, 0x3c, 0x7e, 0x08, 0x51, 0xfb, 0x4f, 0x0b, 0xa1, 0x13, 0xce, 0x5e, 0x24, 0x2c, 0x51,
0x54, 0xe2, 0xbb, 0xc8, 0x1d, 0x0f, 0x59, 0xc4, 0xf4, 0x56, 0xd9, 0xa4, 0x32, 0x3e, 0x89, 0x18,
0x6c, 0xe0, 0x78, 0x38, 0x4b, 0xd8, 0x58, 0x6f, 0x94, 0x4d, 0xdc, 0xf1, 0xcf, 0x09, 0x1b, 0x9b,
0x34, 0x83, 0xb4, 0x93, 0xa7, 0x4f, 0x20, 0x7d, 0x17, 0xb9, 0xb1, 0xb6, 0xa8, 0xe8, 0xd5, 0x55,
0xe2, 0xdc, 0x22, 0x36, 0x16, 0xae, 0xce, 0xba, 0x71, 0x61, 0x11, 0x1b, 0x0b, 0x2f, 0x4f, 0x83,
0x45, 0xfb, 0x1f, 0x1b, 0x55, 0x09, 0x9d, 0xd1, 0x48, 0x49, 0x90, 0x88, 0x82, 0x9e, 0x03, 0xf4,
0x44, 0x41, 0x4f, 0x2c, 0xe8, 0x39, 0x40, 0x4f, 0x2c, 0xe8, 0x89, 0x05, 0x3d, 0x07, 0xe8, 0x89,
0x05, 0x3d, 0x51, 0xd2, 0x73, 0x80, 0x9e, 0x28, 0xe9, 0x89, 0x92, 0x9e, 0x03, 0xf4, 0x44, 0x49,
0x4f, 0x94, 0xf4, 0x1c, 0xa0, 0x27, 0x4e, 0xaf, 0x75, 0x2d, 0xe8, 0x39, 0x40, 0x4f, 0x94, 0xf4,
0xc4, 0x82, 0x9e, 0x03, 0xf4, 0xc4, 0x82, 0x9e, 0x28, 0xe9, 0x39, 0x40, 0x4f, 0x94, 0xf4, 0x44,
0x49, 0xcf, 0x01, 0x7a, 0xa2, 0xa4, 0x27, 0x16, 0xf4, 0x1c, 0xa0, 0x27, 0x0c, 0xbd, 0x7f, 0x6d,
0xe4, 0xbd, 0x49, 0xe2, 0x09, 0x55, 0xf8, 0x31, 0x72, 0xcf, 0x79, 0xca, 0x85, 0x26, 0xb7, 0xdd,
0xdd, 0xe9, 0x98, 0x2b, 0xda, 0x31, 0xe5, 0xce, 0x73, 0xa8, 0x11, 0x23, 0xc1, 0x4f, 0xc0, 0xcf,
0xa8, 0x61, 0xf3, 0xd6, 0xa9, 0x3d, 0xa1, 0xff, 0xe2, 0x47, 0xc8, 0x93, 0xfa, 0x2a, 0xe9, 0x53,
0xd5, 0xe8, 0x6e, 0x17, 0x6a, 0x73, 0xc1, 0x48, 0x5e, 0xc5, 0x5f, 0x98, 0x0d, 0xd1, 0x4a, 0x58,
0xe7, 0xaa, 0x12, 0x36, 0x28, 0x97, 0x56, 0x85, 0x01, 0xec, 0xef, 0x68, 0xcf, 0x3b, 0x85, 0x32,
0xe7, 0x4e, 0x8a, 0x3a, 0xfe, 0x0a, 0xd5, 0xc5, 0xb0, 0x10, 0xdf, 0xd3, 0xb6, 0x2b, 0xe2, 0x9a,
0xc8, 0x7f, 0xb5, 0x3f, 0x43, 0xae, 0x59, 0x74, 0x15, 0x39, 0x64, 0x70, 0xd4, 0xdc, 0xc0, 0x75,
0xe4, 0x7e, 0x4f, 0x06, 0x83, 0x93, 0xa6, 0x85, 0x6b, 0xa8, 0x72, 0xf8, 0xea, 0x6c, 0xd0, 0xb4,
0xdb, 0x7f, 0xd9, 0xa8, 0x72, 0x1c, 0xcd, 0x24, 0xfe, 0x16, 0x35, 0xa6, 0xe6, 0xb8, 0xc0, 0xde,
0xeb, 0x33, 0xd6, 0xe8, 0x7e, 0x58, 0xf8, 0x83, 0xa4, 0x73, 0xac, 0xcf, 0xcf, 0xa9, 0x12, 0x03,
0xa6, 0xc4, 0x9c, 0xd4, 0xa7, 0x45, 0x8c, 0x0f, 0xd0, 0xd6, 0x54, 0x9f, 0xcd, 0xe2, 0xab, 0x6d,
0xdd, 0xfe, 0xd1, 0xcd, 0x76, 0x38, 0xaf, 0xe6, 0xb3, 0x8d, 0x41, 0x63, 0x5a, 0x66, 0x5a, 0xdf,
0xa1, 0xed, 0x9b, 0xfe, 0xb8, 0x89, 0x9c, 0x5f, 0xe9, 0x5c, 0x63, 0x74, 0x08, 0xfc, 0xc4, 0x3b,
0xc8, 0xbd, 0x88, 0xd2, 0x8c, 0xea, 0xeb, 0x57, 0x27, 0x26, 0x78, 0x66, 0x7f, 0x63, 0xb5, 0x4e,
0x50, 0x73, 0xd9, 0xfe, 0x7a, 0x7f, 0xcd, 0xf4, 0x3f, 0xbc, 0xde, 0xbf, 0x0a, 0xa5, 0xf4, 0x6b,
0xff, 0x61, 0xa1, 0xcd, 0x63, 0x39, 0x79, 0x93, 0xa8, 0xb7, 0x3f, 0x31, 0xca, 0xc7, 0xf8, 0x3e,
0x72, 0x55, 0xa2, 0x52, 0xaa, 0xed, 0xea, 0x2f, 0x37, 0x88, 0x09, 0xb1, 0x8f, 0x3c, 0x19, 0xa5,
0x91, 0x98, 0x6b, 0x4f, 0xe7, 0xe5, 0x06, 0xc9, 0x63, 0xdc, 0x42, 0xd5, 0xe7, 0x3c, 0x83, 0x95,
0xe8, 0x67, 0x01, 0x7a, 0x8a, 0x04, 0xfe, 0x14, 0x6d, 0xbe, 0xe5, 0x53, 0x3a, 0x8c, 0xe2, 0x58,
0x50, 0x29, 0xf5, 0x0b, 0x01, 0x82, 0x06, 0x64, 0x0f, 0x4c, 0xf2, 0xb0, 0x8a, 0xdc, 0x8c, 0x25,
0x9c, 0xb5, 0x1f, 0xa1, 0x0a, 0xa1, 0x51, 0x5a, 0x7e, 0xbe, 0x65, 0xde, 0x08, 0x1d, 0x3c, 0xae,
0xd5, 0xe2, 0xe6, 0xd5, 0xd5, 0xd5, 0x95, 0xdd, 0xbe, 0x84, 0xff, 0x08, 0x5f, 0xf2, 0x1e, 0xef,
0xa1, 0x7a, 0x32, 0x8d, 0x26, 0x09, 0x83, 0x95, 0x19, 0x79, 0x99, 0x28, 0x5b, 0xba, 0x47, 0x68,
0x5b, 0xd0, 0x28, 0x1d, 0xd2, 0xf7, 0x8a, 0x32, 0x99, 0x70, 0x86, 0x37, 0xcb, 0x23, 0x15, 0xa5,
0xfe, 0x6f, 0x37, 0xcf, 0x64, 0x6e, 0x4f, 0xb6, 0xa0, 0x69, 0x50, 0xf4, 0xb4, 0xff, 0x73, 0x11,
0xfa, 0x91, 0xf1, 0x4b, 0xf6, 0x7a, 0x3e, 0xa3, 0x12, 0x3f, 0x44, 0x76, 0xc4, 0xfc, 0x6d, 0xdd,
0xba, 0xd3, 0x31, 0xf3, 0xa9, 0x53, 0xcc, 0xa7, 0xce, 0x01, 0x9b, 0x13, 0x3b, 0x62, 0xf8, 0x4b,
0xe4, 0xc4, 0x99, 0xb9, 0xa5, 0x8d, 0xee, 0xee, 0x8a, 0xec, 0x28, 0x9f, 0x92, 0x04, 0x54, 0xf8,
0x73, 0x64, 0x4b, 0xe5, 0x6f, 0x6a, 0xed, 0x83, 0x15, 0xed, 0xa9, 0x9e, 0x98, 0xc4, 0x96, 0x70,
0xfb, 0x6d, 0x25, 0x73, 0xbe, 0xad, 0x15, 0xe1, 0xeb, 0x62, 0x78, 0x12, 0x5b, 0x49, 0xd0, 0xa6,
0x17, 0xfe, 0x9d, 0x35, 0xda, 0x57, 0x89, 0x54, 0xbf, 0xc0, 0x0e, 0x13, 0x3b, 0xbd, 0xc0, 0x21,
0x72, 0x2e, 0xa2, 0xd4, 0x6f, 0x6a, 0xf1, 0xfd, 0x15, 0xb1, 0x11, 0x82, 0x04, 0x77, 0x90, 0x13,
0x8f, 0x52, 0xcd, 0xbc, 0xd1, 0xdd, 0x5b, 0xfd, 0x2e, 0xfd, 0xc8, 0xe5, 0xfa, 0x78, 0x94, 0xe2,
0x27, 0xc8, 0x19, 0xa7, 0x4a, 0x1f, 0x01, 0xb8, 0x70, 0xcb, 0x7a, 0xfd, 0x5c, 0xe6, 0xf2, 0x71,
0xaa, 0x40, 0x9e, 0xe4, 0xb3, 0xf5, 0x36, 0xb9, 0xbe, 0x42, 0xb9, 0x3c, 0xe9, 0xf7, 0x60, 0x35,
0x59, 0xbf, 0xa7, 0xa7, 0xca, 0x6d, 0xab, 0x39, 0xbb, 0xae, 0xcf, 0xfa, 0x3d, 0x6d, 0xbf, 0xdf,
0xd5, 0x43, 0x78, 0x8d, 0xfd, 0x7e, 0xb7, 0xb0, 0xdf, 0xef, 0x6a, 0xfb, 0xfd, 0xae, 0x9e, 0xcc,
0xeb, 0xec, 0x17, 0xfa, 0x4c, 0xeb, 0x2b, 0x7a, 0x84, 0xd5, 0xd7, 0x6c, 0x3a, 0xdc, 0x61, 0x23,
0xd7, 0x3a, 0xf0, 0x87, 0xd7, 0x08, 0xad, 0xf1, 0x37, 0x63, 0x21, 0xf7, 0x97, 0x4a, 0xe0, 0xaf,
0x91, 0x5b, 0x0e, 0xf7, 0xdb, 0x3e, 0x40, 0x8f, 0x0b, 0xd3, 0x60, 0x94, 0xcf, 0x02, 0x54, 0x61,
0xd1, 0x94, 0x2e, 0x1d, 0xfc, 0xdf, 0xf5, 0x0b, 0xa3, 0x2b, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff,
0xd5, 0x39, 0x32, 0x09, 0xf9, 0x09, 0x00, 0x00,
}

View File

@@ -31,6 +31,12 @@
syntax = "proto2";
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 message for holding primitive types.
@@ -48,6 +54,16 @@ message Simple {
optional bytes o_bytes = 11;
}
// 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;
@@ -89,6 +105,8 @@ message MsgWithOneof {
oneof union {
string title = 1;
int64 salary = 2;
string Country = 3;
string home_address = 4;
}
}
@@ -108,3 +126,22 @@ message Complex {
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;
}

View File

@@ -39,5 +39,5 @@ test: install generate-test-pbs
generate-test-pbs:
make install
make -C testdata
protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata:. proto3_proto/proto3.proto
protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata,Mgoogle/protobuf/any.proto=github.com/golang/protobuf/ptypes/any:. proto3_proto/proto3.proto
make

View File

@@ -420,7 +420,7 @@ func TestMarshalerEncoding(t *testing.T) {
name string
m Message
want []byte
wantErr error
errType reflect.Type
}{
{
name: "Marshaler that fails",
@@ -428,9 +428,11 @@ func TestMarshalerEncoding(t *testing.T) {
err: errors.New("some marshal err"),
b: []byte{5, 6, 7},
},
// Since there's an error, nothing should be written to buffer.
want: nil,
wantErr: errors.New("some marshal err"),
// Since the Marshal method returned bytes, they should be written to the
// buffer. (For efficiency, we assume that Marshal implementations are
// always correct w.r.t. RequiredNotSetError and output.)
want: []byte{5, 6, 7},
errType: reflect.TypeOf(errors.New("some marshal err")),
},
{
name: "Marshaler that fails with RequiredNotSetError",
@@ -446,30 +448,37 @@ func TestMarshalerEncoding(t *testing.T) {
10, 3, // for &msgWithFakeMarshaler
5, 6, 7, // for &fakeMarshaler
},
wantErr: &RequiredNotSetError{},
errType: reflect.TypeOf(&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},
wantErr: nil,
want: []byte{0, 1, 2, 3, 4, 127, 255},
},
}
for _, test := range tests {
b := NewBuffer(nil)
err := b.Marshal(test.m)
if _, ok := err.(*RequiredNotSetError); ok {
// We're not in package proto, so we can only assert the type in this case.
err = &RequiredNotSetError{}
}
if !reflect.DeepEqual(test.wantErr, err) {
t.Errorf("%s: got err %v wanted %v", test.name, err, test.wantErr)
if reflect.TypeOf(err) != test.errType {
t.Errorf("%s: got err %T(%v) wanted %T", test.name, err, err, test.errType)
}
if !reflect.DeepEqual(test.want, b.Bytes()) {
t.Errorf("%s: got bytes %v wanted %v", test.name, b.Bytes(), test.want)
}
if size := Size(test.m); size != len(b.Bytes()) {
t.Errorf("%s: Size(_) = %v, but marshaled to %v bytes", test.name, size, len(b.Bytes()))
}
m, mErr := Marshal(test.m)
if !bytes.Equal(b.Bytes(), m) {
t.Errorf("%s: Marshal returned %v, but (*Buffer).Marshal wrote %v", test.name, m, b.Bytes())
}
if !reflect.DeepEqual(err, mErr) {
t.Errorf("%s: Marshal err = %q, but (*Buffer).Marshal returned %q",
test.name, fmt.Sprint(mErr), fmt.Sprint(err))
}
}
}
@@ -1302,7 +1311,7 @@ func TestEnum(t *testing.T) {
// We don't care what the value actually is, just as long as it doesn't crash.
func TestPrintingNilEnumFields(t *testing.T) {
pb := new(GoEnum)
fmt.Sprintf("%+v", pb)
_ = fmt.Sprintf("%+v", pb)
}
// Verify that absent required fields cause Marshal/Unmarshal to return errors.
@@ -1311,7 +1320,7 @@ func TestRequiredFieldEnforcement(t *testing.T) {
_, err := Marshal(pb)
if err == nil {
t.Error("marshal: expected error, got nil")
} else if strings.Index(err.Error(), "Label") < 0 {
} else if _, ok := err.(*RequiredNotSetError); !ok || !strings.Contains(err.Error(), "Label") {
t.Errorf("marshal: bad error type: %v", err)
}
@@ -1322,16 +1331,42 @@ func TestRequiredFieldEnforcement(t *testing.T) {
err = Unmarshal(buf, pb)
if err == nil {
t.Error("unmarshal: expected error, got nil")
} else if strings.Index(err.Error(), "{Unknown}") < 0 {
} else if _, ok := err.(*RequiredNotSetError); !ok || !strings.Contains(err.Error(), "{Unknown}") {
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 := &GoTestRequiredGroupField{Group: &GoTestRequiredGroupField_Group{}}
if _, err := Marshal(pb); err == nil {
t.Error("marshal: expected error, got nil")
} else if _, ok := err.(*RequiredNotSetError); !ok || !strings.Contains(err.Error(), "Group.Field") {
t.Errorf("marshal: bad error type: %v", err)
}
buf := []byte{11, 12}
if err := Unmarshal(buf, pb); err == nil {
t.Error("unmarshal: expected error, got nil")
} else if _, ok := err.(*RequiredNotSetError); !ok || !strings.Contains(err.Error(), "Group.{Unknown}") {
t.Errorf("unmarshal: bad error type: %v", err)
}
}
func TestTypedNilMarshal(t *testing.T) {
// A typed nil should return ErrNil and not crash.
_, err := Marshal((*GoEnum)(nil))
if err != ErrNil {
t.Errorf("Marshal: got err %v, want ErrNil", err)
{
var m *GoEnum
if _, err := Marshal(m); err != ErrNil {
t.Errorf("Marshal(%#v): got %v, want ErrNil", m, err)
}
}
{
m := &Communique{Union: &Communique_Msg{nil}}
if _, err := Marshal(m); err == nil || err == ErrNil {
t.Errorf("Marshal(%#v): got %v, want errOneofHasNil", m, err)
}
}
}
@@ -1947,14 +1982,88 @@ func TestMapFieldRoundTrips(t *testing.T) {
}
func TestMapFieldWithNil(t *testing.T) {
m := &MessageWithMap{
m1 := &MessageWithMap{
MsgMapping: map[int64]*FloatingPoint{
1: nil,
},
}
b, err := Marshal(m)
if err == nil {
t.Fatalf("Marshal of bad map should have failed, got these bytes: %v", b)
b, err := Marshal(m1)
if err != nil {
t.Fatalf("Marshal: %v", err)
}
m2 := new(MessageWithMap)
if err := Unmarshal(b, m2); err != nil {
t.Fatalf("Unmarshal: %v, got these bytes: %v", err, b)
}
if v, ok := m2.MsgMapping[1]; !ok {
t.Error("msg_mapping[1] not present")
} else if v != nil {
t.Errorf("msg_mapping[1] not nil: %v", v)
}
}
func TestMapFieldWithNilBytes(t *testing.T) {
m1 := &MessageWithMap{
ByteMapping: map[bool][]byte{
false: []byte{},
true: nil,
},
}
n := Size(m1)
b, err := 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(MessageWithMap)
if err := 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 := &MessageWithMap{}
err := Unmarshal(b, got)
if err != nil {
t.Fatalf("failed to marshal map with missing key: %v", err)
}
want := &MessageWithMap{NameMapping: map[int32]string{0: "m"}}
if !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 := []byte{
0x0A, 0x02, // message, tag 1 (name_mapping), of length 2 bytes
0x08, 0x01, // varint key, value 1
// no value
}
got := &MessageWithMap{}
err := Unmarshal(b, got)
if err != nil {
t.Fatalf("failed to marshal map with missing value: %v", err)
}
want := &MessageWithMap{NameMapping: map[int32]string{1: ""}}
if !Equal(got, want) {
t.Errorf("Unmarshaled map with no value was not as expected. got: %v, want %v", got, want)
}
}

300
vendor/github.com/golang/protobuf/proto/any_test.go generated vendored Normal file
View File

@@ -0,0 +1,300 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// 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.
package proto_test
import (
"strings"
"testing"
"github.com/golang/protobuf/proto"
pb "github.com/golang/protobuf/proto/proto3_proto"
testpb "github.com/golang/protobuf/proto/testdata"
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 := &pb.Nested{Bunny: "Monty"}
nb, err := proto.Marshal(nested)
if err != nil {
panic(err)
}
m1 := &pb.Message{
Name: "David",
ResultCount: 47,
Anything: &anypb.Any{TypeUrl: "type.googleapis.com/" + proto.MessageName(nested), Value: nb},
}
m2 := &pb.Message{
Name: "David",
ResultCount: 47,
Anything: &anypb.Any{TypeUrl: "http://[::1]/type.googleapis.com/" + proto.MessageName(nested), Value: nb},
}
m3 := &pb.Message{
Name: "David",
ResultCount: 47,
Anything: &anypb.Any{TypeUrl: `type.googleapis.com/"/` + proto.MessageName(nested), Value: nb},
}
m4 := &pb.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 := &testpb.MyMessage{Count: proto.Int32(47), Name: proto.String("David")}
proto.SetExtension(any1, testpb.E_Ext_More, &testpb.Ext{Data: proto.String("foo")})
proto.SetExtension(any1, testpb.E_Ext_Text, proto.String("bar"))
any1b, err := proto.Marshal(any1)
if err != nil {
panic(err)
}
any2 := &testpb.MyMessage{Count: proto.Int32(42), Bikeshed: testpb.MyMessage_GREEN.Enum(), RepBytes: [][]byte{[]byte("roboto")}}
proto.SetExtension(any2, testpb.E_Ext_More, &testpb.Ext{Data: proto.String("baz")})
any2b, err := proto.Marshal(any2)
if err != nil {
panic(err)
}
m6 := &pb.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_proto.Nested]: <
bunny: "Monty"
>
>
`
m2Golden = `
name: "David"
result_count: 47
anything: <
["http://[::1]/type.googleapis.com/proto3_proto.Nested"]: <
bunny: "Monty"
>
>
`
m3Golden = `
name: "David"
result_count: 47
anything: <
["type.googleapis.com/\"/proto3_proto.Nested"]: <
bunny: "Monty"
>
>
`
m4Golden = `
name: "David"
result_count: 47
anything: <
[type.googleapis.com/a/path/proto3_proto.Nested]: <
bunny: "Monty"
>
>
`
m5Golden = `
[type.googleapis.com/proto3_proto.Nested]: <
bunny: "Monty"
>
`
m6Golden = `
name: "David"
result_count: 47
anything: <
[type.googleapis.com/testdata.MyMessage]: <
count: 47
name: "David"
[testdata.Ext.more]: <
data: "foo"
>
[testdata.Ext.text]: "bar"
>
>
many_things: <
[type.googleapis.com/testdata.MyMessage]: <
count: 42
bikeshed: GREEN
rep_bytes: "roboto"
[testdata.Ext.more]: <
data: "baz"
>
>
>
many_things: <
[type.googleapis.com/testdata.MyMessage]: <
count: 47
name: "David"
[testdata.Ext.more]: <
data: "foo"
>
[testdata.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 {
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 {
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 := &pb.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_proto.Nested"
value: "\n\x05Monty"
`, pb)
t.Logf("result: %v (error: %v)", expandedMarshaler.Text(pb), err)
if err != nil {
t.Errorf("failed to parse ambiguous Any message: %v", err)
}
}
func TestUnmarshalOverwriteAny(t *testing.T) {
pb := &anypb.Any{}
err := proto.UnmarshalText(`
[type.googleapis.com/a/path/proto3_proto.Nested]: <
bunny: "Monty"
>
[type.googleapis.com/a/path/proto3_proto.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.\nHave: %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_proto.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.\nHave: %v\nWant: %v", err.Error(), want)
}
}

View File

@@ -84,9 +84,15 @@ func mergeStruct(out, in reflect.Value) {
mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
}
if emIn, ok := in.Addr().Interface().(extendableProto); ok {
emOut := out.Addr().Interface().(extendableProto)
mergeExtension(emOut.ExtensionMap(), emIn.ExtensionMap())
if emIn, ok := extendable(in.Addr().Interface()); ok {
emOut, _ := extendable(out.Addr().Interface())
mIn, muIn := emIn.extensionsRead()
if mIn != nil {
mOut := emOut.extensionsWrite()
muIn.Lock()
mergeExtension(mOut, mIn)
muIn.Unlock()
}
}
uf := in.FieldByName("XXX_unrecognized")

View File

@@ -195,6 +195,9 @@ var mergeTests = []struct {
NameMapping: map[int32]string{6: "Nigel"},
MsgMapping: map[int64]*pb.FloatingPoint{
0x4001: &pb.FloatingPoint{F: proto.Float64(2.0)},
0x4002: &pb.FloatingPoint{
F: proto.Float64(2.0),
},
},
ByteMapping: map[bool][]byte{true: []byte("wowsa")},
},
@@ -203,6 +206,12 @@ var mergeTests = []struct {
6: "Bruce", // should be overwritten
7: "Andrew",
},
MsgMapping: map[int64]*pb.FloatingPoint{
0x4002: &pb.FloatingPoint{
F: proto.Float64(3.0),
Exact: proto.Bool(true),
}, // the entire message should be overwritten
},
},
want: &pb.MessageWithMap{
NameMapping: map[int32]string{
@@ -211,6 +220,9 @@ var mergeTests = []struct {
},
MsgMapping: map[int64]*pb.FloatingPoint{
0x4001: &pb.FloatingPoint{F: proto.Float64(2.0)},
0x4002: &pb.FloatingPoint{
F: proto.Float64(2.0),
},
},
ByteMapping: map[bool][]byte{true: []byte("wowsa")},
},
@@ -254,6 +266,27 @@ var mergeTests = []struct {
Union: &pb.Communique_Name{"Bobby Tables"},
},
},
{
src: &proto3pb.Message{
Terrain: map[string]*proto3pb.Nested{
"kay_a": &proto3pb.Nested{Cute: true}, // replace
"kay_b": &proto3pb.Nested{Bunny: "rabbit"}, // insert
},
},
dst: &proto3pb.Message{
Terrain: map[string]*proto3pb.Nested{
"kay_a": &proto3pb.Nested{Bunny: "lost"}, // replaced
"kay_c": &proto3pb.Nested{Bunny: "bunny"}, // keep
},
},
want: &proto3pb.Message{
Terrain: map[string]*proto3pb.Nested{
"kay_a": &proto3pb.Nested{Cute: true},
"kay_b": &proto3pb.Nested{Bunny: "rabbit"},
"kay_c": &proto3pb.Nested{Bunny: "bunny"},
},
},
},
}
func TestMerge(t *testing.T) {

View File

@@ -61,7 +61,6 @@ var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for
// int32, int64, uint32, uint64, bool, and enum
// protocol buffer types.
func DecodeVarint(buf []byte) (x uint64, n int) {
// x, n already 0
for shift := uint(0); shift < 64; shift += 7 {
if n >= len(buf) {
return 0, 0
@@ -78,13 +77,7 @@ func DecodeVarint(buf []byte) (x uint64, n int) {
return 0, 0
}
// DecodeVarint reads a varint-encoded integer from the Buffer.
// This is the format for the
// int32, int64, uint32, uint64, bool, and enum
// protocol buffer types.
func (p *Buffer) DecodeVarint() (x uint64, err error) {
// x, err already 0
func (p *Buffer) decodeVarintSlow() (x uint64, err error) {
i := p.index
l := len(p.buf)
@@ -107,6 +100,107 @@ func (p *Buffer) DecodeVarint() (x uint64, err error) {
return
}
// DecodeVarint reads a varint-encoded integer from the Buffer.
// This is the format for the
// int32, int64, uint32, uint64, bool, and enum
// protocol buffer types.
func (p *Buffer) DecodeVarint() (x uint64, err error) {
i := p.index
buf := p.buf
if i >= len(buf) {
return 0, io.ErrUnexpectedEOF
} else if buf[i] < 0x80 {
p.index++
return uint64(buf[i]), nil
} else if len(buf)-i < 10 {
return p.decodeVarintSlow()
}
var b uint64
// we already checked the first byte
x = uint64(buf[i]) - 0x80
i++
b = uint64(buf[i])
i++
x += b << 7
if b&0x80 == 0 {
goto done
}
x -= 0x80 << 7
b = uint64(buf[i])
i++
x += b << 14
if b&0x80 == 0 {
goto done
}
x -= 0x80 << 14
b = uint64(buf[i])
i++
x += b << 21
if b&0x80 == 0 {
goto done
}
x -= 0x80 << 21
b = uint64(buf[i])
i++
x += b << 28
if b&0x80 == 0 {
goto done
}
x -= 0x80 << 28
b = uint64(buf[i])
i++
x += b << 35
if b&0x80 == 0 {
goto done
}
x -= 0x80 << 35
b = uint64(buf[i])
i++
x += b << 42
if b&0x80 == 0 {
goto done
}
x -= 0x80 << 42
b = uint64(buf[i])
i++
x += b << 49
if b&0x80 == 0 {
goto done
}
x -= 0x80 << 49
b = uint64(buf[i])
i++
x += b << 56
if b&0x80 == 0 {
goto done
}
x -= 0x80 << 56
b = uint64(buf[i])
i++
x += b << 63
if b&0x80 == 0 {
goto done
}
// x -= 0x80 << 63 // Always zero.
return 0, errOverflow
done:
p.index = i
return x, nil
}
// DecodeFixed64 reads a 64-bit integer from the Buffer.
// This is the format for the
// fixed64, sfixed64, and double protocol buffer types.
@@ -340,6 +434,8 @@ func (p *Buffer) DecodeGroup(pb Message) error {
// Buffer and places the decoded result in pb. If the struct
// underlying pb does not match the data in the buffer, the results can be
// unpredictable.
//
// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal.
func (p *Buffer) Unmarshal(pb Message) error {
// If the object can unmarshal itself, let it.
if u, ok := pb.(Unmarshaler); ok {
@@ -378,6 +474,11 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group
wire := int(u & 0x7)
if wire == WireEndGroup {
if is_group {
if required > 0 {
// Not enough information to determine the exact field.
// (See below.)
return &RequiredNotSetError{"{Unknown}"}
}
return nil // input is satisfied
}
return fmt.Errorf("proto: %s: wiretype end group for non-group", st)
@@ -390,11 +491,12 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group
if !ok {
// Maybe it's an extension?
if prop.extendable {
if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) {
if e, _ := extendable(structPointer_Interface(base, st)); isExtensionField(e, int32(tag)) {
if err = o.skip(st, tag, wire); err == nil {
ext := e.ExtensionMap()[int32(tag)] // may be missing
extmap := e.extensionsWrite()
ext := extmap[int32(tag)] // may be missing
ext.enc = append(ext.enc, o.buf[oi:o.index]...)
e.ExtensionMap()[int32(tag)] = ext
extmap[int32(tag)] = ext
}
continue
}
@@ -768,10 +870,11 @@ func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
}
}
keyelem, valelem := keyptr.Elem(), valptr.Elem()
if !keyelem.IsValid() || !valelem.IsValid() {
// We did not decode the key or the value in the map entry.
// Either way, it's an invalid map entry.
return fmt.Errorf("proto: bad map data: missing key/val")
if !keyelem.IsValid() {
keyelem = reflect.Zero(p.mtype.Key())
}
if !valelem.IsValid() {
valelem = reflect.Zero(p.mtype.Elem())
}
v.SetMapIndex(keyelem, valelem)

258
vendor/github.com/golang/protobuf/proto/decode_test.go generated vendored Normal file
View File

@@ -0,0 +1,258 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2010 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// 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.
// +build go1.7
package proto_test
import (
"fmt"
"testing"
"github.com/golang/protobuf/proto"
tpb "github.com/golang/protobuf/proto/proto3_proto"
)
var (
bytesBlackhole []byte
msgBlackhole = new(tpb.Message)
)
// BenchmarkVarint32ArraySmall shows the performance on an array of small int32 fields (1 and
// 2 bytes long).
func BenchmarkVarint32ArraySmall(b *testing.B) {
for i := uint(1); i <= 10; i++ {
dist := genInt32Dist([7]int{0, 3, 1}, 1<<i)
raw, err := proto.Marshal(&tpb.Message{
ShortKey: dist,
})
if err != nil {
b.Error("wrong encode", err)
}
b.Run(fmt.Sprintf("Len%v", len(dist)), func(b *testing.B) {
scratchBuf := proto.NewBuffer(nil)
b.ResetTimer()
for k := 0; k < b.N; k++ {
scratchBuf.SetBuf(raw)
msgBlackhole.Reset()
if err := scratchBuf.Unmarshal(msgBlackhole); err != nil {
b.Error("wrong decode", err)
}
}
})
}
}
// BenchmarkVarint32ArrayLarge shows the performance on an array of large int32 fields (3 and
// 4 bytes long, with a small number of 1, 2, 5 and 10 byte long versions).
func BenchmarkVarint32ArrayLarge(b *testing.B) {
for i := uint(1); i <= 10; i++ {
dist := genInt32Dist([7]int{0, 1, 2, 4, 8, 1, 1}, 1<<i)
raw, err := proto.Marshal(&tpb.Message{
ShortKey: dist,
})
if err != nil {
b.Error("wrong encode", err)
}
b.Run(fmt.Sprintf("Len%v", len(dist)), func(b *testing.B) {
scratchBuf := proto.NewBuffer(nil)
b.ResetTimer()
for k := 0; k < b.N; k++ {
scratchBuf.SetBuf(raw)
msgBlackhole.Reset()
if err := scratchBuf.Unmarshal(msgBlackhole); err != nil {
b.Error("wrong decode", err)
}
}
})
}
}
// BenchmarkVarint64ArraySmall shows the performance on an array of small int64 fields (1 and
// 2 bytes long).
func BenchmarkVarint64ArraySmall(b *testing.B) {
for i := uint(1); i <= 10; i++ {
dist := genUint64Dist([11]int{0, 3, 1}, 1<<i)
raw, err := proto.Marshal(&tpb.Message{
Key: dist,
})
if err != nil {
b.Error("wrong encode", err)
}
b.Run(fmt.Sprintf("Len%v", len(dist)), func(b *testing.B) {
scratchBuf := proto.NewBuffer(nil)
b.ResetTimer()
for k := 0; k < b.N; k++ {
scratchBuf.SetBuf(raw)
msgBlackhole.Reset()
if err := scratchBuf.Unmarshal(msgBlackhole); err != nil {
b.Error("wrong decode", err)
}
}
})
}
}
// BenchmarkVarint64ArrayLarge shows the performance on an array of large int64 fields (6, 7,
// and 8 bytes long with a small number of the other sizes).
func BenchmarkVarint64ArrayLarge(b *testing.B) {
for i := uint(1); i <= 10; i++ {
dist := genUint64Dist([11]int{0, 1, 1, 2, 4, 8, 16, 32, 16, 1, 1}, 1<<i)
raw, err := proto.Marshal(&tpb.Message{
Key: dist,
})
if err != nil {
b.Error("wrong encode", err)
}
b.Run(fmt.Sprintf("Len%v", len(dist)), func(b *testing.B) {
scratchBuf := proto.NewBuffer(nil)
b.ResetTimer()
for k := 0; k < b.N; k++ {
scratchBuf.SetBuf(raw)
msgBlackhole.Reset()
if err := scratchBuf.Unmarshal(msgBlackhole); err != nil {
b.Error("wrong decode", err)
}
}
})
}
}
// BenchmarkVarint64ArrayMixed shows the performance of lots of small messages, each
// containing a small number of large (3, 4, and 5 byte) repeated int64s.
func BenchmarkVarint64ArrayMixed(b *testing.B) {
for i := uint(1); i <= 1<<5; i <<= 1 {
dist := genUint64Dist([11]int{0, 0, 0, 4, 6, 4, 0, 0, 0, 0, 0}, int(i))
// number of sub fields
for k := uint(1); k <= 1<<10; k <<= 2 {
msg := &tpb.Message{}
for m := uint(0); m < k; m++ {
msg.Children = append(msg.Children, &tpb.Message{
Key: dist,
})
}
raw, err := proto.Marshal(msg)
if err != nil {
b.Error("wrong encode", err)
}
b.Run(fmt.Sprintf("Fields%vLen%v", k, i), func(b *testing.B) {
scratchBuf := proto.NewBuffer(nil)
b.ResetTimer()
for k := 0; k < b.N; k++ {
scratchBuf.SetBuf(raw)
msgBlackhole.Reset()
if err := scratchBuf.Unmarshal(msgBlackhole); err != nil {
b.Error("wrong decode", err)
}
}
})
}
}
}
// genInt32Dist generates a slice of ints that will match the size distribution of dist.
// A size of 6 corresponds to a max length varint32, which is 10 bytes. The distribution
// is 1-indexed. (i.e. the value at index 1 is how many 1 byte ints to create).
func genInt32Dist(dist [7]int, count int) (dest []int32) {
for i := 0; i < count; i++ {
for k := 0; k < len(dist); k++ {
var num int32
switch k {
case 1:
num = 1<<7 - 1
case 2:
num = 1<<14 - 1
case 3:
num = 1<<21 - 1
case 4:
num = 1<<28 - 1
case 5:
num = 1<<29 - 1
case 6:
num = -1
}
for m := 0; m < dist[k]; m++ {
dest = append(dest, num)
}
}
}
return
}
// genUint64Dist generates a slice of ints that will match the size distribution of dist.
// The distribution is 1-indexed. (i.e. the value at index 1 is how many 1 byte ints to create).
func genUint64Dist(dist [11]int, count int) (dest []uint64) {
for i := 0; i < count; i++ {
for k := 0; k < len(dist); k++ {
var num uint64
switch k {
case 1:
num = 1<<7 - 1
case 2:
num = 1<<14 - 1
case 3:
num = 1<<21 - 1
case 4:
num = 1<<28 - 1
case 5:
num = 1<<35 - 1
case 6:
num = 1<<42 - 1
case 7:
num = 1<<49 - 1
case 8:
num = 1<<56 - 1
case 9:
num = 1<<63 - 1
case 10:
num = 1<<64 - 1
}
for m := 0; m < dist[k]; m++ {
dest = append(dest, num)
}
}
}
return
}
// BenchmarkDecodeEmpty measures the overhead of doing the minimal possible decode.
func BenchmarkDecodeEmpty(b *testing.B) {
raw, err := proto.Marshal(&tpb.Message{})
if err != nil {
b.Error("wrong encode", err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
if err := proto.Unmarshal(raw, msgBlackhole); err != nil {
b.Error("wrong decode", err)
}
}
}

View File

@@ -64,8 +64,16 @@ var (
// a struct with a repeated field containing a nil element.
errRepeatedHasNil = errors.New("proto: repeated field has nil element")
// errOneofHasNil is the error returned if Marshal is called with
// a struct with a oneof field containing a nil element.
errOneofHasNil = errors.New("proto: oneof field has nil value")
// ErrNil is the error returned if Marshal is called with nil.
ErrNil = errors.New("proto: Marshal called with nil")
// ErrTooLarge is the error returned if Marshal is called with a
// message that encodes to >2GB.
ErrTooLarge = errors.New("proto: message encodes to over 2 GB")
)
// The fundamental encoders that put bytes on the wire.
@@ -74,6 +82,10 @@ var (
const maxVarintBytes = 10 // maximum length of a varint
// maxMarshalSize is the largest allowed size of an encoded protobuf,
// since C++ and Java use signed int32s for the size.
const maxMarshalSize = 1<<31 - 1
// EncodeVarint returns the varint encoding of x.
// This is the format for the
// int32, int64, uint32, uint64, bool, and enum
@@ -162,11 +174,11 @@ func sizeFixed32(x uint64) int {
// This is the format used for the sint64 protocol buffer type.
func (p *Buffer) EncodeZigzag64(x uint64) error {
// use signed number to get arithmetic right shift.
return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
return p.EncodeVarint((x << 1) ^ uint64((int64(x) >> 63)))
}
func sizeZigzag64(x uint64) int {
return sizeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
return sizeVarint((x << 1) ^ uint64((int64(x) >> 63)))
}
// EncodeZigzag32 writes a zigzag-encoded 32-bit integer
@@ -222,10 +234,6 @@ func Marshal(pb Message) ([]byte, error) {
}
p := NewBuffer(nil)
err := p.Marshal(pb)
var state errorState
if err != nil && !state.shouldContinue(err, nil) {
return nil, err
}
if p.buf == nil && err == nil {
// Return a non-nil slice on success.
return []byte{}, nil
@@ -254,11 +262,8 @@ func (p *Buffer) Marshal(pb Message) error {
// Can the object marshal itself?
if m, ok := pb.(Marshaler); ok {
data, err := m.Marshal()
if err != nil {
return err
}
p.buf = append(p.buf, data...)
return nil
return err
}
t, base, err := getbase(pb)
@@ -270,9 +275,12 @@ func (p *Buffer) Marshal(pb Message) error {
}
if collectStats {
stats.Encode++
(stats).Encode++ // Parens are to work around a goimports bug.
}
if len(p.buf) > maxMarshalSize {
return ErrTooLarge
}
return err
}
@@ -294,7 +302,7 @@ func Size(pb Message) (n int) {
}
if collectStats {
stats.Size++
(stats).Size++ // Parens are to work around a goimports bug.
}
return
@@ -999,7 +1007,6 @@ func size_slice_struct_message(p *Properties, base structPointer) (n int) {
if p.isMarshaler {
m := structPointer_Interface(structp, p.stype).(Marshaler)
data, _ := m.Marshal()
n += len(p.tagcode)
n += sizeRawBytes(data)
continue
}
@@ -1058,10 +1065,32 @@ func size_slice_struct_group(p *Properties, base structPointer) (n int) {
// Encode an extension map.
func (o *Buffer) enc_map(p *Properties, base structPointer) error {
v := *structPointer_ExtMap(base, p.field)
if err := encodeExtensionMap(v); err != nil {
exts := structPointer_ExtMap(base, p.field)
if err := encodeExtensionsMap(*exts); err != nil {
return err
}
return o.enc_map_body(*exts)
}
func (o *Buffer) enc_exts(p *Properties, base structPointer) error {
exts := structPointer_Extensions(base, p.field)
v, mu := exts.extensionsRead()
if v == nil {
return nil
}
mu.Lock()
defer mu.Unlock()
if err := encodeExtensionsMap(v); err != nil {
return err
}
return o.enc_map_body(v)
}
func (o *Buffer) enc_map_body(v map[int32]Extension) error {
// Fast-path for common cases: zero or one extensions.
if len(v) <= 1 {
for _, e := range v {
@@ -1084,8 +1113,13 @@ func (o *Buffer) enc_map(p *Properties, base structPointer) error {
}
func size_map(p *Properties, base structPointer) int {
v := *structPointer_ExtMap(base, p.field)
return sizeExtensionMap(v)
v := structPointer_ExtMap(base, p.field)
return extensionsMapSize(*v)
}
func size_exts(p *Properties, base structPointer) int {
v := structPointer_Extensions(base, p.field)
return extensionsSize(v)
}
// Encode a map field.
@@ -1114,7 +1148,7 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil {
return err
}
if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil {
if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil && err != ErrNil {
return err
}
return nil
@@ -1124,11 +1158,6 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
for _, key := range v.MapKeys() {
val := v.MapIndex(key)
// The only illegal map entry values are nil message pointers.
if val.Kind() == reflect.Ptr && val.IsNil() {
return errors.New("proto: map has nil element")
}
keycopy.Set(key)
valcopy.Set(val)
@@ -1216,13 +1245,18 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
return err
}
}
if len(o.buf) > maxMarshalSize {
return ErrTooLarge
}
}
}
// Do oneof fields.
if prop.oneofMarshaler != nil {
m := structPointer_Interface(base, prop.stype).(Message)
if err := prop.oneofMarshaler(m, o); err != nil {
if err := prop.oneofMarshaler(m, o); err == ErrNil {
return errOneofHasNil
} else if err != nil {
return err
}
}
@@ -1230,6 +1264,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
// Add unrecognized fields at the end.
if prop.unrecField.IsValid() {
v := *structPointer_Bytes(base, prop.unrecField)
if len(o.buf)+len(v) > maxMarshalSize {
return ErrTooLarge
}
if len(v) > 0 {
o.buf = append(o.buf, v...)
}

85
vendor/github.com/golang/protobuf/proto/encode_test.go generated vendored Normal file
View File

@@ -0,0 +1,85 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2010 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// 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.
// +build go1.7
package proto_test
import (
"strconv"
"testing"
"github.com/golang/protobuf/proto"
tpb "github.com/golang/protobuf/proto/proto3_proto"
"github.com/golang/protobuf/ptypes"
)
var (
blackhole []byte
)
// BenchmarkAny creates increasingly large arbitrary Any messages. The type is always the
// same.
func BenchmarkAny(b *testing.B) {
data := make([]byte, 1<<20)
quantum := 1 << 10
for i := uint(0); i <= 10; i++ {
b.Run(strconv.Itoa(quantum<<i), func(b *testing.B) {
for k := 0; k < b.N; k++ {
inner := &tpb.Message{
Data: data[:quantum<<i],
}
outer, err := ptypes.MarshalAny(inner)
if err != nil {
b.Error("wrong encode", err)
}
raw, err := proto.Marshal(&tpb.Message{
Anything: outer,
})
if err != nil {
b.Error("wrong encode", err)
}
blackhole = raw
}
})
}
}
// BenchmarkEmpy measures the overhead of doing the minimal possible encode.
func BenchmarkEmpy(b *testing.B) {
for i := 0; i < b.N; i++ {
raw, err := proto.Marshal(&tpb.Message{})
if err != nil {
b.Error("wrong encode", err)
}
blackhole = raw
}
}

View File

@@ -54,13 +54,17 @@ Equality is defined in this way:
in a proto3 .proto file, fields are not "set"; specifically,
zero length proto3 "bytes" fields are equal (nil == {}).
- Two repeated fields are equal iff their lengths are the same,
and their corresponding elements are equal (a "bytes" field,
although represented by []byte, is not a repeated field)
and their corresponding elements are equal. Note a "bytes" field,
although represented by []byte, is not a repeated field and the
rule for the scalar fields described above applies.
- Two unset fields are equal.
- Two unknown field sets are equal if their current
encoded state is equal.
- Two extension sets are equal iff they have corresponding
elements that are pairwise equal.
- Two map fields are equal iff their lengths are the same,
and they contain the same set of elements. Zero-length map
fields are equal.
- Every other combination of things are not equal.
The return value is undefined if a and b are not protocol buffers.
@@ -121,9 +125,16 @@ func equalStruct(v1, v2 reflect.Value) bool {
}
}
if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() {
em2 := v2.FieldByName("XXX_InternalExtensions")
if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) {
return false
}
}
if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() {
em2 := v2.FieldByName("XXX_extensions")
if !equalExtensions(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {
if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {
return false
}
}
@@ -184,6 +195,13 @@ func equalAny(v1, v2 reflect.Value, prop *Properties) bool {
}
return true
case reflect.Ptr:
// Maps may have nil values in them, so check for nil.
if v1.IsNil() && v2.IsNil() {
return true
}
if v1.IsNil() != v2.IsNil() {
return false
}
return equalAny(v1.Elem(), v2.Elem(), prop)
case reflect.Slice:
if v1.Type().Elem().Kind() == reflect.Uint8 {
@@ -223,8 +241,14 @@ func equalAny(v1, v2 reflect.Value, prop *Properties) bool {
}
// base is the struct type that the extensions are based on.
// em1 and em2 are extension maps.
func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool {
// x1 and x2 are InternalExtensions.
func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool {
em1, _ := x1.extensionsRead()
em2, _ := x2.extensionsRead()
return equalExtMap(base, em1, em2)
}
func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {
if len(em1) != len(em2) {
return false
}

View File

@@ -183,6 +183,18 @@ var EqualTests = []struct {
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}},
false,
},
{
"zero-length maps same",
&pb.MessageWithMap{NameMapping: map[int32]string{}},
&pb.MessageWithMap{NameMapping: nil},
true,
},
{
"orders in map don't matter",
&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken", 2: "Rob"}},
&pb.MessageWithMap{NameMapping: map[int32]string{2: "Rob", 1: "Ken"}},
true,
},
{
"oneof same",
&pb.Communique{Union: &pb.Communique_Number{41}},

View File

@@ -52,14 +52,99 @@ type ExtensionRange struct {
Start, End int32 // both inclusive
}
// extendableProto is an interface implemented by any protocol buffer that may be extended.
// extendableProto is an interface implemented by any protocol buffer generated by the current
// proto compiler that may be extended.
type extendableProto interface {
Message
ExtensionRangeArray() []ExtensionRange
extensionsWrite() map[int32]Extension
extensionsRead() (map[int32]Extension, sync.Locker)
}
// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous
// version of the proto compiler that may be extended.
type extendableProtoV1 interface {
Message
ExtensionRangeArray() []ExtensionRange
ExtensionMap() map[int32]Extension
}
// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto.
type extensionAdapter struct {
extendableProtoV1
}
func (e extensionAdapter) extensionsWrite() map[int32]Extension {
return e.ExtensionMap()
}
func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {
return e.ExtensionMap(), notLocker{}
}
// notLocker is a sync.Locker whose Lock and Unlock methods are nops.
type notLocker struct{}
func (n notLocker) Lock() {}
func (n notLocker) Unlock() {}
// extendable returns the extendableProto interface for the given generated proto message.
// If the proto message has the old extension format, it returns a wrapper that implements
// the extendableProto interface.
func extendable(p interface{}) (extendableProto, bool) {
if ep, ok := p.(extendableProto); ok {
return ep, ok
}
if ep, ok := p.(extendableProtoV1); ok {
return extensionAdapter{ep}, ok
}
return nil, false
}
// XXX_InternalExtensions is an internal representation of proto extensions.
//
// Each generated message struct type embeds an anonymous XXX_InternalExtensions field,
// thus gaining the unexported 'extensions' method, which can be called only from the proto package.
//
// The methods of XXX_InternalExtensions are not concurrency safe in general,
// but calls to logically read-only methods such as has and get may be executed concurrently.
type XXX_InternalExtensions struct {
// The struct must be indirect so that if a user inadvertently copies a
// generated message and its embedded XXX_InternalExtensions, they
// avoid the mayhem of a copied mutex.
//
// The mutex serializes all logically read-only operations to p.extensionMap.
// It is up to the client to ensure that write operations to p.extensionMap are
// mutually exclusive with other accesses.
p *struct {
mu sync.Mutex
extensionMap map[int32]Extension
}
}
// extensionsWrite returns the extension map, creating it on first use.
func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension {
if e.p == nil {
e.p = new(struct {
mu sync.Mutex
extensionMap map[int32]Extension
})
e.p.extensionMap = make(map[int32]Extension)
}
return e.p.extensionMap
}
// extensionsRead returns the extensions map for read-only use. It may be nil.
// The caller must hold the returned mutex's lock when accessing Elements within the map.
func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) {
if e.p == nil {
return nil, nil
}
return e.p.extensionMap, &e.p.mu
}
var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem()
var extendableProtoV1Type = reflect.TypeOf((*extendableProtoV1)(nil)).Elem()
// ExtensionDesc represents an extension specification.
// Used in generated code from the protocol compiler.
@@ -69,6 +154,7 @@ type ExtensionDesc struct {
Field int32 // field number
Name string // fully-qualified name of extension, for text formatting
Tag string // protobuf tag style
Filename string // name of the file in which the extension is defined
}
func (ed *ExtensionDesc) repeated() bool {
@@ -92,8 +178,13 @@ type Extension struct {
}
// SetRawExtension is for testing only.
func SetRawExtension(base extendableProto, id int32, b []byte) {
base.ExtensionMap()[id] = Extension{enc: b}
func SetRawExtension(base Message, id int32, b []byte) {
epb, ok := extendable(base)
if !ok {
return
}
extmap := epb.extensionsWrite()
extmap[id] = Extension{enc: b}
}
// isExtensionField returns true iff the given field number is in an extension range.
@@ -108,8 +199,12 @@ func isExtensionField(pb extendableProto, field int32) bool {
// checkExtensionTypes checks that the given extension is valid for pb.
func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
var pbi interface{} = pb
// Check the extended type.
if a, b := reflect.TypeOf(pb), reflect.TypeOf(extension.ExtendedType); a != b {
if ea, ok := pbi.(extensionAdapter); ok {
pbi = ea.extendableProtoV1
}
if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b {
return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String())
}
// Check the range.
@@ -155,8 +250,19 @@ func extensionProperties(ed *ExtensionDesc) *Properties {
return prop
}
// encodeExtensionMap encodes any unmarshaled (unencoded) extensions in m.
func encodeExtensionMap(m map[int32]Extension) error {
// encode encodes any unmarshaled (unencoded) extensions in e.
func encodeExtensions(e *XXX_InternalExtensions) error {
m, mu := e.extensionsRead()
if m == nil {
return nil // fast path
}
mu.Lock()
defer mu.Unlock()
return encodeExtensionsMap(m)
}
// encode encodes any unmarshaled (unencoded) extensions in e.
func encodeExtensionsMap(m map[int32]Extension) error {
for k, e := range m {
if e.value == nil || e.desc == nil {
// Extension is only in its encoded form.
@@ -184,7 +290,17 @@ func encodeExtensionMap(m map[int32]Extension) error {
return nil
}
func sizeExtensionMap(m map[int32]Extension) (n int) {
func extensionsSize(e *XXX_InternalExtensions) (n int) {
m, mu := e.extensionsRead()
if m == nil {
return 0
}
mu.Lock()
defer mu.Unlock()
return extensionsMapSize(m)
}
func extensionsMapSize(m map[int32]Extension) (n int) {
for _, e := range m {
if e.value == nil || e.desc == nil {
// Extension is only in its encoded form.
@@ -209,26 +325,51 @@ func sizeExtensionMap(m map[int32]Extension) (n int) {
}
// HasExtension returns whether the given extension is present in pb.
func HasExtension(pb extendableProto, extension *ExtensionDesc) bool {
func HasExtension(pb Message, extension *ExtensionDesc) bool {
// TODO: Check types, field numbers, etc.?
_, ok := pb.ExtensionMap()[extension.Field]
epb, ok := extendable(pb)
if !ok {
return false
}
extmap, mu := epb.extensionsRead()
if extmap == nil {
return false
}
mu.Lock()
_, ok = extmap[extension.Field]
mu.Unlock()
return ok
}
// ClearExtension removes the given extension from pb.
func ClearExtension(pb extendableProto, extension *ExtensionDesc) {
func ClearExtension(pb Message, extension *ExtensionDesc) {
epb, ok := extendable(pb)
if !ok {
return
}
// TODO: Check types, field numbers, etc.?
delete(pb.ExtensionMap(), extension.Field)
extmap := epb.extensionsWrite()
delete(extmap, extension.Field)
}
// GetExtension parses and returns the given extension of pb.
// If the extension is not present and has no default value it returns ErrMissingExtension.
func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) {
if err := checkExtensionTypes(pb, extension); err != nil {
func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
epb, ok := extendable(pb)
if !ok {
return nil, errors.New("proto: not an extendable proto")
}
if err := checkExtensionTypes(epb, extension); err != nil {
return nil, err
}
emap := pb.ExtensionMap()
emap, mu := epb.extensionsRead()
if emap == nil {
return defaultExtensionValue(extension)
}
mu.Lock()
defer mu.Unlock()
e, ok := emap[extension.Field]
if !ok {
// defaultExtensionValue returns the default value or
@@ -332,10 +473,9 @@ func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
// GetExtensions returns a slice of the extensions present in pb that are also listed in es.
// The returned slice has the same length as es; missing extensions will appear as nil elements.
func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
epb, ok := pb.(extendableProto)
epb, ok := extendable(pb)
if !ok {
err = errors.New("proto: not an extendable proto")
return
return nil, errors.New("proto: not an extendable proto")
}
extensions = make([]interface{}, len(es))
for i, e := range es {
@@ -350,9 +490,44 @@ func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, e
return
}
// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order.
// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing
// just the Field field, which defines the extension's field number.
func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {
epb, ok := extendable(pb)
if !ok {
return nil, fmt.Errorf("proto: %T is not an extendable proto.Message", pb)
}
registeredExtensions := RegisteredExtensions(pb)
emap, mu := epb.extensionsRead()
if emap == nil {
return nil, nil
}
mu.Lock()
defer mu.Unlock()
extensions := make([]*ExtensionDesc, 0, len(emap))
for extid, e := range emap {
desc := e.desc
if desc == nil {
desc = registeredExtensions[extid]
if desc == nil {
desc = &ExtensionDesc{Field: extid}
}
}
extensions = append(extensions, desc)
}
return extensions, nil
}
// SetExtension sets the specified extension of pb to the specified value.
func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{}) error {
if err := checkExtensionTypes(pb, extension); err != nil {
func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error {
epb, ok := extendable(pb)
if !ok {
return errors.New("proto: not an extendable proto")
}
if err := checkExtensionTypes(epb, extension); err != nil {
return err
}
typ := reflect.TypeOf(extension.ExtensionType)
@@ -368,10 +543,23 @@ func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{
return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
}
pb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value}
extmap := epb.extensionsWrite()
extmap[extension.Field] = Extension{desc: extension, value: value}
return nil
}
// ClearAllExtensions clears all extensions from pb.
func ClearAllExtensions(pb Message) {
epb, ok := extendable(pb)
if !ok {
return
}
m := epb.extensionsWrite()
for k := range m {
delete(m, k)
}
}
// A global registry of extensions.
// The generated code will register the generated descriptors by calling RegisterExtension.

View File

@@ -35,17 +35,19 @@ import (
"bytes"
"fmt"
"reflect"
"sort"
"testing"
"github.com/golang/protobuf/proto"
pb "github.com/golang/protobuf/proto/testdata"
"golang.org/x/sync/errgroup"
)
func TestGetExtensionsWithMissingExtensions(t *testing.T) {
msg := &pb.MyMessage{}
ext1 := &pb.Ext{}
if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil {
t.Fatalf("Could not set ext1: %s", ext1)
t.Fatalf("Could not set ext1: %s", err)
}
exts, err := proto.GetExtensions(msg, []*proto.ExtensionDesc{
pb.E_Ext_More,
@@ -62,6 +64,58 @@ func TestGetExtensionsWithMissingExtensions(t *testing.T) {
}
}
func TestExtensionDescsWithMissingExtensions(t *testing.T) {
msg := &pb.MyMessage{Count: proto.Int32(0)}
extdesc1 := pb.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 := &pb.Ext{}
if err := proto.SetExtension(msg, extdesc1, ext1); err != nil {
t.Fatalf("Could not set ext1: %s", err)
}
extdesc2 := &proto.ExtensionDesc{
ExtendedType: (*pb.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, &proto.ExtensionDesc{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 *pb.MyMessage) bool {
ext1, err := proto.GetExtension(m, pb.E_Ext_More)
@@ -428,3 +482,55 @@ func TestUnmarshalRepeatingNonRepeatedExtension(t *testing.T) {
}
}
}
func TestClearAllExtensions(t *testing.T) {
// unregistered extension
desc := &proto.ExtensionDesc{
ExtendedType: (*pb.MyMessage)(nil),
ExtensionType: (*bool)(nil),
Field: 101010100,
Name: "emptyextension",
Tag: "varint,0,opt",
}
m := &pb.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) {
// unregistered extension
desc := &proto.ExtensionDesc{
ExtendedType: (*pb.MyMessage)(nil),
ExtensionType: (*bool)(nil),
Field: 101010100,
Name: "emptyextension",
Tag: "varint,0,opt",
}
m := &pb.MyMessage{Count: proto.Int32(4)}
if err := proto.SetExtension(m, desc, proto.Bool(true)); err != nil {
t.Errorf("proto.SetExtension(m, desc, true): got error %q, want nil", err)
}
var g errgroup.Group
for n := 3; n > 0; n-- {
g.Go(func() error {
_, err := proto.Marshal(m)
return err
})
}
if err := g.Wait(); err != nil {
t.Fatal(err)
}
}

View File

@@ -73,7 +73,6 @@ for a protocol buffer variable v:
When the .proto file specifies `syntax="proto3"`, there are some differences:
- Non-repeated fields of non-message type are values instead of pointers.
- Getters are only generated for message and oneof fields.
- Enum types do not get an Enum method.
The simplest way to describe this is to see an example.
@@ -235,6 +234,7 @@ To create and play with a Test object:
test := &pb.Test{
Label: proto.String("hello"),
Type: proto.Int32(17),
Reps: []int64{1, 2, 3},
Optionalgroup: &pb.Test_OptionalGroup{
RequiredField: proto.String("good bye"),
},
@@ -307,7 +307,7 @@ func GetStats() Stats { return stats }
// temporary Buffer and are fine for most applications.
type Buffer struct {
buf []byte // encode/decode byte stream
index int // write point
index int // read point
// pools of basic types to amortize allocation.
bools []bool
@@ -888,6 +888,10 @@ func isProto3Zero(v reflect.Value) bool {
return false
}
// ProtoPackageIsVersion2 is referenced from generated protocol buffer files
// to assert that that code is compatible with this version of the proto package.
const ProtoPackageIsVersion2 = true
// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
// to assert that that code is compatible with this version of the proto package.
const ProtoPackageIsVersion1 = true

46
vendor/github.com/golang/protobuf/proto/map_test.go generated vendored Normal file
View File

@@ -0,0 +1,46 @@
package proto_test
import (
"fmt"
"testing"
"github.com/golang/protobuf/proto"
ppb "github.com/golang/protobuf/proto/proto3_proto"
)
func marshalled() []byte {
m := &ppb.IntMaps{}
for i := 0; i < 1000; i++ {
m.Maps = append(m.Maps, &ppb.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
}
func BenchmarkConcurrentMapUnmarshal(b *testing.B) {
in := marshalled()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
var out ppb.IntMaps
if err := proto.Unmarshal(in, &out); err != nil {
b.Errorf("Can't unmarshal ppb.IntMaps: %v", err)
}
}
})
}
func BenchmarkSequentialMapUnmarshal(b *testing.B) {
in := marshalled()
b.ResetTimer()
for i := 0; i < b.N; i++ {
var out ppb.IntMaps
if err := proto.Unmarshal(in, &out); err != nil {
b.Errorf("Can't unmarshal ppb.IntMaps: %v", err)
}
}
}

View File

@@ -149,9 +149,21 @@ func skipVarint(buf []byte) []byte {
// MarshalMessageSet encodes the extension map represented by m in the message set wire format.
// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
func MarshalMessageSet(m map[int32]Extension) ([]byte, error) {
if err := encodeExtensionMap(m); err != nil {
return nil, err
func MarshalMessageSet(exts interface{}) ([]byte, error) {
var m map[int32]Extension
switch exts := exts.(type) {
case *XXX_InternalExtensions:
if err := encodeExtensions(exts); err != nil {
return nil, err
}
m, _ = exts.extensionsRead()
case map[int32]Extension:
if err := encodeExtensionsMap(exts); err != nil {
return nil, err
}
m = exts
default:
return nil, errors.New("proto: not an extension map")
}
// Sort extension IDs to provide a deterministic encoding.
@@ -178,7 +190,17 @@ func MarshalMessageSet(m map[int32]Extension) ([]byte, error) {
// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error {
func UnmarshalMessageSet(buf []byte, exts interface{}) error {
var m map[int32]Extension
switch exts := exts.(type) {
case *XXX_InternalExtensions:
m = exts.extensionsWrite()
case map[int32]Extension:
m = exts
default:
return errors.New("proto: not an extension map")
}
ms := new(messageSet)
if err := Unmarshal(buf, ms); err != nil {
return err
@@ -209,7 +231,16 @@ func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error {
// MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) {
func MarshalMessageSetJSON(exts interface{}) ([]byte, error) {
var m map[int32]Extension
switch exts := exts.(type) {
case *XXX_InternalExtensions:
m, _ = exts.extensionsRead()
case map[int32]Extension:
m = exts
default:
return nil, errors.New("proto: not an extension map")
}
var b bytes.Buffer
b.WriteByte('{')
@@ -252,7 +283,7 @@ func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) {
// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
func UnmarshalMessageSetJSON(buf []byte, m map[int32]Extension) error {
func UnmarshalMessageSetJSON(buf []byte, exts interface{}) error {
// Common-case fast path.
if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) {
return nil

View File

@@ -50,13 +50,13 @@ func TestUnmarshalMessageSetWithDuplicate(t *testing.T) {
}
t.Logf("Marshaled bytes: %q", b)
m := make(map[int32]Extension)
if err := UnmarshalMessageSet(b, m); err != nil {
var extensions XXX_InternalExtensions
if err := UnmarshalMessageSet(b, &extensions); err != nil {
t.Fatalf("UnmarshalMessageSet: %v", err)
}
ext, ok := m[12345]
ext, ok := extensions.p.extensionMap[12345]
if !ok {
t.Fatalf("Didn't retrieve extension 12345; map is %v", m)
t.Fatalf("Didn't retrieve extension 12345; map is %v", extensions.p.extensionMap)
}
// Skip wire type/field number and length varints.
got := skipVarint(skipVarint(ext.enc))

View File

@@ -29,7 +29,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// +build appengine
// +build appengine js
// This file contains an implementation of proto field accesses using package reflect.
// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
@@ -139,6 +139,11 @@ func structPointer_StringSlice(p structPointer, f field) *[]string {
return structPointer_ifield(p, f).(*[]string)
}
// Extensions returns the address of an extension map field in the struct.
func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
return structPointer_ifield(p, f).(*XXX_InternalExtensions)
}
// ExtMap returns the address of an extension map field in the struct.
func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
return structPointer_ifield(p, f).(*map[int32]Extension)

View File

@@ -29,7 +29,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// +build !appengine
// +build !appengine,!js
// This file contains the implementation of the proto field accesses using package unsafe.
@@ -126,6 +126,10 @@ func structPointer_StringSlice(p structPointer, f field) *[]string {
}
// ExtMap returns the address of an extension map field in the struct.
func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
return (*XXX_InternalExtensions)(unsafe.Pointer(uintptr(p) + uintptr(f)))
}
func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
}

View File

@@ -173,6 +173,7 @@ func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order
type Properties struct {
Name string // name of the field, for error messages
OrigName string // original name before protocol compiler (always set)
JSONName string // name to use for JSON; determined by protoc
Wire string
WireType int
Tag int
@@ -229,8 +230,9 @@ func (p *Properties) String() string {
if p.Packed {
s += ",packed"
}
if p.OrigName != p.Name {
s += ",name=" + p.OrigName
s += ",name=" + p.OrigName
if p.JSONName != p.OrigName {
s += ",json=" + p.JSONName
}
if p.proto3 {
s += ",proto3"
@@ -310,6 +312,8 @@ func (p *Properties) Parse(s string) {
p.Packed = true
case strings.HasPrefix(f, "name="):
p.OrigName = f[5:]
case strings.HasPrefix(f, "json="):
p.JSONName = f[5:]
case strings.HasPrefix(f, "enum="):
p.Enum = f[5:]
case f == "proto3":
@@ -469,17 +473,13 @@ func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lock
p.dec = (*Buffer).dec_slice_int64
p.packedDec = (*Buffer).dec_slice_packed_int64
case reflect.Uint8:
p.enc = (*Buffer).enc_slice_byte
p.dec = (*Buffer).dec_slice_byte
p.size = size_slice_byte
// This is a []byte, which is either a bytes field,
// or the value of a map field. In the latter case,
// we always encode an empty []byte, so we should not
// use the proto3 enc/size funcs.
// f == nil iff this is the key/value of a map field.
if p.proto3 && f != nil {
if p.proto3 {
p.enc = (*Buffer).enc_proto3_slice_byte
p.size = size_proto3_slice_byte
} else {
p.enc = (*Buffer).enc_slice_byte
p.size = size_slice_byte
}
case reflect.Float32, reflect.Float64:
switch t2.Bits() {
@@ -678,7 +678,8 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
propertiesMap[t] = prop
// build properties
prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType)
prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) ||
reflect.PtrTo(t).Implements(extendableProtoV1Type)
prop.unrecField = invalidField
prop.Prop = make([]*Properties, t.NumField())
prop.order = make([]int, t.NumField())
@@ -689,15 +690,22 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
name := f.Name
p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
if f.Name == "XXX_extensions" { // special case
if f.Name == "XXX_InternalExtensions" { // special case
p.enc = (*Buffer).enc_exts
p.dec = nil // not needed
p.size = size_exts
} else if f.Name == "XXX_extensions" { // special case
p.enc = (*Buffer).enc_map
p.dec = nil // not needed
p.size = size_map
}
if f.Name == "XXX_unrecognized" { // special case
} else if f.Name == "XXX_unrecognized" { // special case
prop.unrecField = toField(&f)
}
oneof := f.Tag.Get("protobuf_oneof") != "" // special case
oneof := f.Tag.Get("protobuf_oneof") // special case
if oneof != "" {
// Oneof fields don't use the traditional protobuf tag.
p.OrigName = oneof
}
prop.Prop[i] = p
prop.order[i] = i
if debug {
@@ -707,7 +715,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
}
print("\n")
}
if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && !oneof {
if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && oneof == "" {
fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
}
}
@@ -836,7 +844,29 @@ func RegisterType(x Message, name string) {
}
// MessageName returns the fully-qualified proto name for the given message type.
func MessageName(x Message) string { return revProtoTypes[reflect.TypeOf(x)] }
func MessageName(x Message) string {
type xname interface {
XXX_MessageName() string
}
if m, ok := x.(xname); ok {
return m.XXX_MessageName()
}
return revProtoTypes[reflect.TypeOf(x)]
}
// MessageType returns the message type (pointer to struct) for a named message.
func MessageType(name string) reflect.Type { return protoTypes[name] }
// A registry of all linked proto files.
var (
protoFiles = make(map[string][]byte) // file name => fileDescriptor
)
// RegisterFile is called from generated code and maps from the
// full file name of a .proto file to its compressed FileDescriptorProto.
func RegisterFile(filename string, fileDescriptor []byte) {
protoFiles[filename] = fileDescriptor
}
// FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
func FileDescriptor(filename string) []byte { return protoFiles[filename] }

View File

@@ -0,0 +1,347 @@
// Code generated by protoc-gen-go.
// source: proto3_proto/proto3.proto
// DO NOT EDIT!
/*
Package proto3_proto is a generated protocol buffer package.
It is generated from these files:
proto3_proto/proto3.proto
It has these top-level messages:
Message
Nested
MessageWithMap
IntMap
IntMaps
*/
package proto3_proto
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import google_protobuf "github.com/golang/protobuf/ptypes/any"
import testdata "github.com/golang/protobuf/proto/testdata"
// 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.ProtoPackageIsVersion2 // 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 fileDescriptor0, []int{0, 0} }
type Message struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Hilarity Message_Humour `protobuf:"varint,2,opt,name=hilarity,enum=proto3_proto.Message_Humour" json:"hilarity,omitempty"`
HeightInCm uint32 `protobuf:"varint,3,opt,name=height_in_cm,json=heightInCm" 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" json:"result_count,omitempty"`
TrueScotsman bool `protobuf:"varint,8,opt,name=true_scotsman,json=trueScotsman" json:"true_scotsman,omitempty"`
Score float32 `protobuf:"fixed32,9,opt,name=score" json:"score,omitempty"`
Key []uint64 `protobuf:"varint,5,rep,packed,name=key" json:"key,omitempty"`
ShortKey []int32 `protobuf:"varint,19,rep,packed,name=short_key,json=shortKey" json:"short_key,omitempty"`
Nested *Nested `protobuf:"bytes,6,opt,name=nested" json:"nested,omitempty"`
RFunny []Message_Humour `protobuf:"varint,16,rep,packed,name=r_funny,json=rFunny,enum=proto3_proto.Message_Humour" json:"r_funny,omitempty"`
Terrain map[string]*Nested `protobuf:"bytes,10,rep,name=terrain" json:"terrain,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
Proto2Field *testdata.SubDefaults `protobuf:"bytes,11,opt,name=proto2_field,json=proto2Field" json:"proto2_field,omitempty"`
Proto2Value map[string]*testdata.SubDefaults `protobuf:"bytes,13,rep,name=proto2_value,json=proto2Value" json:"proto2_value,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
Anything *google_protobuf.Any `protobuf:"bytes,14,opt,name=anything" json:"anything,omitempty"`
ManyThings []*google_protobuf.Any `protobuf:"bytes,15,rep,name=many_things,json=manyThings" json:"many_things,omitempty"`
Submessage *Message `protobuf:"bytes,17,opt,name=submessage" json:"submessage,omitempty"`
Children []*Message `protobuf:"bytes,18,rep,name=children" json:"children,omitempty"`
}
func (m *Message) Reset() { *m = Message{} }
func (m *Message) String() string { return proto.CompactTextString(m) }
func (*Message) ProtoMessage() {}
func (*Message) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
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() *testdata.SubDefaults {
if m != nil {
return m.Proto2Field
}
return nil
}
func (m *Message) GetProto2Value() map[string]*testdata.SubDefaults {
if m != nil {
return m.Proto2Value
}
return nil
}
func (m *Message) GetAnything() *google_protobuf.Any {
if m != nil {
return m.Anything
}
return nil
}
func (m *Message) GetManyThings() []*google_protobuf.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
}
type Nested struct {
Bunny string `protobuf:"bytes,1,opt,name=bunny" json:"bunny,omitempty"`
Cute bool `protobuf:"varint,2,opt,name=cute" json:"cute,omitempty"`
}
func (m *Nested) Reset() { *m = Nested{} }
func (m *Nested) String() string { return proto.CompactTextString(m) }
func (*Nested) ProtoMessage() {}
func (*Nested) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
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" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"`
}
func (m *MessageWithMap) Reset() { *m = MessageWithMap{} }
func (m *MessageWithMap) String() string { return proto.CompactTextString(m) }
func (*MessageWithMap) ProtoMessage() {}
func (*MessageWithMap) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
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" json:"rtt,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"`
}
func (m *IntMap) Reset() { *m = IntMap{} }
func (m *IntMap) String() string { return proto.CompactTextString(m) }
func (*IntMap) ProtoMessage() {}
func (*IntMap) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
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" json:"maps,omitempty"`
}
func (m *IntMaps) Reset() { *m = IntMaps{} }
func (m *IntMaps) String() string { return proto.CompactTextString(m) }
func (*IntMaps) ProtoMessage() {}
func (*IntMaps) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (m *IntMaps) GetMaps() []*IntMap {
if m != nil {
return m.Maps
}
return nil
}
func init() {
proto.RegisterType((*Message)(nil), "proto3_proto.Message")
proto.RegisterType((*Nested)(nil), "proto3_proto.Nested")
proto.RegisterType((*MessageWithMap)(nil), "proto3_proto.MessageWithMap")
proto.RegisterType((*IntMap)(nil), "proto3_proto.IntMap")
proto.RegisterType((*IntMaps)(nil), "proto3_proto.IntMaps")
proto.RegisterEnum("proto3_proto.Message_Humour", Message_Humour_name, Message_Humour_value)
}
func init() { proto.RegisterFile("proto3_proto/proto3.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 733 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x84, 0x53, 0x6d, 0x6f, 0xf3, 0x34,
0x14, 0x25, 0x4d, 0x5f, 0xd2, 0x9b, 0x74, 0x0b, 0x5e, 0x91, 0xbc, 0x02, 0x52, 0x28, 0x12, 0x8a,
0x78, 0x49, 0xa1, 0xd3, 0xd0, 0x84, 0x10, 0x68, 0x1b, 0x9b, 0xa8, 0xd6, 0x95, 0xca, 0xdd, 0x98,
0xf8, 0x14, 0xa5, 0xad, 0xdb, 0x46, 0x34, 0x4e, 0x49, 0x1c, 0xa4, 0xfc, 0x1d, 0xfe, 0x28, 0x8f,
0x6c, 0xa7, 0x5d, 0x36, 0x65, 0xcf, 0xf3, 0x29, 0xf6, 0xf1, 0xb9, 0xf7, 0x9c, 0x1c, 0x5f, 0xc3,
0xe9, 0x2e, 0x89, 0x79, 0x7c, 0xe6, 0xcb, 0xcf, 0x40, 0x6d, 0x3c, 0xf9, 0x41, 0x56, 0xf9, 0xa8,
0x77, 0xba, 0x8e, 0xe3, 0xf5, 0x96, 0x2a, 0xca, 0x3c, 0x5b, 0x0d, 0x02, 0x96, 0x2b, 0x62, 0xef,
0x84, 0xd3, 0x94, 0x2f, 0x03, 0x1e, 0x0c, 0xc4, 0x42, 0x81, 0xfd, 0xff, 0x5b, 0xd0, 0xba, 0xa7,
0x69, 0x1a, 0xac, 0x29, 0x42, 0x50, 0x67, 0x41, 0x44, 0xb1, 0xe6, 0x68, 0x6e, 0x9b, 0xc8, 0x35,
0xba, 0x00, 0x63, 0x13, 0x6e, 0x83, 0x24, 0xe4, 0x39, 0xae, 0x39, 0x9a, 0x7b, 0x34, 0xfc, 0xcc,
0x2b, 0x0b, 0x7a, 0x45, 0xb1, 0xf7, 0x7b, 0x16, 0xc5, 0x59, 0x42, 0x0e, 0x6c, 0xe4, 0x80, 0xb5,
0xa1, 0xe1, 0x7a, 0xc3, 0xfd, 0x90, 0xf9, 0x8b, 0x08, 0xeb, 0x8e, 0xe6, 0x76, 0x08, 0x28, 0x6c,
0xc4, 0xae, 0x23, 0xa1, 0x27, 0xec, 0xe0, 0xba, 0xa3, 0xb9, 0x16, 0x91, 0x6b, 0xf4, 0x05, 0x58,
0x09, 0x4d, 0xb3, 0x2d, 0xf7, 0x17, 0x71, 0xc6, 0x38, 0x6e, 0x39, 0x9a, 0xab, 0x13, 0x53, 0x61,
0xd7, 0x02, 0x42, 0x5f, 0x42, 0x87, 0x27, 0x19, 0xf5, 0xd3, 0x45, 0xcc, 0xd3, 0x28, 0x60, 0xd8,
0x70, 0x34, 0xd7, 0x20, 0x96, 0x00, 0x67, 0x05, 0x86, 0xba, 0xd0, 0x48, 0x17, 0x71, 0x42, 0x71,
0xdb, 0xd1, 0xdc, 0x1a, 0x51, 0x1b, 0x64, 0x83, 0xfe, 0x37, 0xcd, 0x71, 0xc3, 0xd1, 0xdd, 0x3a,
0x11, 0x4b, 0xf4, 0x29, 0xb4, 0xd3, 0x4d, 0x9c, 0x70, 0x5f, 0xe0, 0x27, 0x8e, 0xee, 0x36, 0x88,
0x21, 0x81, 0x3b, 0x9a, 0xa3, 0x6f, 0xa1, 0xc9, 0x68, 0xca, 0xe9, 0x12, 0x37, 0x1d, 0xcd, 0x35,
0x87, 0xdd, 0x97, 0xbf, 0x3e, 0x91, 0x67, 0xa4, 0xe0, 0xa0, 0x73, 0x68, 0x25, 0xfe, 0x2a, 0x63,
0x2c, 0xc7, 0xb6, 0xa3, 0x7f, 0x30, 0xa9, 0x66, 0x72, 0x2b, 0xb8, 0xe8, 0x67, 0x68, 0x71, 0x9a,
0x24, 0x41, 0xc8, 0x30, 0x38, 0xba, 0x6b, 0x0e, 0xfb, 0xd5, 0x65, 0x0f, 0x8a, 0x74, 0xc3, 0x78,
0x92, 0x93, 0x7d, 0x09, 0xba, 0x00, 0x75, 0xff, 0x43, 0x7f, 0x15, 0xd2, 0xed, 0x12, 0x9b, 0xd2,
0xe8, 0x27, 0xde, 0xfe, 0xae, 0xbd, 0x59, 0x36, 0xff, 0x8d, 0xae, 0x82, 0x6c, 0xcb, 0x53, 0x62,
0x2a, 0xea, 0xad, 0x60, 0xa2, 0xd1, 0xa1, 0xf2, 0xdf, 0x60, 0x9b, 0x51, 0xdc, 0x91, 0xe2, 0x5f,
0x55, 0x8b, 0x4f, 0x25, 0xf3, 0x4f, 0x41, 0x54, 0x06, 0x8a, 0x56, 0x12, 0x41, 0xdf, 0x83, 0x11,
0xb0, 0x9c, 0x6f, 0x42, 0xb6, 0xc6, 0x47, 0x45, 0x52, 0x6a, 0x0e, 0xbd, 0xfd, 0x1c, 0x7a, 0x97,
0x2c, 0x27, 0x07, 0x16, 0x3a, 0x07, 0x33, 0x0a, 0x58, 0xee, 0xcb, 0x5d, 0x8a, 0x8f, 0xa5, 0x76,
0x75, 0x11, 0x08, 0xe2, 0x83, 0xe4, 0xa1, 0x73, 0x80, 0x34, 0x9b, 0x47, 0xca, 0x14, 0xfe, 0xb8,
0xf8, 0xd7, 0x2a, 0xc7, 0xa4, 0x44, 0x44, 0x3f, 0x80, 0xb1, 0xd8, 0x84, 0xdb, 0x65, 0x42, 0x19,
0x46, 0x52, 0xea, 0x8d, 0xa2, 0x03, 0xad, 0x37, 0x05, 0xab, 0x1c, 0xf8, 0x7e, 0x72, 0xd4, 0xd3,
0x90, 0x93, 0xf3, 0x35, 0x34, 0x54, 0x70, 0xb5, 0xf7, 0xcc, 0x86, 0xa2, 0xfc, 0x54, 0xbb, 0xd0,
0x7a, 0x8f, 0x60, 0xbf, 0x4e, 0xb1, 0xa2, 0xeb, 0x37, 0x2f, 0xbb, 0xbe, 0x71, 0x91, 0xcf, 0x6d,
0xfb, 0xbf, 0x42, 0x53, 0x0d, 0x14, 0x32, 0xa1, 0xf5, 0x38, 0xb9, 0x9b, 0xfc, 0xf1, 0x34, 0xb1,
0x3f, 0x42, 0x06, 0xd4, 0xa7, 0x8f, 0x93, 0x99, 0xad, 0xa1, 0x0e, 0xb4, 0x67, 0xe3, 0xcb, 0xe9,
0xec, 0x61, 0x74, 0x7d, 0x67, 0xd7, 0xd0, 0x31, 0x98, 0x57, 0xa3, 0xf1, 0xd8, 0xbf, 0xba, 0x1c,
0x8d, 0x6f, 0xfe, 0xb2, 0xf5, 0xfe, 0x10, 0x9a, 0xca, 0xac, 0x78, 0x33, 0x73, 0x39, 0xbe, 0xca,
0x8f, 0xda, 0x88, 0x57, 0xba, 0xc8, 0xb8, 0x32, 0x64, 0x10, 0xb9, 0xee, 0xff, 0xa7, 0xc1, 0x51,
0x91, 0xd9, 0x53, 0xc8, 0x37, 0xf7, 0xc1, 0x0e, 0x4d, 0xc1, 0x9a, 0xe7, 0x9c, 0xfa, 0x51, 0xb0,
0xdb, 0x89, 0x39, 0xd0, 0x64, 0xce, 0xdf, 0x55, 0xe6, 0x5c, 0xd4, 0x78, 0x57, 0x39, 0xa7, 0xf7,
0x8a, 0x5f, 0x4c, 0xd5, 0xfc, 0x19, 0xe9, 0xfd, 0x02, 0xf6, 0x6b, 0x42, 0x39, 0x30, 0x43, 0x05,
0xd6, 0x2d, 0x07, 0x66, 0x95, 0x93, 0xf9, 0x07, 0x9a, 0x23, 0xc6, 0x85, 0xb7, 0x01, 0xe8, 0x09,
0xe7, 0x85, 0xa5, 0xcf, 0x5f, 0x5a, 0x52, 0x14, 0x8f, 0x70, 0xae, 0x2c, 0x08, 0x66, 0xef, 0x47,
0x30, 0xf6, 0x40, 0x59, 0xb2, 0x51, 0x21, 0xd9, 0x28, 0x4b, 0x9e, 0x41, 0x4b, 0xf5, 0x4b, 0x91,
0x0b, 0xf5, 0x28, 0xd8, 0xa5, 0x85, 0x68, 0xb7, 0x4a, 0x94, 0x48, 0xc6, 0xbc, 0xa9, 0x8e, 0xde,
0x05, 0x00, 0x00, 0xff, 0xff, 0x75, 0x38, 0xad, 0x84, 0xe4, 0x05, 0x00, 0x00,
}

View File

@@ -31,6 +31,7 @@
syntax = "proto3";
import "google/protobuf/any.proto";
import "testdata/test.proto";
package proto3_proto;
@@ -52,17 +53,35 @@ message Message {
float score = 9;
repeated uint64 key = 5;
repeated int32 short_key = 19;
Nested nested = 6;
repeated Humour r_funny = 16;
map<string, Nested> terrain = 10;
testdata.SubDefaults proto2_field = 11;
map<string, testdata.SubDefaults> proto2_value = 13;
google.protobuf.Any anything = 14;
repeated google.protobuf.Any many_things = 15;
Message submessage = 17;
repeated Message children = 18;
}
message Nested {
string bunny = 1;
bool cute = 2;
}
message MessageWithMap {
map<bool, bytes> byte_mapping = 1;
}
message IntMap {
map<int32, int32> rtt = 1;
}
message IntMaps {
repeated IntMap maps = 1;
}

View File

@@ -93,6 +93,16 @@ func TestRoundTripProto3(t *testing.T) {
}
}
func TestGettersForBasicTypesExist(t *testing.T) {
var m pb.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 := &pb.Message{
Terrain: map[string]*pb.Nested{

File diff suppressed because it is too large Load Diff

View File

@@ -169,6 +169,13 @@ message GoTest {
};
}
// 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.
@@ -237,6 +244,10 @@ message OtherMessage {
extensions 100 to max;
}
message RequiredInnerMessage {
required InnerMessage leo_finally_won_an_oscar = 1;
}
message MyMessage {
required int32 count = 1;
optional string name = 2;
@@ -244,6 +255,7 @@ message MyMessage {
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 {
@@ -483,6 +495,7 @@ message GroupNew {
message FloatingPoint {
required double f = 1;
optional bool exact = 2;
}
message MessageWithMap {

View File

@@ -154,7 +154,7 @@ func (w *textWriter) indent() { w.ind++ }
func (w *textWriter) unindent() {
if w.ind == 0 {
log.Printf("proto: textWriter unindented too far")
log.Print("proto: textWriter unindented too far")
return
}
w.ind--
@@ -175,7 +175,93 @@ type raw interface {
Bytes() []byte
}
func writeStruct(w *textWriter, sv reflect.Value) error {
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
}
// isAny reports whether sv is a google.protobuf.Any message
func isAny(sv reflect.Value) bool {
type wkt interface {
XXX_WellKnownType() string
}
t, ok := sv.Addr().Interface().(wkt)
return ok && t.XXX_WellKnownType() == "Any"
}
// 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 (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) {
turl := sv.FieldByName("TypeUrl")
val := sv.FieldByName("Value")
if !turl.IsValid() || !val.IsValid() {
return true, errors.New("proto: invalid google.protobuf.Any message")
}
b, ok := val.Interface().([]byte)
if !ok {
return true, errors.New("proto: invalid google.protobuf.Any message")
}
parts := strings.Split(turl.String(), "/")
mt := MessageType(parts[len(parts)-1])
if mt == nil {
return false, nil
}
m := reflect.New(mt.Elem())
if err := Unmarshal(b, m.Interface().(Message)); err != nil {
return false, nil
}
w.Write([]byte("["))
u := turl.String()
if requiresQuotes(u) {
writeString(w, u)
} else {
w.Write([]byte(u))
}
if w.compact {
w.Write([]byte("]:<"))
} else {
w.Write([]byte("]: <\n"))
w.ind++
}
if err := tm.writeStruct(w, m.Elem()); err != nil {
return true, err
}
if w.compact {
w.Write([]byte("> "))
} else {
w.ind--
w.Write([]byte(">\n"))
}
return true, nil
}
func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
if tm.ExpandAny && isAny(sv) {
if canExpand, err := tm.writeProto3Any(w, sv); canExpand {
return err
}
}
st := sv.Type()
sprops := GetProperties(st)
for i := 0; i < sv.NumField(); i++ {
@@ -227,7 +313,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
}
continue
}
if err := writeAny(w, v, props); err != nil {
if err := tm.writeAny(w, v, props); err != nil {
return err
}
if err := w.WriteByte('\n'); err != nil {
@@ -269,7 +355,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
return err
}
}
if err := writeAny(w, key, props.mkeyprop); err != nil {
if err := tm.writeAny(w, key, props.mkeyprop); err != nil {
return err
}
if err := w.WriteByte('\n'); err != nil {
@@ -286,7 +372,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
return err
}
}
if err := writeAny(w, val, props.mvalprop); err != nil {
if err := tm.writeAny(w, val, props.mvalprop); err != nil {
return err
}
if err := w.WriteByte('\n'); err != nil {
@@ -358,7 +444,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
}
// Enums have a String method, so writeAny will work fine.
if err := writeAny(w, fv, props); err != nil {
if err := tm.writeAny(w, fv, props); err != nil {
return err
}
@@ -369,8 +455,8 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
// Extensions (the XXX_extensions field).
pv := sv.Addr()
if pv.Type().Implements(extendableProtoType) {
if err := writeExtensions(w, pv); err != nil {
if _, ok := extendable(pv.Interface()); ok {
if err := tm.writeExtensions(w, pv); err != nil {
return err
}
}
@@ -400,7 +486,7 @@ func writeRaw(w *textWriter, b []byte) error {
}
// writeAny writes an arbitrary field.
func writeAny(w *textWriter, v reflect.Value, props *Properties) error {
func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error {
v = reflect.Indirect(v)
// Floats have special cases.
@@ -427,7 +513,7 @@ func writeAny(w *textWriter, v reflect.Value, props *Properties) error {
switch v.Kind() {
case reflect.Slice:
// Should only be a []byte; repeated fields are handled in writeStruct.
if err := writeString(w, string(v.Interface().([]byte))); err != nil {
if err := writeString(w, string(v.Bytes())); err != nil {
return err
}
case reflect.String:
@@ -449,15 +535,15 @@ func writeAny(w *textWriter, v reflect.Value, props *Properties) error {
}
}
w.indent()
if tm, ok := v.Interface().(encoding.TextMarshaler); ok {
text, err := tm.MarshalText()
if etm, ok := v.Interface().(encoding.TextMarshaler); ok {
text, err := etm.MarshalText()
if err != nil {
return err
}
if _, err = w.Write(text); err != nil {
return err
}
} else if err := writeStruct(w, v); err != nil {
} else if err := tm.writeStruct(w, v); err != nil {
return err
}
w.unindent()
@@ -601,19 +687,24 @@ func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// writeExtensions writes all the extensions in pv.
// pv is assumed to be a pointer to a protocol message struct that is extendable.
func writeExtensions(w *textWriter, pv reflect.Value) error {
func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error {
emap := extensionMaps[pv.Type().Elem()]
ep := pv.Interface().(extendableProto)
ep, _ := extendable(pv.Interface())
// Order the extensions by ID.
// This isn't strictly necessary, but it will give us
// canonical output, which will also make testing easier.
m := ep.ExtensionMap()
m, mu := ep.extensionsRead()
if m == nil {
return nil
}
mu.Lock()
ids := make([]int32, 0, len(m))
for id := range m {
ids = append(ids, id)
}
sort.Sort(int32Slice(ids))
mu.Unlock()
for _, extNum := range ids {
ext := m[extNum]
@@ -636,13 +727,13 @@ func writeExtensions(w *textWriter, pv reflect.Value) error {
// Repeated extensions will appear as a slice.
if !desc.repeated() {
if err := writeExtension(w, desc.Name, pb); err != nil {
if err := tm.writeExtension(w, desc.Name, pb); err != nil {
return err
}
} else {
v := reflect.ValueOf(pb)
for i := 0; i < v.Len(); i++ {
if err := writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {
return err
}
}
@@ -651,7 +742,7 @@ func writeExtensions(w *textWriter, pv reflect.Value) error {
return nil
}
func writeExtension(w *textWriter, name string, pb interface{}) error {
func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error {
if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil {
return err
}
@@ -660,7 +751,7 @@ func writeExtension(w *textWriter, name string, pb interface{}) error {
return err
}
}
if err := writeAny(w, reflect.ValueOf(pb), nil); err != nil {
if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil {
return err
}
if err := w.WriteByte('\n'); err != nil {
@@ -685,7 +776,15 @@ func (w *textWriter) writeIndent() {
w.complete = false
}
func marshalText(w io.Writer, pb Message, compact bool) error {
// 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 a given protocol buffer in text format.
// The only errors returned are from w.
func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {
val := reflect.ValueOf(pb)
if pb == nil || val.IsNil() {
w.Write([]byte("<nil>"))
@@ -700,11 +799,11 @@ func marshalText(w io.Writer, pb Message, compact bool) error {
aw := &textWriter{
w: ww,
complete: true,
compact: compact,
compact: tm.Compact,
}
if tm, ok := pb.(encoding.TextMarshaler); ok {
text, err := tm.MarshalText()
if etm, ok := pb.(encoding.TextMarshaler); ok {
text, err := etm.MarshalText()
if err != nil {
return err
}
@@ -718,7 +817,7 @@ func marshalText(w io.Writer, pb Message, compact bool) error {
}
// Dereference the received pointer so we don't have outer < and >.
v := reflect.Indirect(val)
if err := writeStruct(aw, v); err != nil {
if err := tm.writeStruct(aw, v); err != nil {
return err
}
if bw != nil {
@@ -727,25 +826,29 @@ func marshalText(w io.Writer, pb Message, compact bool) error {
return nil
}
// Text is the same as Marshal, but returns the string directly.
func (tm *TextMarshaler) Text(pb Message) string {
var buf bytes.Buffer
tm.Marshal(&buf, pb)
return buf.String()
}
var (
defaultTextMarshaler = TextMarshaler{}
compactTextMarshaler = TextMarshaler{Compact: true}
)
// TODO: consider removing some of the Marshal functions below.
// MarshalText writes a given protocol buffer in text format.
// The only errors returned are from w.
func MarshalText(w io.Writer, pb Message) error {
return marshalText(w, pb, false)
}
func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) }
// MarshalTextString is the same as MarshalText, but returns the string directly.
func MarshalTextString(pb Message) string {
var buf bytes.Buffer
marshalText(&buf, pb, false)
return buf.String()
}
func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) }
// CompactText writes a given protocol buffer in compact text format (one line).
func CompactText(w io.Writer, pb Message) error { return marshalText(w, pb, true) }
func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) }
// CompactTextString is the same as CompactText, but returns the string directly.
func CompactTextString(pb Message) string {
var buf bytes.Buffer
marshalText(&buf, pb, true)
return buf.String()
}
func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) }

View File

@@ -44,6 +44,9 @@ import (
"unicode/utf8"
)
// Error string emitted when deserializing Any and fields are already set
const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set"
type ParseError struct {
Message string
Line int // 1-based line number
@@ -119,6 +122,14 @@ func isWhitespace(c byte) bool {
return false
}
func isQuote(c byte) bool {
switch c {
case '"', '\'':
return true
}
return false
}
func (p *textParser) skipWhitespace() {
i := 0
for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') {
@@ -155,7 +166,7 @@ func (p *textParser) advance() {
p.cur.offset, p.cur.line = p.offset, p.line
p.cur.unquoted = ""
switch p.s[0] {
case '<', '>', '{', '}', ':', '[', ']', ';', ',':
case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/':
// Single symbol
p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]
case '"', '\'':
@@ -333,13 +344,13 @@ func (p *textParser) next() *token {
p.advance()
if p.done {
p.cur.value = ""
} else if len(p.cur.value) > 0 && p.cur.value[0] == '"' {
} 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 || p.s[0] != '"' {
if p.done || !isQuote(p.s[0]) {
break
}
p.advance()
@@ -443,7 +454,10 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
fieldSet := make(map[string]bool)
// 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]".
// "[extension]" or "[type/url]".
//
// The whole struct can also be an expanded Any message, like:
// [type/url] < ... struct contents ... >
for {
tok := p.next()
if tok.err != nil {
@@ -453,33 +467,74 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
break
}
if tok.value == "[" {
// Looks like an extension.
// Looks like an extension or an Any.
//
// TODO: Check whether we need to handle
// namespace rooted names (e.g. ".something.Foo").
tok = p.next()
if tok.err != nil {
return tok.err
extName, err := p.consumeExtName()
if err != nil {
return err
}
if s := strings.LastIndex(extName, "/"); s >= 0 {
// If it contains a slash, it's an Any type URL.
messageName := extName[s+1:]
mt := MessageType(messageName)
if mt == nil {
return p.errorf("unrecognized message %q in google.protobuf.Any", messageName)
}
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)
}
v := reflect.New(mt.Elem())
if pe := p.readStruct(v.Elem(), terminator); pe != nil {
return pe
}
b, err := Marshal(v.Interface().(Message))
if err != nil {
return p.errorf("failed to marshal message of type %q: %v", messageName, err)
}
if fieldSet["type_url"] {
return p.errorf(anyRepeatedlyUnpacked, "type_url")
}
if fieldSet["value"] {
return p.errorf(anyRepeatedlyUnpacked, "value")
}
sv.FieldByName("TypeUrl").SetString(extName)
sv.FieldByName("Value").SetBytes(b)
fieldSet["type_url"] = true
fieldSet["value"] = true
continue
}
var desc *ExtensionDesc
// This could be faster, but it's functional.
// TODO: Do something smarter than a linear scan.
for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) {
if d.Name == tok.value {
if d.Name == extName {
desc = d
break
}
}
if desc == nil {
return p.errorf("unrecognized extension %q", tok.value)
}
// Check the extension terminator.
tok = p.next()
if tok.err != nil {
return tok.err
}
if tok.value != "]" {
return p.errorf("unrecognized extension terminator %q", tok.value)
return p.errorf("unrecognized extension %q", extName)
}
props := &Properties{}
@@ -506,7 +561,7 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
}
reqFieldErr = err
}
ep := sv.Addr().Interface().(extendableProto)
ep := sv.Addr().Interface().(Message)
if !rep {
SetExtension(ep, desc, ext.Interface())
} else {
@@ -537,7 +592,11 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
props = oop.Prop
nv := reflect.New(oop.Type.Elem())
dst = nv.Elem().Field(0)
sv.Field(oop.Field).Set(nv)
field := sv.Field(oop.Field)
if !field.IsNil() {
return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name)
}
field.Set(nv)
}
if !dst.IsValid() {
return p.errorf("unknown field name %q in %v", name, st)
@@ -558,8 +617,9 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
// The map entry should be this sequence of tokens:
// < key : KEY value : VALUE >
// Technically the "key" and "value" could come in any order,
// but in practice they won't.
// However, implementations may omit key or value, and technically
// we should support them in any order. See b/28924776 for a time
// this went wrong.
tok := p.next()
var terminator string
@@ -571,32 +631,39 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
default:
return p.errorf("expected '{' or '<', found %q", tok.value)
}
if err := p.consumeToken("key"); err != nil {
return err
}
if err := p.consumeToken(":"); err != nil {
return err
}
if err := p.readAny(key, props.mkeyprop); err != nil {
return err
}
if err := p.consumeOptionalSeparator(); err != nil {
return err
}
if err := p.consumeToken("value"); err != nil {
return err
}
if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
return err
}
if err := p.readAny(val, props.mvalprop); err != nil {
return err
}
if err := p.consumeOptionalSeparator(); err != nil {
return err
}
if err := p.consumeToken(terminator); err != nil {
return err
for {
tok := p.next()
if tok.err != nil {
return tok.err
}
if tok.value == terminator {
break
}
switch tok.value {
case "key":
if err := p.consumeToken(":"); err != nil {
return err
}
if err := p.readAny(key, props.mkeyprop); err != nil {
return err
}
if err := p.consumeOptionalSeparator(); err != nil {
return err
}
case "value":
if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
return err
}
if err := p.readAny(val, props.mvalprop); err != nil {
return err
}
if err := p.consumeOptionalSeparator(); err != nil {
return err
}
default:
p.back()
return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value)
}
}
dst.SetMapIndex(key, val)
@@ -619,7 +686,8 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
return err
}
reqFieldErr = err
} else if props.Required {
}
if props.Required {
reqCount--
}
@@ -635,6 +703,35 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
return reqFieldErr
}
// consumeExtName consumes extension name or expanded Any type URL and the
// following ']'. It returns the name or URL consumed.
func (p *textParser) consumeExtName() (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)
}
}
return strings.Join(parts, ""), nil
}
// consumeOptionalSeparator consumes an optional semicolon or comma.
// It is used in readStruct to provide backward compatibility.
func (p *textParser) consumeOptionalSeparator() error {
@@ -699,12 +796,12 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error {
fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
return p.readAny(fv.Index(fv.Len()-1), props)
case reflect.Bool:
// Either "true", "false", 1 or 0.
// true/1/t/True or false/f/0/False.
switch tok.value {
case "true", "1":
case "true", "1", "t", "True":
fv.SetBool(true)
return nil
case "false", "0":
case "false", "0", "f", "False":
fv.SetBool(false)
return nil
}
@@ -768,7 +865,7 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error {
return p.readStruct(fv, terminator)
case reflect.Uint32:
if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {
fv.SetUint(uint64(x))
fv.SetUint(x)
return nil
}
case reflect.Uint64:

View File

@@ -95,7 +95,7 @@ var unMarshalTextTests = []UnmarshalTextTest{
},
},
// Quoted string concatenation
// Quoted string concatenation with double quotes
{
in: `count:42 name: "My name is "` + "\n" + `"elsewhere"`,
out: &MyMessage{
@@ -104,6 +104,31 @@ var unMarshalTextTests = []UnmarshalTextTest{
},
},
// Quoted string concatenation with single quotes
{
in: "count:42 name: 'My name is '\n'elsewhere'",
out: &MyMessage{
Count: Int32(42),
Name: String("My name is elsewhere"),
},
},
// Quoted string concatenations with mixed quotes
{
in: "count:42 name: 'My name is '\n\"elsewhere\"",
out: &MyMessage{
Count: Int32(42),
Name: String("My name is elsewhere"),
},
},
{
in: "count:42 name: \"My name is \"\n'elsewhere'",
out: &MyMessage{
Count: Int32(42),
Name: String("My name is elsewhere"),
},
},
// Quoted string with escaped apostrophe
{
in: `count:42 name: "HOLIDAY - New Year\'s Day"`,
@@ -311,6 +336,16 @@ var unMarshalTextTests = []UnmarshalTextTest{
},
},
// Missing required field in a required submessage
{
in: `count: 42 we_must_go_deeper < leo_finally_won_an_oscar <> >`,
err: `proto: required field "testdata.InnerMessage.host" not set`,
out: &MyMessage{
Count: Int32(42),
WeMustGoDeeper: &RequiredInnerMessage{LeoFinallyWonAnOscar: &InnerMessage{}},
},
},
// Repeated non-repeated field
{
in: `name: "Rob" name: "Russ"`,
@@ -345,6 +380,95 @@ var unMarshalTextTests = []UnmarshalTextTest{
},
},
// Boolean false
{
in: `count:42 inner { host: "example.com" connected: false }`,
out: &MyMessage{
Count: Int32(42),
Inner: &InnerMessage{
Host: String("example.com"),
Connected: Bool(false),
},
},
},
// Boolean true
{
in: `count:42 inner { host: "example.com" connected: true }`,
out: &MyMessage{
Count: Int32(42),
Inner: &InnerMessage{
Host: String("example.com"),
Connected: Bool(true),
},
},
},
// Boolean 0
{
in: `count:42 inner { host: "example.com" connected: 0 }`,
out: &MyMessage{
Count: Int32(42),
Inner: &InnerMessage{
Host: String("example.com"),
Connected: Bool(false),
},
},
},
// Boolean 1
{
in: `count:42 inner { host: "example.com" connected: 1 }`,
out: &MyMessage{
Count: Int32(42),
Inner: &InnerMessage{
Host: String("example.com"),
Connected: Bool(true),
},
},
},
// Boolean f
{
in: `count:42 inner { host: "example.com" connected: f }`,
out: &MyMessage{
Count: Int32(42),
Inner: &InnerMessage{
Host: String("example.com"),
Connected: Bool(false),
},
},
},
// Boolean t
{
in: `count:42 inner { host: "example.com" connected: t }`,
out: &MyMessage{
Count: Int32(42),
Inner: &InnerMessage{
Host: String("example.com"),
Connected: Bool(true),
},
},
},
// Boolean False
{
in: `count:42 inner { host: "example.com" connected: False }`,
out: &MyMessage{
Count: Int32(42),
Inner: &InnerMessage{
Host: String("example.com"),
Connected: Bool(false),
},
},
},
// Boolean True
{
in: `count:42 inner { host: "example.com" connected: True }`,
out: &MyMessage{
Count: Int32(42),
Inner: &InnerMessage{
Host: String("example.com"),
Connected: Bool(true),
},
},
},
// Extension
buildExtStructTest(`count: 42 [testdata.Ext.more]:<data:"Hello, world!" >`),
buildExtStructTest(`count: 42 [testdata.Ext.more] {data:"Hello, world!"}`),
@@ -473,7 +597,10 @@ func TestMapParsing(t *testing.T) {
const in = `name_mapping:<key:1234 value:"Feist"> name_mapping:<key:1 value:"Beatles">` +
`msg_mapping:<key:-4, value:<f: 2.0>,>` + // separating commas are okay
`msg_mapping<key:-2 value<f: 4.0>>` + // no colon after "value"
`byte_mapping:<key:true value:"so be it">`
`msg_mapping:<value:<f: 5.0>>` + // omitted key
`msg_mapping:<key:1>` + // omitted value
`byte_mapping:<key:true value:"so be it">` +
`byte_mapping:<>` // omitted key and value
want := &MessageWithMap{
NameMapping: map[int32]string{
1: "Beatles",
@@ -482,9 +609,12 @@ func TestMapParsing(t *testing.T) {
MsgMapping: map[int64]*FloatingPoint{
-4: {F: Float64(2.0)},
-2: {F: Float64(4.0)},
0: {F: Float64(5.0)},
1: nil,
},
ByteMapping: map[bool][]byte{
true: []byte("so be it"),
false: nil,
true: []byte("so be it"),
},
}
if err := UnmarshalText(in, m); err != nil {
@@ -505,6 +635,17 @@ func TestOneofParsing(t *testing.T) {
if !Equal(m, want) {
t.Errorf("\n got %v\nwant %v", m, want)
}
const inOverwrite = `name:"Shrek" number:42`
m = new(Communique)
testErr := "line 1.13: field 'number' would overwrite already parsed oneof 'Union'"
if err := UnmarshalText(inOverwrite, m); err == nil {
t.Errorf("TestOneofParsing: Didn't get expected error: %v", testErr)
} else if err.Error() != testErr {
t.Errorf("TestOneofParsing: Incorrect error.\nHave: %v\nWant: %v",
err.Error(), testErr)
}
}
var benchInput string

View File

@@ -32,8 +32,5 @@
# Not stored here, but descriptor.proto is in https://github.com/google/protobuf/
# at src/google/protobuf/descriptor.proto
regenerate:
echo WARNING! THIS RULE IS PROBABLY NOT RIGHT FOR YOUR INSTALLATION
protoc --go_out=. -I$(HOME)/src/protobuf/src $(HOME)/src/protobuf/src/google/protobuf/descriptor.proto && \
sed 's,^package google_protobuf,package descriptor,' google/protobuf/descriptor.pb.go > \
$(GOPATH)/src/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go && \
rm -f google/protobuf/descriptor.pb.go
@echo WARNING! THIS RULE IS PROBABLY NOT RIGHT FOR YOUR INSTALLATION
protoc --go_out=../../../../.. -I$(HOME)/src/protobuf/include $(HOME)/src/protobuf/include/google/protobuf/descriptor.proto

File diff suppressed because it is too large Load Diff

View File

@@ -62,7 +62,7 @@ import (
// 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 = 1
const generatedCodeVersion = 2
// A Plugin provides functionality to add to the output during Go code generation,
// such as to produce RPC stubs.
@@ -264,6 +264,36 @@ type FileDescriptor struct {
// PackageName is the package name we'll use in the generated code to refer to this file.
func (d *FileDescriptor) PackageName() string { return uniquePackageOf(d.FileDescriptorProto) }
// 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 { return fmt.Sprintf("fileDescriptor%d", d.index) }
// 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, pkg string, ok bool) {
pkg = d.GetOptions().GetGoPackage()
if pkg == "" {
return
}
ok = true
// The presence of a slash implies there's an import path.
slash := strings.LastIndex(pkg, "/")
if slash < 0 {
return
}
impPath, pkg = pkg, pkg[slash+1:]
// A semicolon-delimited suffix overrides the package name.
sc := strings.IndexByte(impPath, ';')
if sc < 0 {
return
}
impPath, pkg = impPath[:sc], impPath[sc+1:]
return
}
// goPackageName returns the Go package name to use in the
// generated Go file. The result explicit reports whether the name
// came from an option go_package statement. If explicit is false,
@@ -271,10 +301,8 @@ func (d *FileDescriptor) PackageName() string { return uniquePackageOf(d.FileDes
// or the input file name.
func (d *FileDescriptor) goPackageName() (name string, explicit bool) {
// Does the file have a "go_package" option?
if opts := d.Options; opts != nil {
if pkg := opts.GetGoPackage(); pkg != "" {
return pkg, true
}
if _, pkg, ok := d.goPackageOption(); ok {
return pkg, true
}
// Does the file have a package clause?
@@ -285,6 +313,26 @@ func (d *FileDescriptor) goPackageName() (name string, explicit bool) {
return baseName(d.GetName()), false
}
// goFileName returns the output name for the generated Go file.
func (d *FileDescriptor) goFileName() string {
name := *d.Name
if ext := path.Ext(name); ext == ".proto" || ext == ".protodevel" {
name = name[:len(name)-len(ext)]
}
name += ".pb.go"
// 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(impPath, name)
return name
}
return name
}
func (d *FileDescriptor) addExport(obj Object, sym symbol) {
d.exported[obj] = append(d.exported[obj], sym)
}
@@ -320,8 +368,6 @@ func (ms *messageSymbol) GenerateAlias(g *Generator, pkg string) {
if ms.hasExtensions {
g.P("func (*", ms.sym, ") ExtensionRangeArray() []", g.Pkg["proto"], ".ExtensionRange ",
"{ return (*", remoteSym, ")(nil).ExtensionRangeArray() }")
g.P("func (m *", ms.sym, ") ExtensionMap() map[int32]", g.Pkg["proto"], ".Extension ",
"{ return (*", remoteSym, ")(m).ExtensionMap() }")
if ms.isMessageSet {
g.P("func (m *", ms.sym, ") Marshal() ([]byte, error) ",
"{ return (*", remoteSym, ")(m).Marshal() }")
@@ -512,7 +558,7 @@ type Generator struct {
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 import name to generated name
ImportMap map[string]string // Mapping from .proto file name to import path
Pkg map[string]string // The names under which we import support packages
@@ -580,7 +626,6 @@ func (g *Generator) CommandLineParameters(parameter string) {
}
}
}
if pluginList != "" {
// Amend the set of plugins.
enabled := make(map[string]bool)
@@ -760,9 +805,9 @@ AllFiles:
// 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, len(g.Request.ProtoFile))
g.allFiles = make([]*FileDescriptor, 0, len(g.Request.ProtoFile))
g.allFilesByName = make(map[string]*FileDescriptor, len(g.allFiles))
for i, f := range g.Request.ProtoFile {
for _, f := range g.Request.ProtoFile {
// We must wrap the descriptors before we wrap the enums
descs := wrapDescriptors(f)
g.buildNestedDescriptors(descs)
@@ -778,22 +823,22 @@ func (g *Generator) WrapTypes() {
proto3: fileIsProto3(f),
}
extractComments(fd)
g.allFiles[i] = fd
g.allFiles = append(g.allFiles, fd)
g.allFilesByName[f.GetName()] = fd
}
for _, fd := range g.allFiles {
fd.imp = wrapImported(fd.FileDescriptorProto, g)
}
g.genFiles = make([]*FileDescriptor, len(g.Request.FileToGenerate))
for i, fileName := range g.Request.FileToGenerate {
g.genFiles[i] = g.allFilesByName[fileName]
if g.genFiles[i] == nil {
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[i].index = i
fd.index = len(g.genFiles)
g.genFiles = append(g.genFiles, fd)
}
g.Response.File = make([]*plugin.CodeGeneratorResponse_File, len(g.genFiles))
}
// Scan the descriptors in this file. For each one, build the slice of nested descriptors
@@ -857,9 +902,8 @@ func newDescriptor(desc *descriptor.DescriptorProto, parent *Descriptor, file *d
}
}
d.ext = make([]*ExtensionDescriptor, len(desc.Extension))
for i, field := range desc.Extension {
d.ext[i] = &ExtensionDescriptor{common{file}, field, d}
for _, field := range desc.Extension {
d.ext = append(d.ext, &ExtensionDescriptor{common{file}, field, d})
}
return d
@@ -918,9 +962,9 @@ func wrapEnumDescriptors(file *descriptor.FileDescriptorProto, descs []*Descript
// Return a slice of all the top-level ExtensionDescriptors defined within this file.
func wrapExtensions(file *descriptor.FileDescriptorProto) []*ExtensionDescriptor {
sl := make([]*ExtensionDescriptor, len(file.Extension))
for i, field := range file.Extension {
sl[i] = &ExtensionDescriptor{common{file}, field, nil}
var sl []*ExtensionDescriptor
for _, field := range file.Extension {
sl = append(sl, &ExtensionDescriptor{common{file}, field, nil})
}
return sl
}
@@ -1089,7 +1133,6 @@ func (g *Generator) GenerateAllFiles() {
for _, file := range g.genFiles {
genFileMap[file] = true
}
i := 0
for _, file := range g.allFiles {
g.Reset()
g.writeOutput = genFileMap[file]
@@ -1097,10 +1140,10 @@ func (g *Generator) GenerateAllFiles() {
if !g.writeOutput {
continue
}
g.Response.File[i] = new(plugin.CodeGeneratorResponse_File)
g.Response.File[i].Name = proto.String(goFileName(*file.Name))
g.Response.File[i].Content = proto.String(g.String())
i++
g.Response.File = append(g.Response.File, &plugin.CodeGeneratorResponse_File{
Name: proto.String(file.goFileName()),
Content: proto.String(g.String()),
})
}
}
@@ -1132,10 +1175,11 @@ func (g *Generator) generate(file *FileDescriptor) {
// For one file in the package, assert version compatibility.
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("const _ = ", g.Pkg["proto"], ".ProtoPackageIsVersion", generatedCodeVersion)
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)
}
@@ -1193,9 +1237,8 @@ func (g *Generator) generate(file *FileDescriptor) {
// Generate the header, including package definition
func (g *Generator) generateHeader() {
g.P("// Code generated by protoc-gen-go.")
g.P("// Code generated by protoc-gen-go. DO NOT EDIT.")
g.P("// source: ", g.file.Name)
g.P("// DO NOT EDIT!")
g.P()
name := g.file.PackageName()
@@ -1285,7 +1328,7 @@ func (g *Generator) generateImports() {
if fd.PackageName() == g.packageName {
continue
}
filename := goFileName(s)
filename := fd.goFileName()
// By default, import path is the dirname of the Go filename.
importPath := path.Dir(filename)
if substitution, ok := g.ImportMap[s]; ok {
@@ -1425,7 +1468,10 @@ func (g *Generator) generateEnum(enum *EnumDescriptor) {
indexes = append([]string{strconv.Itoa(m.index)}, indexes...)
}
indexes = append(indexes, strconv.Itoa(enum.index))
g.P("func (", ccTypeName, ") EnumDescriptor() ([]byte, []int) { return fileDescriptor", g.file.index, ", []int{", strings.Join(indexes, ", "), "} }")
g.P("func (", ccTypeName, ") EnumDescriptor() ([]byte, []int) { return ", g.file.VarName(), ", []int{", strings.Join(indexes, ", "), "} }")
if enum.file.GetPackage() == "google.protobuf" && enum.GetName() == "NullValue" {
g.P("func (", ccTypeName, `) XXX_WellKnownType() string { return "`, enum.GetName(), `" }`)
}
g.P()
}
@@ -1502,7 +1548,11 @@ func (g *Generator) goTag(message *Descriptor, field *descriptor.FieldDescriptor
enum += CamelCaseSlice(obj.TypeName())
}
packed := ""
if field.Options != nil && field.Options.GetPacked() {
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()
@@ -1517,6 +1567,11 @@ func (g *Generator) goTag(message *Descriptor, field *descriptor.FieldDescriptor
name = name[i+1:]
}
}
if json := field.GetJsonName(); 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() {
// We only need the extra tag for []byte fields;
@@ -1635,7 +1690,8 @@ func (g *Generator) RecordTypeUse(t string) {
}
// Method names that may be generated. Fields with these names get an
// underscore appended.
// underscore appended. Any change to this set is a potential incompatible
// API change because it changes generated field names.
var methodNames = [...]string{
"Reset",
"String",
@@ -1647,6 +1703,28 @@ var methodNames = [...]string{
"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,
}
// Generate the type and default constant definitions for this Descriptor.
func (g *Generator) generateMessage(message *Descriptor) {
// The full type name
@@ -1798,7 +1876,7 @@ func (g *Generator) generateMessage(message *Descriptor) {
g.RecordTypeUse(field.GetTypeName())
}
if len(message.ExtensionRange) > 0 {
g.P("XXX_extensions\t\tmap[int32]", g.Pkg["proto"], ".Extension `json:\"-\"`")
g.P(g.Pkg["proto"], ".XXX_InternalExtensions `json:\"-\"`")
}
if !message.proto3() {
g.P("XXX_unrecognized\t[]byte `json:\"-\"`")
@@ -1827,13 +1905,15 @@ func (g *Generator) generateMessage(message *Descriptor) {
g.P("func (m *", ccTypeName, ") Reset() { *m = ", ccTypeName, "{} }")
g.P("func (m *", ccTypeName, ") String() string { return ", g.Pkg["proto"], ".CompactTextString(m) }")
g.P("func (*", ccTypeName, ") ProtoMessage() {}")
if !message.group {
var indexes []string
for m := message; m != nil; m = m.parent {
// XXX: skip groups?
indexes = append([]string{strconv.Itoa(m.index)}, indexes...)
}
g.P("func (*", ccTypeName, ") Descriptor() ([]byte, []int) { return fileDescriptor", g.file.index, ", []int{", strings.Join(indexes, ", "), "} }")
var indexes []string
for m := message; m != nil; m = m.parent {
indexes = append([]string{strconv.Itoa(m.index)}, indexes...)
}
g.P("func (*", ccTypeName, ") Descriptor() ([]byte, []int) { return ", g.file.VarName(), ", []int{", strings.Join(indexes, ", "), "} }")
// TODO: Revisit the decision to use a XXX_WellKnownType method
// if we change proto.MessageName to work with multiple equivalents.
if message.file.GetPackage() == "google.protobuf" && wellKnownTypes[message.GetName()] {
g.P("func (*", ccTypeName, `) XXX_WellKnownType() string { return "`, message.GetName(), `" }`)
}
// Extension support methods
@@ -1846,22 +1926,22 @@ func (g *Generator) generateMessage(message *Descriptor) {
g.P()
g.P("func (m *", ccTypeName, ") Marshal() ([]byte, error) {")
g.In()
g.P("return ", g.Pkg["proto"], ".MarshalMessageSet(m.ExtensionMap())")
g.P("return ", g.Pkg["proto"], ".MarshalMessageSet(&m.XXX_InternalExtensions)")
g.Out()
g.P("}")
g.P("func (m *", ccTypeName, ") Unmarshal(buf []byte) error {")
g.In()
g.P("return ", g.Pkg["proto"], ".UnmarshalMessageSet(buf, m.ExtensionMap())")
g.P("return ", g.Pkg["proto"], ".UnmarshalMessageSet(buf, &m.XXX_InternalExtensions)")
g.Out()
g.P("}")
g.P("func (m *", ccTypeName, ") MarshalJSON() ([]byte, error) {")
g.In()
g.P("return ", g.Pkg["proto"], ".MarshalMessageSetJSON(m.XXX_extensions)")
g.P("return ", g.Pkg["proto"], ".MarshalMessageSetJSON(&m.XXX_InternalExtensions)")
g.Out()
g.P("}")
g.P("func (m *", ccTypeName, ") UnmarshalJSON(buf []byte) error {")
g.In()
g.P("return ", g.Pkg["proto"], ".UnmarshalMessageSetJSON(buf, m.XXX_extensions)")
g.P("return ", g.Pkg["proto"], ".UnmarshalMessageSetJSON(buf, &m.XXX_InternalExtensions)")
g.Out()
g.P("}")
g.P("// ensure ", ccTypeName, " satisfies proto.Marshaler and proto.Unmarshaler")
@@ -1883,16 +1963,6 @@ func (g *Generator) generateMessage(message *Descriptor) {
g.P("return extRange_", ccTypeName)
g.Out()
g.P("}")
g.P("func (m *", ccTypeName, ") ExtensionMap() map[int32]", g.Pkg["proto"], ".Extension {")
g.In()
g.P("if m.XXX_extensions == nil {")
g.In()
g.P("m.XXX_extensions = make(map[int32]", g.Pkg["proto"], ".Extension)")
g.Out()
g.P("}")
g.P("return m.XXX_extensions")
g.Out()
g.P("}")
}
// Default constants
@@ -2005,11 +2075,6 @@ func (g *Generator) generateMessage(message *Descriptor) {
star = "*"
}
// In proto3, only generate getters for message fields and oneof fields.
if message.proto3() && *field.Type != descriptor.FieldDescriptorProto_TYPE_MESSAGE && !oneof {
continue
}
// Only export getter symbols for basic types,
// and for messages and enums in the same package.
// Groups are not exported.
@@ -2068,7 +2133,11 @@ func (g *Generator) generateMessage(message *Descriptor) {
continue
}
if !oneof {
g.P("if m != nil && m." + fname + " != nil {")
if message.proto3() {
g.P("if m != nil {")
} else {
g.P("if m != nil && m." + fname + " != nil {")
}
g.In()
g.P("return " + star + "m." + fname)
g.Out()
@@ -2486,6 +2555,7 @@ func (g *Generator) generateExtension(ext *ExtensionDescriptor) {
g.P("Field: ", field.Number, ",")
g.P(`Name: "`, extName, `",`)
g.P("Tag: ", tag, ",")
g.P(`Filename: "`, g.file.GetName(), `",`)
g.Out()
g.P("}")
@@ -2541,7 +2611,10 @@ func (g *Generator) generateFileDescriptor(file *FileDescriptor) {
w.Close()
b = buf.Bytes()
g.P("var fileDescriptor", file.index, " = []byte{")
v := file.VarName()
g.P()
g.P("func init() { ", g.Pkg["proto"], ".RegisterFile(", strconv.Quote(*file.Name), ", ", v, ") }")
g.P("var ", v, " = []byte{")
g.In()
g.P("// ", len(b), " bytes of a gzipped FileDescriptorProto")
for len(b) > 0 {
@@ -2645,15 +2718,6 @@ 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, ".") }
// Given a .proto file name, return the output name for the generated Go program.
func goFileName(name string) string {
ext := path.Ext(name)
if ext == ".proto" || ext == ".protodevel" {
name = name[0 : len(name)-len(ext)]
}
return name + ".pb.go"
}
// Is this field optional?
func isOptional(field *descriptor.FieldDescriptorProto) bool {
return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_OPTIONAL
@@ -2669,6 +2733,32 @@ 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.

View File

@@ -33,6 +33,8 @@ package generator
import (
"testing"
"github.com/golang/protobuf/protoc-gen-go/descriptor"
)
func TestCamelCase(t *testing.T) {
@@ -54,3 +56,30 @@ func TestCamelCase(t *testing.T) {
}
}
}
func TestGoPackageOption(t *testing.T) {
tests := []struct {
in string
impPath, pkg string
ok bool
}{
{"", "", "", false},
{"foo", "", "foo", true},
{"github.com/golang/bar", "github.com/golang/bar", "bar", true},
{"github.com/golang/bar;baz", "github.com/golang/bar", "baz", true},
}
for _, tc := range tests {
d := &FileDescriptor{
FileDescriptorProto: &descriptor.FileDescriptorProto{
Options: &descriptor.FileOptions{
GoPackage: &tc.in,
},
},
}
impPath, pkg, ok := d.goPackageOption()
if impPath != tc.impPath || pkg != tc.pkg || ok != tc.ok {
t.Errorf("go_package = %q => (%q, %q, %t), want (%q, %q, %t)", tc.in,
impPath, pkg, ok, tc.impPath, tc.pkg, tc.ok)
}
}
}

View File

@@ -44,6 +44,12 @@ import (
"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 = 4
// Paths for packages used by code generated in this file,
// relative to the import_prefix of the generator.Generator.
const (
@@ -101,10 +107,18 @@ func (g *grpc) Generate(file *generator.FileDescriptor) {
if len(file.FileDescriptorProto.Service) == 0 {
return
}
g.P("// Reference imports to suppress errors if they are not otherwise used.")
g.P("var _ ", contextPkg, ".Context")
g.P("var _ ", grpcPkg, ".ClientConn")
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)
}
@@ -204,7 +218,7 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
// Server handler implementations.
var handlerNames []string
for _, method := range service.Method {
hname := g.generateServerMethod(servName, method)
hname := g.generateServerMethod(servName, fullServName, method)
handlerNames = append(handlerNames, hname)
}
@@ -240,6 +254,7 @@ func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.Servi
g.P("},")
}
g.P("},")
g.P("Metadata: \"", file.GetName(), "\",")
g.P("}")
g.P()
}
@@ -364,19 +379,25 @@ func (g *grpc) generateServerSignature(servName string, method *pb.MethodDescrip
return methName + "(" + strings.Join(reqArgs, ", ") + ") " + ret
}
func (g *grpc) generateServerMethod(servName string, method *pb.MethodDescriptorProto) string {
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) (interface{}, error) {")
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("out, err := srv.(", servName, "Server).", methName, "(ctx, in)")
g.P("if err != nil { return nil, err }")
g.P("return out, nil")
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

View File

@@ -31,4 +31,4 @@
package main
import _ "github.com/golang/protobuf/protoc-gen-go/internal/grpc"
import _ "github.com/golang/protobuf/protoc-gen-go/grpc"

View File

@@ -33,10 +33,9 @@
# at src/google/protobuf/compiler/plugin.proto
# Also we need to fix an import.
regenerate:
echo WARNING! THIS RULE IS PROBABLY NOT RIGHT FOR YOUR INSTALLATION
protoc --go_out=Mgoogle/protobuf/descriptor.proto=github.com/golang/protobuf/protoc-gen-go/descriptor:. \
-I$(HOME)/src/protobuf/src $(HOME)/src/protobuf/src/google/protobuf/compiler/plugin.proto && \
mv google/protobuf/compiler/plugin.pb.go $(GOPATH)/src/github.com/golang/protobuf/protoc-gen-go/plugin
@echo WARNING! THIS RULE IS PROBABLY NOT RIGHT FOR YOUR INSTALLATION
protoc --go_out=Mgoogle/protobuf/descriptor.proto=github.com/golang/protobuf/protoc-gen-go/descriptor:../../../../.. \
-I$(HOME)/src/protobuf/include $(HOME)/src/protobuf/include/google/protobuf/compiler/plugin.proto
restore:
cp plugin.pb.golden plugin.pb.go

View File

@@ -0,0 +1,293 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: google/protobuf/compiler/plugin.proto
/*
Package plugin_go is a generated protocol buffer package.
It is generated from these files:
google/protobuf/compiler/plugin.proto
It has these top-level messages:
Version
CodeGeneratorRequest
CodeGeneratorResponse
*/
package plugin_go
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import google_protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor"
// 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.ProtoPackageIsVersion2 // please upgrade the proto package
// The version number of protocol compiler.
type Version struct {
Major *int32 `protobuf:"varint,1,opt,name=major" json:"major,omitempty"`
Minor *int32 `protobuf:"varint,2,opt,name=minor" json:"minor,omitempty"`
Patch *int32 `protobuf:"varint,3,opt,name=patch" json:"patch,omitempty"`
// A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should
// be empty for mainline stable releases.
Suffix *string `protobuf:"bytes,4,opt,name=suffix" json:"suffix,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Version) Reset() { *m = Version{} }
func (m *Version) String() string { return proto.CompactTextString(m) }
func (*Version) ProtoMessage() {}
func (*Version) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *Version) GetMajor() int32 {
if m != nil && m.Major != nil {
return *m.Major
}
return 0
}
func (m *Version) GetMinor() int32 {
if m != nil && m.Minor != nil {
return *m.Minor
}
return 0
}
func (m *Version) GetPatch() int32 {
if m != nil && m.Patch != nil {
return *m.Patch
}
return 0
}
func (m *Version) GetSuffix() string {
if m != nil && m.Suffix != nil {
return *m.Suffix
}
return ""
}
// An encoded CodeGeneratorRequest is written to the plugin's stdin.
type CodeGeneratorRequest struct {
// The .proto files that were explicitly listed on the command-line. The
// code generator should generate code only for these files. Each file's
// descriptor will be included in proto_file, below.
FileToGenerate []string `protobuf:"bytes,1,rep,name=file_to_generate,json=fileToGenerate" json:"file_to_generate,omitempty"`
// The generator parameter passed on the command-line.
Parameter *string `protobuf:"bytes,2,opt,name=parameter" json:"parameter,omitempty"`
// FileDescriptorProtos for all files in files_to_generate and everything
// they import. The files will appear in topological order, so each file
// appears before any file that imports it.
//
// protoc guarantees that all proto_files will be written after
// the fields above, even though this is not technically guaranteed by the
// protobuf wire format. This theoretically could allow a plugin to stream
// in the FileDescriptorProtos and handle them one by one rather than read
// the entire set into memory at once. However, as of this writing, this
// is not similarly optimized on protoc's end -- it will store all fields in
// memory at once before sending them to the plugin.
//
// Type names of fields and extensions in the FileDescriptorProto are always
// fully qualified.
ProtoFile []*google_protobuf.FileDescriptorProto `protobuf:"bytes,15,rep,name=proto_file,json=protoFile" json:"proto_file,omitempty"`
// The version number of protocol compiler.
CompilerVersion *Version `protobuf:"bytes,3,opt,name=compiler_version,json=compilerVersion" json:"compiler_version,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *CodeGeneratorRequest) Reset() { *m = CodeGeneratorRequest{} }
func (m *CodeGeneratorRequest) String() string { return proto.CompactTextString(m) }
func (*CodeGeneratorRequest) ProtoMessage() {}
func (*CodeGeneratorRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *CodeGeneratorRequest) GetFileToGenerate() []string {
if m != nil {
return m.FileToGenerate
}
return nil
}
func (m *CodeGeneratorRequest) GetParameter() string {
if m != nil && m.Parameter != nil {
return *m.Parameter
}
return ""
}
func (m *CodeGeneratorRequest) GetProtoFile() []*google_protobuf.FileDescriptorProto {
if m != nil {
return m.ProtoFile
}
return nil
}
func (m *CodeGeneratorRequest) GetCompilerVersion() *Version {
if m != nil {
return m.CompilerVersion
}
return nil
}
// The plugin writes an encoded CodeGeneratorResponse to stdout.
type CodeGeneratorResponse struct {
// Error message. If non-empty, code generation failed. The plugin process
// should exit with status code zero even if it reports an error in this way.
//
// This should be used to indicate errors in .proto files which prevent the
// code generator from generating correct code. Errors which indicate a
// problem in protoc itself -- such as the input CodeGeneratorRequest being
// unparseable -- should be reported by writing a message to stderr and
// exiting with a non-zero status code.
Error *string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"`
File []*CodeGeneratorResponse_File `protobuf:"bytes,15,rep,name=file" json:"file,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *CodeGeneratorResponse) Reset() { *m = CodeGeneratorResponse{} }
func (m *CodeGeneratorResponse) String() string { return proto.CompactTextString(m) }
func (*CodeGeneratorResponse) ProtoMessage() {}
func (*CodeGeneratorResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (m *CodeGeneratorResponse) GetError() string {
if m != nil && m.Error != nil {
return *m.Error
}
return ""
}
func (m *CodeGeneratorResponse) GetFile() []*CodeGeneratorResponse_File {
if m != nil {
return m.File
}
return nil
}
// Represents a single generated file.
type CodeGeneratorResponse_File struct {
// The file name, relative to the output directory. The name must not
// contain "." or ".." components and must be relative, not be absolute (so,
// the file cannot lie outside the output directory). "/" must be used as
// the path separator, not "\".
//
// If the name is omitted, the content will be appended to the previous
// file. This allows the generator to break large files into small chunks,
// and allows the generated text to be streamed back to protoc so that large
// files need not reside completely in memory at one time. Note that as of
// this writing protoc does not optimize for this -- it will read the entire
// CodeGeneratorResponse before writing files to disk.
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
// If non-empty, indicates that the named file should already exist, and the
// content here is to be inserted into that file at a defined insertion
// point. This feature allows a code generator to extend the output
// produced by another code generator. The original generator may provide
// insertion points by placing special annotations in the file that look
// like:
// @@protoc_insertion_point(NAME)
// The annotation can have arbitrary text before and after it on the line,
// which allows it to be placed in a comment. NAME should be replaced with
// an identifier naming the point -- this is what other generators will use
// as the insertion_point. Code inserted at this point will be placed
// immediately above the line containing the insertion point (thus multiple
// insertions to the same point will come out in the order they were added).
// The double-@ is intended to make it unlikely that the generated code
// could contain things that look like insertion points by accident.
//
// For example, the C++ code generator places the following line in the
// .pb.h files that it generates:
// // @@protoc_insertion_point(namespace_scope)
// This line appears within the scope of the file's package namespace, but
// outside of any particular class. Another plugin can then specify the
// insertion_point "namespace_scope" to generate additional classes or
// other declarations that should be placed in this scope.
//
// Note that if the line containing the insertion point begins with
// whitespace, the same whitespace will be added to every line of the
// inserted text. This is useful for languages like Python, where
// indentation matters. In these languages, the insertion point comment
// should be indented the same amount as any inserted code will need to be
// in order to work correctly in that context.
//
// The code generator that generates the initial file and the one which
// inserts into it must both run as part of a single invocation of protoc.
// Code generators are executed in the order in which they appear on the
// command line.
//
// If |insertion_point| is present, |name| must also be present.
InsertionPoint *string `protobuf:"bytes,2,opt,name=insertion_point,json=insertionPoint" json:"insertion_point,omitempty"`
// The file contents.
Content *string `protobuf:"bytes,15,opt,name=content" json:"content,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *CodeGeneratorResponse_File) Reset() { *m = CodeGeneratorResponse_File{} }
func (m *CodeGeneratorResponse_File) String() string { return proto.CompactTextString(m) }
func (*CodeGeneratorResponse_File) ProtoMessage() {}
func (*CodeGeneratorResponse_File) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2, 0} }
func (m *CodeGeneratorResponse_File) GetName() string {
if m != nil && m.Name != nil {
return *m.Name
}
return ""
}
func (m *CodeGeneratorResponse_File) GetInsertionPoint() string {
if m != nil && m.InsertionPoint != nil {
return *m.InsertionPoint
}
return ""
}
func (m *CodeGeneratorResponse_File) GetContent() string {
if m != nil && m.Content != nil {
return *m.Content
}
return ""
}
func init() {
proto.RegisterType((*Version)(nil), "google.protobuf.compiler.Version")
proto.RegisterType((*CodeGeneratorRequest)(nil), "google.protobuf.compiler.CodeGeneratorRequest")
proto.RegisterType((*CodeGeneratorResponse)(nil), "google.protobuf.compiler.CodeGeneratorResponse")
proto.RegisterType((*CodeGeneratorResponse_File)(nil), "google.protobuf.compiler.CodeGeneratorResponse.File")
}
func init() { proto.RegisterFile("google/protobuf/compiler/plugin.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 417 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xcf, 0x6a, 0x14, 0x41,
0x10, 0xc6, 0x19, 0x77, 0x63, 0x98, 0x8a, 0x64, 0x43, 0x13, 0xa5, 0x09, 0x39, 0x8c, 0x8b, 0xe2,
0x5c, 0x32, 0x0b, 0xc1, 0x8b, 0x78, 0x4b, 0x44, 0x3d, 0x78, 0x58, 0x1a, 0xf1, 0x20, 0xc8, 0x30,
0x99, 0xd4, 0x74, 0x5a, 0x66, 0xba, 0xc6, 0xee, 0x1e, 0xf1, 0x49, 0x7d, 0x0f, 0xdf, 0x40, 0xfa,
0xcf, 0x24, 0xb2, 0xb8, 0xa7, 0xee, 0xef, 0x57, 0xd5, 0xd5, 0x55, 0x1f, 0x05, 0x2f, 0x25, 0x91,
0xec, 0x71, 0x33, 0x1a, 0x72, 0x74, 0x33, 0x75, 0x9b, 0x96, 0x86, 0x51, 0xf5, 0x68, 0x36, 0x63,
0x3f, 0x49, 0xa5, 0xab, 0x10, 0x60, 0x3c, 0xa6, 0x55, 0x73, 0x5a, 0x35, 0xa7, 0x9d, 0x15, 0xbb,
0x05, 0x6e, 0xd1, 0xb6, 0x46, 0x8d, 0x8e, 0x4c, 0xcc, 0x5e, 0xb7, 0x70, 0xf8, 0x05, 0x8d, 0x55,
0xa4, 0xd9, 0x29, 0x1c, 0x0c, 0xcd, 0x77, 0x32, 0x3c, 0x2b, 0xb2, 0xf2, 0x40, 0x44, 0x11, 0xa8,
0xd2, 0x64, 0xf8, 0xa3, 0x44, 0xbd, 0xf0, 0x74, 0x6c, 0x5c, 0x7b, 0xc7, 0x17, 0x91, 0x06, 0xc1,
0x9e, 0xc1, 0x63, 0x3b, 0x75, 0x9d, 0xfa, 0xc5, 0x97, 0x45, 0x56, 0xe6, 0x22, 0xa9, 0xf5, 0x9f,
0x0c, 0x4e, 0xaf, 0xe9, 0x16, 0x3f, 0xa0, 0x46, 0xd3, 0x38, 0x32, 0x02, 0x7f, 0x4c, 0x68, 0x1d,
0x2b, 0xe1, 0xa4, 0x53, 0x3d, 0xd6, 0x8e, 0x6a, 0x19, 0x63, 0xc8, 0xb3, 0x62, 0x51, 0xe6, 0xe2,
0xd8, 0xf3, 0xcf, 0x94, 0x5e, 0x20, 0x3b, 0x87, 0x7c, 0x6c, 0x4c, 0x33, 0xa0, 0xc3, 0xd8, 0x4a,
0x2e, 0x1e, 0x00, 0xbb, 0x06, 0x08, 0xe3, 0xd4, 0xfe, 0x15, 0x5f, 0x15, 0x8b, 0xf2, 0xe8, 0xf2,
0x45, 0xb5, 0x6b, 0xcb, 0x7b, 0xd5, 0xe3, 0xbb, 0x7b, 0x03, 0xb6, 0x1e, 0x8b, 0x3c, 0x44, 0x7d,
0x84, 0x7d, 0x82, 0x93, 0xd9, 0xb8, 0xfa, 0x67, 0xf4, 0x24, 0x8c, 0x77, 0x74, 0xf9, 0xbc, 0xda,
0xe7, 0x70, 0x95, 0xcc, 0x13, 0xab, 0x99, 0x24, 0xb0, 0xfe, 0x9d, 0xc1, 0xd3, 0x9d, 0x99, 0xed,
0x48, 0xda, 0xa2, 0xf7, 0x0e, 0x8d, 0x49, 0x3e, 0xe7, 0x22, 0x0a, 0xf6, 0x11, 0x96, 0xff, 0x34,
0xff, 0x7a, 0xff, 0x8f, 0xff, 0x2d, 0x1a, 0x66, 0x13, 0xa1, 0xc2, 0xd9, 0x37, 0x58, 0x86, 0x79,
0x18, 0x2c, 0x75, 0x33, 0x60, 0xfa, 0x26, 0xdc, 0xd9, 0x2b, 0x58, 0x29, 0x6d, 0xd1, 0x38, 0x45,
0xba, 0x1e, 0x49, 0x69, 0x97, 0xcc, 0x3c, 0xbe, 0xc7, 0x5b, 0x4f, 0x19, 0x87, 0xc3, 0x96, 0xb4,
0x43, 0xed, 0xf8, 0x2a, 0x24, 0xcc, 0xf2, 0x4a, 0xc2, 0x79, 0x4b, 0xc3, 0xde, 0xfe, 0xae, 0x9e,
0x6c, 0xc3, 0x6e, 0x06, 0x7b, 0xed, 0xd7, 0x37, 0x52, 0xb9, 0xbb, 0xe9, 0xc6, 0x87, 0x37, 0x92,
0xfa, 0x46, 0xcb, 0x87, 0x65, 0x0c, 0x97, 0xf6, 0x42, 0xa2, 0xbe, 0x90, 0x94, 0x56, 0xfa, 0x6d,
0x3c, 0x6a, 0x49, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xf7, 0x15, 0x40, 0xc5, 0xfe, 0x02, 0x00,
0x00,
}

View File

@@ -45,8 +45,9 @@ my_test/test.pb.go: my_test/test.proto
golden:
make -B my_test/test.pb.go
sed -i '/return.*fileDescriptor/d' my_test/test.pb.go
sed -i '/^var fileDescriptor/,/^}/d' my_test/test.pb.go
sed -i -e '/return.*fileDescriptor/d' my_test/test.pb.go
sed -i -e '/^var fileDescriptor/,/^}/d' my_test/test.pb.go
sed -i -e '/proto.RegisterFile.*fileDescriptor/d' my_test/test.pb.go
gofmt -w my_test/test.pb.go
diff -w my_test/test.pb.go my_test/test.pb.go.golden
@@ -57,7 +58,7 @@ testbuild: regenerate
regenerate:
# Invoke protoc once to generate three independent .pb.go files in the same package.
protoc --go_out=. multi/multi{1,2,3}.proto
protoc --go_out=. multi/multi1.proto multi/multi2.proto multi/multi3.proto
#extension_test: extension_test.$O
# $(LD) -L. -o $@ $<

View File

@@ -0,0 +1,870 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: my_test/test.proto
/*
Package my_test is a generated protocol buffer package.
This package holds interesting messages.
It is generated from these files:
my_test/test.proto
It has these top-level messages:
Request
Reply
OtherBase
ReplyExtensions
OtherReplyExtensions
OldReply
Communique
*/
package my_test
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import _ "github.com/golang/protobuf/protoc-gen-go/testdata/multi"
// 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.ProtoPackageIsVersion2 // please upgrade the proto package
type HatType int32
const (
// deliberately skipping 0
HatType_FEDORA HatType = 1
HatType_FEZ HatType = 2
)
var HatType_name = map[int32]string{
1: "FEDORA",
2: "FEZ",
}
var HatType_value = map[string]int32{
"FEDORA": 1,
"FEZ": 2,
}
func (x HatType) Enum() *HatType {
p := new(HatType)
*p = x
return p
}
func (x HatType) String() string {
return proto.EnumName(HatType_name, int32(x))
}
func (x *HatType) UnmarshalJSON(data []byte) error {
value, err := proto.UnmarshalJSONEnum(HatType_value, data, "HatType")
if err != nil {
return err
}
*x = HatType(value)
return nil
}
// This enum represents days of the week.
type Days int32
const (
Days_MONDAY Days = 1
Days_TUESDAY Days = 2
Days_LUNDI Days = 1
)
var Days_name = map[int32]string{
1: "MONDAY",
2: "TUESDAY",
// Duplicate value: 1: "LUNDI",
}
var Days_value = map[string]int32{
"MONDAY": 1,
"TUESDAY": 2,
"LUNDI": 1,
}
func (x Days) Enum() *Days {
p := new(Days)
*p = x
return p
}
func (x Days) String() string {
return proto.EnumName(Days_name, int32(x))
}
func (x *Days) UnmarshalJSON(data []byte) error {
value, err := proto.UnmarshalJSONEnum(Days_value, data, "Days")
if err != nil {
return err
}
*x = Days(value)
return nil
}
type Request_Color int32
const (
Request_RED Request_Color = 0
Request_GREEN Request_Color = 1
Request_BLUE Request_Color = 2
)
var Request_Color_name = map[int32]string{
0: "RED",
1: "GREEN",
2: "BLUE",
}
var Request_Color_value = map[string]int32{
"RED": 0,
"GREEN": 1,
"BLUE": 2,
}
func (x Request_Color) Enum() *Request_Color {
p := new(Request_Color)
*p = x
return p
}
func (x Request_Color) String() string {
return proto.EnumName(Request_Color_name, int32(x))
}
func (x *Request_Color) UnmarshalJSON(data []byte) error {
value, err := proto.UnmarshalJSONEnum(Request_Color_value, data, "Request_Color")
if err != nil {
return err
}
*x = Request_Color(value)
return nil
}
type Reply_Entry_Game int32
const (
Reply_Entry_FOOTBALL Reply_Entry_Game = 1
Reply_Entry_TENNIS Reply_Entry_Game = 2
)
var Reply_Entry_Game_name = map[int32]string{
1: "FOOTBALL",
2: "TENNIS",
}
var Reply_Entry_Game_value = map[string]int32{
"FOOTBALL": 1,
"TENNIS": 2,
}
func (x Reply_Entry_Game) Enum() *Reply_Entry_Game {
p := new(Reply_Entry_Game)
*p = x
return p
}
func (x Reply_Entry_Game) String() string {
return proto.EnumName(Reply_Entry_Game_name, int32(x))
}
func (x *Reply_Entry_Game) UnmarshalJSON(data []byte) error {
value, err := proto.UnmarshalJSONEnum(Reply_Entry_Game_value, data, "Reply_Entry_Game")
if err != nil {
return err
}
*x = Reply_Entry_Game(value)
return nil
}
// This is a message that might be sent somewhere.
type Request struct {
Key []int64 `protobuf:"varint,1,rep,name=key" json:"key,omitempty"`
// optional imp.ImportedMessage imported_message = 2;
Hue *Request_Color `protobuf:"varint,3,opt,name=hue,enum=my.test.Request_Color" json:"hue,omitempty"`
Hat *HatType `protobuf:"varint,4,opt,name=hat,enum=my.test.HatType,def=1" json:"hat,omitempty"`
// optional imp.ImportedMessage.Owner owner = 6;
Deadline *float32 `protobuf:"fixed32,7,opt,name=deadline,def=inf" json:"deadline,omitempty"`
Somegroup *Request_SomeGroup `protobuf:"group,8,opt,name=SomeGroup,json=somegroup" json:"somegroup,omitempty"`
// This is a map field. It will generate map[int32]string.
NameMapping map[int32]string `protobuf:"bytes,14,rep,name=name_mapping,json=nameMapping" json:"name_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
// This is a map field whose value type is a message.
MsgMapping map[int64]*Reply `protobuf:"bytes,15,rep,name=msg_mapping,json=msgMapping" json:"msg_mapping,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
Reset_ *int32 `protobuf:"varint,12,opt,name=reset" json:"reset,omitempty"`
// This field should not conflict with any getters.
GetKey_ *string `protobuf:"bytes,16,opt,name=get_key,json=getKey" json:"get_key,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Request) Reset() { *m = Request{} }
func (m *Request) String() string { return proto.CompactTextString(m) }
func (*Request) ProtoMessage() {}
const Default_Request_Hat HatType = HatType_FEDORA
var Default_Request_Deadline float32 = float32(math.Inf(1))
func (m *Request) GetKey() []int64 {
if m != nil {
return m.Key
}
return nil
}
func (m *Request) GetHue() Request_Color {
if m != nil && m.Hue != nil {
return *m.Hue
}
return Request_RED
}
func (m *Request) GetHat() HatType {
if m != nil && m.Hat != nil {
return *m.Hat
}
return Default_Request_Hat
}
func (m *Request) GetDeadline() float32 {
if m != nil && m.Deadline != nil {
return *m.Deadline
}
return Default_Request_Deadline
}
func (m *Request) GetSomegroup() *Request_SomeGroup {
if m != nil {
return m.Somegroup
}
return nil
}
func (m *Request) GetNameMapping() map[int32]string {
if m != nil {
return m.NameMapping
}
return nil
}
func (m *Request) GetMsgMapping() map[int64]*Reply {
if m != nil {
return m.MsgMapping
}
return nil
}
func (m *Request) GetReset_() int32 {
if m != nil && m.Reset_ != nil {
return *m.Reset_
}
return 0
}
func (m *Request) GetGetKey_() string {
if m != nil && m.GetKey_ != nil {
return *m.GetKey_
}
return ""
}
type Request_SomeGroup struct {
GroupField *int32 `protobuf:"varint,9,opt,name=group_field,json=groupField" json:"group_field,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Request_SomeGroup) Reset() { *m = Request_SomeGroup{} }
func (m *Request_SomeGroup) String() string { return proto.CompactTextString(m) }
func (*Request_SomeGroup) ProtoMessage() {}
func (m *Request_SomeGroup) GetGroupField() int32 {
if m != nil && m.GroupField != nil {
return *m.GroupField
}
return 0
}
type Reply struct {
Found []*Reply_Entry `protobuf:"bytes,1,rep,name=found" json:"found,omitempty"`
CompactKeys []int32 `protobuf:"varint,2,rep,packed,name=compact_keys,json=compactKeys" json:"compact_keys,omitempty"`
proto.XXX_InternalExtensions `json:"-"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Reply) Reset() { *m = Reply{} }
func (m *Reply) String() string { return proto.CompactTextString(m) }
func (*Reply) ProtoMessage() {}
var extRange_Reply = []proto.ExtensionRange{
{100, 536870911},
}
func (*Reply) ExtensionRangeArray() []proto.ExtensionRange {
return extRange_Reply
}
func (m *Reply) GetFound() []*Reply_Entry {
if m != nil {
return m.Found
}
return nil
}
func (m *Reply) GetCompactKeys() []int32 {
if m != nil {
return m.CompactKeys
}
return nil
}
type Reply_Entry struct {
KeyThatNeeds_1234Camel_CasIng *int64 `protobuf:"varint,1,req,name=key_that_needs_1234camel_CasIng,json=keyThatNeeds1234camelCasIng" json:"key_that_needs_1234camel_CasIng,omitempty"`
Value *int64 `protobuf:"varint,2,opt,name=value,def=7" json:"value,omitempty"`
XMyFieldName_2 *int64 `protobuf:"varint,3,opt,name=_my_field_name_2,json=MyFieldName2" json:"_my_field_name_2,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Reply_Entry) Reset() { *m = Reply_Entry{} }
func (m *Reply_Entry) String() string { return proto.CompactTextString(m) }
func (*Reply_Entry) ProtoMessage() {}
const Default_Reply_Entry_Value int64 = 7
func (m *Reply_Entry) GetKeyThatNeeds_1234Camel_CasIng() int64 {
if m != nil && m.KeyThatNeeds_1234Camel_CasIng != nil {
return *m.KeyThatNeeds_1234Camel_CasIng
}
return 0
}
func (m *Reply_Entry) GetValue() int64 {
if m != nil && m.Value != nil {
return *m.Value
}
return Default_Reply_Entry_Value
}
func (m *Reply_Entry) GetXMyFieldName_2() int64 {
if m != nil && m.XMyFieldName_2 != nil {
return *m.XMyFieldName_2
}
return 0
}
type OtherBase struct {
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
proto.XXX_InternalExtensions `json:"-"`
XXX_unrecognized []byte `json:"-"`
}
func (m *OtherBase) Reset() { *m = OtherBase{} }
func (m *OtherBase) String() string { return proto.CompactTextString(m) }
func (*OtherBase) ProtoMessage() {}
var extRange_OtherBase = []proto.ExtensionRange{
{100, 536870911},
}
func (*OtherBase) ExtensionRangeArray() []proto.ExtensionRange {
return extRange_OtherBase
}
func (m *OtherBase) GetName() string {
if m != nil && m.Name != nil {
return *m.Name
}
return ""
}
type ReplyExtensions struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *ReplyExtensions) Reset() { *m = ReplyExtensions{} }
func (m *ReplyExtensions) String() string { return proto.CompactTextString(m) }
func (*ReplyExtensions) ProtoMessage() {}
var E_ReplyExtensions_Time = &proto.ExtensionDesc{
ExtendedType: (*Reply)(nil),
ExtensionType: (*float64)(nil),
Field: 101,
Name: "my.test.ReplyExtensions.time",
Tag: "fixed64,101,opt,name=time",
Filename: "my_test/test.proto",
}
var E_ReplyExtensions_Carrot = &proto.ExtensionDesc{
ExtendedType: (*Reply)(nil),
ExtensionType: (*ReplyExtensions)(nil),
Field: 105,
Name: "my.test.ReplyExtensions.carrot",
Tag: "bytes,105,opt,name=carrot",
Filename: "my_test/test.proto",
}
var E_ReplyExtensions_Donut = &proto.ExtensionDesc{
ExtendedType: (*OtherBase)(nil),
ExtensionType: (*ReplyExtensions)(nil),
Field: 101,
Name: "my.test.ReplyExtensions.donut",
Tag: "bytes,101,opt,name=donut",
Filename: "my_test/test.proto",
}
type OtherReplyExtensions struct {
Key *int32 `protobuf:"varint,1,opt,name=key" json:"key,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *OtherReplyExtensions) Reset() { *m = OtherReplyExtensions{} }
func (m *OtherReplyExtensions) String() string { return proto.CompactTextString(m) }
func (*OtherReplyExtensions) ProtoMessage() {}
func (m *OtherReplyExtensions) GetKey() int32 {
if m != nil && m.Key != nil {
return *m.Key
}
return 0
}
type OldReply struct {
proto.XXX_InternalExtensions `json:"-"`
XXX_unrecognized []byte `json:"-"`
}
func (m *OldReply) Reset() { *m = OldReply{} }
func (m *OldReply) String() string { return proto.CompactTextString(m) }
func (*OldReply) ProtoMessage() {}
func (m *OldReply) Marshal() ([]byte, error) {
return proto.MarshalMessageSet(&m.XXX_InternalExtensions)
}
func (m *OldReply) Unmarshal(buf []byte) error {
return proto.UnmarshalMessageSet(buf, &m.XXX_InternalExtensions)
}
func (m *OldReply) MarshalJSON() ([]byte, error) {
return proto.MarshalMessageSetJSON(&m.XXX_InternalExtensions)
}
func (m *OldReply) UnmarshalJSON(buf []byte) error {
return proto.UnmarshalMessageSetJSON(buf, &m.XXX_InternalExtensions)
}
// ensure OldReply satisfies proto.Marshaler and proto.Unmarshaler
var _ proto.Marshaler = (*OldReply)(nil)
var _ proto.Unmarshaler = (*OldReply)(nil)
var extRange_OldReply = []proto.ExtensionRange{
{100, 2147483646},
}
func (*OldReply) ExtensionRangeArray() []proto.ExtensionRange {
return extRange_OldReply
}
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_Height
// *Communique_Today
// *Communique_Maybe
// *Communique_Delta_
// *Communique_Msg
// *Communique_Somegroup
Union isCommunique_Union `protobuf_oneof:"union"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Communique) Reset() { *m = Communique{} }
func (m *Communique) String() string { return proto.CompactTextString(m) }
func (*Communique) ProtoMessage() {}
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_Height struct {
Height float32 `protobuf:"fixed32,9,opt,name=height,oneof"`
}
type Communique_Today struct {
Today Days `protobuf:"varint,10,opt,name=today,enum=my.test.Days,oneof"`
}
type Communique_Maybe struct {
Maybe bool `protobuf:"varint,11,opt,name=maybe,oneof"`
}
type Communique_Delta_ struct {
Delta int32 `protobuf:"zigzag32,12,opt,name=delta,oneof"`
}
type Communique_Msg struct {
Msg *Reply `protobuf:"bytes,13,opt,name=msg,oneof"`
}
type Communique_Somegroup struct {
Somegroup *Communique_SomeGroup `protobuf:"group,14,opt,name=SomeGroup,json=somegroup,oneof"`
}
func (*Communique_Number) isCommunique_Union() {}
func (*Communique_Name) isCommunique_Union() {}
func (*Communique_Data) isCommunique_Union() {}
func (*Communique_TempC) isCommunique_Union() {}
func (*Communique_Height) isCommunique_Union() {}
func (*Communique_Today) isCommunique_Union() {}
func (*Communique_Maybe) isCommunique_Union() {}
func (*Communique_Delta_) isCommunique_Union() {}
func (*Communique_Msg) isCommunique_Union() {}
func (*Communique_Somegroup) isCommunique_Union() {}
func (m *Communique) GetUnion() isCommunique_Union {
if m != nil {
return m.Union
}
return nil
}
func (m *Communique) GetMakeMeCry() bool {
if m != nil && m.MakeMeCry != nil {
return *m.MakeMeCry
}
return false
}
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) GetHeight() float32 {
if x, ok := m.GetUnion().(*Communique_Height); ok {
return x.Height
}
return 0
}
func (m *Communique) GetToday() Days {
if x, ok := m.GetUnion().(*Communique_Today); ok {
return x.Today
}
return Days_MONDAY
}
func (m *Communique) GetMaybe() bool {
if x, ok := m.GetUnion().(*Communique_Maybe); ok {
return x.Maybe
}
return false
}
func (m *Communique) GetDelta() int32 {
if x, ok := m.GetUnion().(*Communique_Delta_); ok {
return x.Delta
}
return 0
}
func (m *Communique) GetMsg() *Reply {
if x, ok := m.GetUnion().(*Communique_Msg); ok {
return x.Msg
}
return nil
}
func (m *Communique) GetSomegroup() *Communique_SomeGroup {
if x, ok := m.GetUnion().(*Communique_Somegroup); ok {
return x.Somegroup
}
return nil
}
// XXX_OneofFuncs is for the internal use of the proto package.
func (*Communique) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
return _Communique_OneofMarshaler, _Communique_OneofUnmarshaler, _Communique_OneofSizer, []interface{}{
(*Communique_Number)(nil),
(*Communique_Name)(nil),
(*Communique_Data)(nil),
(*Communique_TempC)(nil),
(*Communique_Height)(nil),
(*Communique_Today)(nil),
(*Communique_Maybe)(nil),
(*Communique_Delta_)(nil),
(*Communique_Msg)(nil),
(*Communique_Somegroup)(nil),
}
}
func _Communique_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
m := msg.(*Communique)
// union
switch x := m.Union.(type) {
case *Communique_Number:
b.EncodeVarint(5<<3 | proto.WireVarint)
b.EncodeVarint(uint64(x.Number))
case *Communique_Name:
b.EncodeVarint(6<<3 | proto.WireBytes)
b.EncodeStringBytes(x.Name)
case *Communique_Data:
b.EncodeVarint(7<<3 | proto.WireBytes)
b.EncodeRawBytes(x.Data)
case *Communique_TempC:
b.EncodeVarint(8<<3 | proto.WireFixed64)
b.EncodeFixed64(math.Float64bits(x.TempC))
case *Communique_Height:
b.EncodeVarint(9<<3 | proto.WireFixed32)
b.EncodeFixed32(uint64(math.Float32bits(x.Height)))
case *Communique_Today:
b.EncodeVarint(10<<3 | proto.WireVarint)
b.EncodeVarint(uint64(x.Today))
case *Communique_Maybe:
t := uint64(0)
if x.Maybe {
t = 1
}
b.EncodeVarint(11<<3 | proto.WireVarint)
b.EncodeVarint(t)
case *Communique_Delta_:
b.EncodeVarint(12<<3 | proto.WireVarint)
b.EncodeZigzag32(uint64(x.Delta))
case *Communique_Msg:
b.EncodeVarint(13<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Msg); err != nil {
return err
}
case *Communique_Somegroup:
b.EncodeVarint(14<<3 | proto.WireStartGroup)
if err := b.Marshal(x.Somegroup); err != nil {
return err
}
b.EncodeVarint(14<<3 | proto.WireEndGroup)
case nil:
default:
return fmt.Errorf("Communique.Union has unexpected type %T", x)
}
return nil
}
func _Communique_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
m := msg.(*Communique)
switch tag {
case 5: // union.number
if wire != proto.WireVarint {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeVarint()
m.Union = &Communique_Number{int32(x)}
return true, err
case 6: // union.name
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeStringBytes()
m.Union = &Communique_Name{x}
return true, err
case 7: // union.data
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeRawBytes(true)
m.Union = &Communique_Data{x}
return true, err
case 8: // union.temp_c
if wire != proto.WireFixed64 {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeFixed64()
m.Union = &Communique_TempC{math.Float64frombits(x)}
return true, err
case 9: // union.height
if wire != proto.WireFixed32 {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeFixed32()
m.Union = &Communique_Height{math.Float32frombits(uint32(x))}
return true, err
case 10: // union.today
if wire != proto.WireVarint {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeVarint()
m.Union = &Communique_Today{Days(x)}
return true, err
case 11: // union.maybe
if wire != proto.WireVarint {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeVarint()
m.Union = &Communique_Maybe{x != 0}
return true, err
case 12: // union.delta
if wire != proto.WireVarint {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeZigzag32()
m.Union = &Communique_Delta_{int32(x)}
return true, err
case 13: // union.msg
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(Reply)
err := b.DecodeMessage(msg)
m.Union = &Communique_Msg{msg}
return true, err
case 14: // union.somegroup
if wire != proto.WireStartGroup {
return true, proto.ErrInternalBadWireType
}
msg := new(Communique_SomeGroup)
err := b.DecodeGroup(msg)
m.Union = &Communique_Somegroup{msg}
return true, err
default:
return false, nil
}
}
func _Communique_OneofSizer(msg proto.Message) (n int) {
m := msg.(*Communique)
// union
switch x := m.Union.(type) {
case *Communique_Number:
n += proto.SizeVarint(5<<3 | proto.WireVarint)
n += proto.SizeVarint(uint64(x.Number))
case *Communique_Name:
n += proto.SizeVarint(6<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.Name)))
n += len(x.Name)
case *Communique_Data:
n += proto.SizeVarint(7<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.Data)))
n += len(x.Data)
case *Communique_TempC:
n += proto.SizeVarint(8<<3 | proto.WireFixed64)
n += 8
case *Communique_Height:
n += proto.SizeVarint(9<<3 | proto.WireFixed32)
n += 4
case *Communique_Today:
n += proto.SizeVarint(10<<3 | proto.WireVarint)
n += proto.SizeVarint(uint64(x.Today))
case *Communique_Maybe:
n += proto.SizeVarint(11<<3 | proto.WireVarint)
n += 1
case *Communique_Delta_:
n += proto.SizeVarint(12<<3 | proto.WireVarint)
n += proto.SizeVarint(uint64((uint32(x.Delta) << 1) ^ uint32((int32(x.Delta) >> 31))))
case *Communique_Msg:
s := proto.Size(x.Msg)
n += proto.SizeVarint(13<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case *Communique_Somegroup:
n += proto.SizeVarint(14<<3 | proto.WireStartGroup)
n += proto.Size(x.Somegroup)
n += proto.SizeVarint(14<<3 | proto.WireEndGroup)
case nil:
default:
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
}
return n
}
type Communique_SomeGroup struct {
Member *string `protobuf:"bytes,15,opt,name=member" json:"member,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Communique_SomeGroup) Reset() { *m = Communique_SomeGroup{} }
func (m *Communique_SomeGroup) String() string { return proto.CompactTextString(m) }
func (*Communique_SomeGroup) ProtoMessage() {}
func (m *Communique_SomeGroup) GetMember() string {
if m != nil && m.Member != nil {
return *m.Member
}
return ""
}
type Communique_Delta struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *Communique_Delta) Reset() { *m = Communique_Delta{} }
func (m *Communique_Delta) String() string { return proto.CompactTextString(m) }
func (*Communique_Delta) ProtoMessage() {}
var E_Tag = &proto.ExtensionDesc{
ExtendedType: (*Reply)(nil),
ExtensionType: (*string)(nil),
Field: 103,
Name: "my.test.tag",
Tag: "bytes,103,opt,name=tag",
Filename: "my_test/test.proto",
}
var E_Donut = &proto.ExtensionDesc{
ExtendedType: (*Reply)(nil),
ExtensionType: (*OtherReplyExtensions)(nil),
Field: 106,
Name: "my.test.donut",
Tag: "bytes,106,opt,name=donut",
Filename: "my_test/test.proto",
}
func init() {
proto.RegisterType((*Request)(nil), "my.test.Request")
proto.RegisterType((*Request_SomeGroup)(nil), "my.test.Request.SomeGroup")
proto.RegisterType((*Reply)(nil), "my.test.Reply")
proto.RegisterType((*Reply_Entry)(nil), "my.test.Reply.Entry")
proto.RegisterType((*OtherBase)(nil), "my.test.OtherBase")
proto.RegisterType((*ReplyExtensions)(nil), "my.test.ReplyExtensions")
proto.RegisterType((*OtherReplyExtensions)(nil), "my.test.OtherReplyExtensions")
proto.RegisterType((*OldReply)(nil), "my.test.OldReply")
proto.RegisterType((*Communique)(nil), "my.test.Communique")
proto.RegisterType((*Communique_SomeGroup)(nil), "my.test.Communique.SomeGroup")
proto.RegisterType((*Communique_Delta)(nil), "my.test.Communique.Delta")
proto.RegisterEnum("my.test.HatType", HatType_name, HatType_value)
proto.RegisterEnum("my.test.Days", Days_name, Days_value)
proto.RegisterEnum("my.test.Request_Color", Request_Color_name, Request_Color_value)
proto.RegisterEnum("my.test.Reply_Entry_Game", Reply_Entry_Game_name, Reply_Entry_Game_value)
proto.RegisterExtension(E_ReplyExtensions_Time)
proto.RegisterExtension(E_ReplyExtensions_Carrot)
proto.RegisterExtension(E_ReplyExtensions_Donut)
proto.RegisterExtension(E_Tag)
proto.RegisterExtension(E_Donut)
}

View File

@@ -1,6 +1,5 @@
// Code generated by protoc-gen-go.
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: my_test/test.proto
// DO NOT EDIT!
/*
Package my_test is a generated protocol buffer package.
@@ -33,7 +32,9 @@ 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.
const _ = proto.ProtoPackageIsVersion1
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type HatType int32
@@ -183,14 +184,14 @@ type Request struct {
Hat *HatType `protobuf:"varint,4,opt,name=hat,enum=my.test.HatType,def=1" json:"hat,omitempty"`
// optional imp.ImportedMessage.Owner owner = 6;
Deadline *float32 `protobuf:"fixed32,7,opt,name=deadline,def=inf" json:"deadline,omitempty"`
Somegroup *Request_SomeGroup `protobuf:"group,8,opt,name=SomeGroup" json:"somegroup,omitempty"`
Somegroup *Request_SomeGroup `protobuf:"group,8,opt,name=SomeGroup,json=somegroup" json:"somegroup,omitempty"`
// This is a map field. It will generate map[int32]string.
NameMapping map[int32]string `protobuf:"bytes,14,rep,name=name_mapping" json:"name_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
NameMapping map[int32]string `protobuf:"bytes,14,rep,name=name_mapping,json=nameMapping" json:"name_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
// This is a map field whose value type is a message.
MsgMapping map[int64]*Reply `protobuf:"bytes,15,rep,name=msg_mapping" json:"msg_mapping,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
MsgMapping map[int64]*Reply `protobuf:"bytes,15,rep,name=msg_mapping,json=msgMapping" json:"msg_mapping,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
Reset_ *int32 `protobuf:"varint,12,opt,name=reset" json:"reset,omitempty"`
// This field should not conflict with any getters.
GetKey_ *string `protobuf:"bytes,16,opt,name=get_key" json:"get_key,omitempty"`
GetKey_ *string `protobuf:"bytes,16,opt,name=get_key,json=getKey" json:"get_key,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
@@ -266,7 +267,7 @@ func (m *Request) GetGetKey_() string {
}
type Request_SomeGroup struct {
GroupField *int32 `protobuf:"varint,9,opt,name=group_field" json:"group_field,omitempty"`
GroupField *int32 `protobuf:"varint,9,opt,name=group_field,json=groupField" json:"group_field,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
@@ -282,10 +283,10 @@ func (m *Request_SomeGroup) GetGroupField() int32 {
}
type Reply struct {
Found []*Reply_Entry `protobuf:"bytes,1,rep,name=found" json:"found,omitempty"`
CompactKeys []int32 `protobuf:"varint,2,rep,packed,name=compact_keys" json:"compact_keys,omitempty"`
XXX_extensions map[int32]proto.Extension `json:"-"`
XXX_unrecognized []byte `json:"-"`
Found []*Reply_Entry `protobuf:"bytes,1,rep,name=found" json:"found,omitempty"`
CompactKeys []int32 `protobuf:"varint,2,rep,packed,name=compact_keys,json=compactKeys" json:"compact_keys,omitempty"`
proto.XXX_InternalExtensions `json:"-"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Reply) Reset() { *m = Reply{} }
@@ -299,12 +300,6 @@ var extRange_Reply = []proto.ExtensionRange{
func (*Reply) ExtensionRangeArray() []proto.ExtensionRange {
return extRange_Reply
}
func (m *Reply) ExtensionMap() map[int32]proto.Extension {
if m.XXX_extensions == nil {
m.XXX_extensions = make(map[int32]proto.Extension)
}
return m.XXX_extensions
}
func (m *Reply) GetFound() []*Reply_Entry {
if m != nil {
@@ -321,9 +316,9 @@ func (m *Reply) GetCompactKeys() []int32 {
}
type Reply_Entry struct {
KeyThatNeeds_1234Camel_CasIng *int64 `protobuf:"varint,1,req,name=key_that_needs_1234camel_CasIng" json:"key_that_needs_1234camel_CasIng,omitempty"`
KeyThatNeeds_1234Camel_CasIng *int64 `protobuf:"varint,1,req,name=key_that_needs_1234camel_CasIng,json=keyThatNeeds1234camelCasIng" json:"key_that_needs_1234camel_CasIng,omitempty"`
Value *int64 `protobuf:"varint,2,opt,name=value,def=7" json:"value,omitempty"`
XMyFieldName_2 *int64 `protobuf:"varint,3,opt,name=_my_field_name_2" json:"_my_field_name_2,omitempty"`
XMyFieldName_2 *int64 `protobuf:"varint,3,opt,name=_my_field_name_2,json=MyFieldName2" json:"_my_field_name_2,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
@@ -355,9 +350,9 @@ func (m *Reply_Entry) GetXMyFieldName_2() int64 {
}
type OtherBase struct {
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
XXX_extensions map[int32]proto.Extension `json:"-"`
XXX_unrecognized []byte `json:"-"`
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
proto.XXX_InternalExtensions `json:"-"`
XXX_unrecognized []byte `json:"-"`
}
func (m *OtherBase) Reset() { *m = OtherBase{} }
@@ -371,12 +366,6 @@ var extRange_OtherBase = []proto.ExtensionRange{
func (*OtherBase) ExtensionRangeArray() []proto.ExtensionRange {
return extRange_OtherBase
}
func (m *OtherBase) ExtensionMap() map[int32]proto.Extension {
if m.XXX_extensions == nil {
m.XXX_extensions = make(map[int32]proto.Extension)
}
return m.XXX_extensions
}
func (m *OtherBase) GetName() string {
if m != nil && m.Name != nil {
@@ -399,6 +388,7 @@ var E_ReplyExtensions_Time = &proto.ExtensionDesc{
Field: 101,
Name: "my.test.ReplyExtensions.time",
Tag: "fixed64,101,opt,name=time",
Filename: "my_test/test.proto",
}
var E_ReplyExtensions_Carrot = &proto.ExtensionDesc{
@@ -407,6 +397,7 @@ var E_ReplyExtensions_Carrot = &proto.ExtensionDesc{
Field: 105,
Name: "my.test.ReplyExtensions.carrot",
Tag: "bytes,105,opt,name=carrot",
Filename: "my_test/test.proto",
}
var E_ReplyExtensions_Donut = &proto.ExtensionDesc{
@@ -415,6 +406,7 @@ var E_ReplyExtensions_Donut = &proto.ExtensionDesc{
Field: 101,
Name: "my.test.ReplyExtensions.donut",
Tag: "bytes,101,opt,name=donut",
Filename: "my_test/test.proto",
}
type OtherReplyExtensions struct {
@@ -434,8 +426,8 @@ func (m *OtherReplyExtensions) GetKey() int32 {
}
type OldReply struct {
XXX_extensions map[int32]proto.Extension `json:"-"`
XXX_unrecognized []byte `json:"-"`
proto.XXX_InternalExtensions `json:"-"`
XXX_unrecognized []byte `json:"-"`
}
func (m *OldReply) Reset() { *m = OldReply{} }
@@ -443,16 +435,16 @@ func (m *OldReply) String() string { return proto.CompactTextString(m) }
func (*OldReply) ProtoMessage() {}
func (m *OldReply) Marshal() ([]byte, error) {
return proto.MarshalMessageSet(m.ExtensionMap())
return proto.MarshalMessageSet(&m.XXX_InternalExtensions)
}
func (m *OldReply) Unmarshal(buf []byte) error {
return proto.UnmarshalMessageSet(buf, m.ExtensionMap())
return proto.UnmarshalMessageSet(buf, &m.XXX_InternalExtensions)
}
func (m *OldReply) MarshalJSON() ([]byte, error) {
return proto.MarshalMessageSetJSON(m.XXX_extensions)
return proto.MarshalMessageSetJSON(&m.XXX_InternalExtensions)
}
func (m *OldReply) UnmarshalJSON(buf []byte) error {
return proto.UnmarshalMessageSetJSON(buf, m.XXX_extensions)
return proto.UnmarshalMessageSetJSON(buf, &m.XXX_InternalExtensions)
}
// ensure OldReply satisfies proto.Marshaler and proto.Unmarshaler
@@ -466,15 +458,9 @@ var extRange_OldReply = []proto.ExtensionRange{
func (*OldReply) ExtensionRangeArray() []proto.ExtensionRange {
return extRange_OldReply
}
func (m *OldReply) ExtensionMap() map[int32]proto.Extension {
if m.XXX_extensions == nil {
m.XXX_extensions = make(map[int32]proto.Extension)
}
return m.XXX_extensions
}
type Communique struct {
MakeMeCry *bool `protobuf:"varint,1,opt,name=make_me_cry" json:"make_me_cry,omitempty"`
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:
@@ -510,7 +496,7 @@ 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,oneof"`
TempC float64 `protobuf:"fixed64,8,opt,name=temp_c,json=tempC,oneof"`
}
type Communique_Height struct {
Height float32 `protobuf:"fixed32,9,opt,name=height,oneof"`
@@ -528,7 +514,7 @@ type Communique_Msg struct {
Msg *Reply `protobuf:"bytes,13,opt,name=msg,oneof"`
}
type Communique_Somegroup struct {
Somegroup *Communique_SomeGroup `protobuf:"group,14,opt,name=SomeGroup,oneof"`
Somegroup *Communique_SomeGroup `protobuf:"group,14,opt,name=SomeGroup,json=somegroup,oneof"`
}
func (*Communique_Number) isCommunique_Union() {}
@@ -848,6 +834,7 @@ var E_Tag = &proto.ExtensionDesc{
Field: 103,
Name: "my.test.tag",
Tag: "bytes,103,opt,name=tag",
Filename: "my_test/test.proto",
}
var E_Donut = &proto.ExtensionDesc{
@@ -856,6 +843,7 @@ var E_Donut = &proto.ExtensionDesc{
Field: 106,
Name: "my.test.donut",
Tag: "bytes,106,opt,name=donut",
Filename: "my_test/test.proto",
}
func init() {

View File

@@ -44,6 +44,7 @@ message Request {
repeated int64 key = 2;
Flavour taste = 3;
Book book = 4;
repeated int64 unpacked = 5 [packed=false];
}
message Book {

139
vendor/github.com/golang/protobuf/ptypes/any.go generated vendored Normal file
View File

@@ -0,0 +1,139 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// 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.
package ptypes
// This file implements functions to marshal proto.Message to/from
// google.protobuf.Any message.
import (
"fmt"
"reflect"
"strings"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes/any"
)
const googleApis = "type.googleapis.com/"
// AnyMessageName returns the name of the message contained in a google.protobuf.Any message.
//
// Note that regular type assertions should be done using the Is
// function. AnyMessageName is provided for less common use cases like filtering a
// sequence of Any messages based on a set of allowed message type names.
func AnyMessageName(any *any.Any) (string, error) {
if any == nil {
return "", fmt.Errorf("message is nil")
}
slash := strings.LastIndex(any.TypeUrl, "/")
if slash < 0 {
return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl)
}
return any.TypeUrl[slash+1:], nil
}
// MarshalAny takes the protocol buffer and encodes it into google.protobuf.Any.
func MarshalAny(pb proto.Message) (*any.Any, error) {
value, err := proto.Marshal(pb)
if err != nil {
return nil, err
}
return &any.Any{TypeUrl: googleApis + proto.MessageName(pb), Value: value}, nil
}
// DynamicAny is a value that can be passed to UnmarshalAny to automatically
// allocate a proto.Message for the type specified in a google.protobuf.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)
type DynamicAny struct {
proto.Message
}
// Empty returns a new proto.Message of the type specified in a
// google.protobuf.Any message. It returns an error if corresponding message
// type isn't linked in.
func Empty(any *any.Any) (proto.Message, error) {
aname, err := AnyMessageName(any)
if err != nil {
return nil, err
}
t := proto.MessageType(aname)
if t == nil {
return nil, fmt.Errorf("any: message type %q isn't linked in", aname)
}
return reflect.New(t.Elem()).Interface().(proto.Message), nil
}
// UnmarshalAny parses the protocol buffer representation in a google.protobuf.Any
// message and places the decoded result in pb. It returns an error if type of
// contents of Any message does not match type of pb message.
//
// pb can be a proto.Message, or a *DynamicAny.
func UnmarshalAny(any *any.Any, pb proto.Message) error {
if d, ok := pb.(*DynamicAny); ok {
if d.Message == nil {
var err error
d.Message, err = Empty(any)
if err != nil {
return err
}
}
return UnmarshalAny(any, d.Message)
}
aname, err := AnyMessageName(any)
if err != nil {
return err
}
mname := proto.MessageName(pb)
if aname != mname {
return fmt.Errorf("mismatched message type: got %q want %q", aname, mname)
}
return proto.Unmarshal(any.Value, pb)
}
// Is returns true if any value contains a given message type.
func Is(any *any.Any, pb proto.Message) bool {
aname, err := AnyMessageName(any)
if err != nil {
return false
}
return aname == proto.MessageName(pb)
}

168
vendor/github.com/golang/protobuf/ptypes/any/any.pb.go generated vendored Normal file
View File

@@ -0,0 +1,168 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: github.com/golang/protobuf/ptypes/any/any.proto
/*
Package any is a generated protocol buffer package.
It is generated from these files:
github.com/golang/protobuf/ptypes/any/any.proto
It has these top-level messages:
Any
*/
package any
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import 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.ProtoPackageIsVersion2 // please upgrade the proto package
// `Any` contains an arbitrary serialized protocol buffer message along with a
// URL that describes the type of the serialized message.
//
// Protobuf library provides support to pack/unpack Any values in the form
// of utility functions or additional generated methods of the Any type.
//
// Example 1: Pack and unpack a message in C++.
//
// Foo foo = ...;
// Any any;
// any.PackFrom(foo);
// ...
// if (any.UnpackTo(&foo)) {
// ...
// }
//
// Example 2: Pack and unpack a message in Java.
//
// Foo foo = ...;
// Any any = Any.pack(foo);
// ...
// if (any.is(Foo.class)) {
// foo = any.unpack(Foo.class);
// }
//
// Example 3: Pack and unpack a message in Python.
//
// foo = Foo(...)
// any = Any()
// any.Pack(foo)
// ...
// if any.Is(Foo.DESCRIPTOR):
// any.Unpack(foo)
// ...
//
// The pack methods provided by protobuf library will by default use
// 'type.googleapis.com/full.type.name' as the type URL and the unpack
// methods only use the fully qualified type name after the last '/'
// in the type URL, for example "foo.bar.com/x/y.z" will yield type
// name "y.z".
//
//
// JSON
// ====
// The JSON representation of an `Any` value uses the regular
// representation of the deserialized, embedded message, with an
// additional field `@type` which contains the type URL. Example:
//
// package google.profile;
// message Person {
// string first_name = 1;
// string last_name = 2;
// }
//
// {
// "@type": "type.googleapis.com/google.profile.Person",
// "firstName": <string>,
// "lastName": <string>
// }
//
// If the embedded message type is well-known and has a custom JSON
// representation, that representation will be embedded adding a field
// `value` which holds the custom JSON in addition to the `@type`
// field. Example (for message [google.protobuf.Duration][]):
//
// {
// "@type": "type.googleapis.com/google.protobuf.Duration",
// "value": "1.212s"
// }
//
type Any struct {
// A URL/resource name whose content describes the type of the
// serialized protocol buffer message.
//
// For URLs which use the scheme `http`, `https`, or no scheme, the
// following restrictions and interpretations apply:
//
// * If no scheme is provided, `https` is assumed.
// * The last segment of the URL's path must represent the fully
// qualified name of the type (as in `path/google.protobuf.Duration`).
// The name should be in a canonical form (e.g., leading "." is
// not accepted).
// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
// value in binary format, or produce an error.
// * Applications are allowed to cache lookup results based on the
// URL, or have them precompiled into a binary to avoid any
// lookup. Therefore, binary compatibility needs to be preserved
// on changes to types. (Use versioned type names to manage
// breaking changes.)
//
// Schemes other than `http`, `https` (or the empty scheme) might be
// used with implementation specific semantics.
//
TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl" json:"type_url,omitempty"`
// Must be a valid serialized protocol buffer of the above specified type.
Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
}
func (m *Any) Reset() { *m = Any{} }
func (m *Any) String() string { return proto.CompactTextString(m) }
func (*Any) ProtoMessage() {}
func (*Any) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (*Any) XXX_WellKnownType() string { return "Any" }
func (m *Any) GetTypeUrl() string {
if m != nil {
return m.TypeUrl
}
return ""
}
func (m *Any) GetValue() []byte {
if m != nil {
return m.Value
}
return nil
}
func init() {
proto.RegisterType((*Any)(nil), "google.protobuf.Any")
}
func init() { proto.RegisterFile("github.com/golang/protobuf/ptypes/any/any.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 184 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4f, 0xcf, 0x2c, 0xc9,
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28,
0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0x28, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x4f, 0xcc,
0xab, 0x04, 0x61, 0x3d, 0xb0, 0xb8, 0x10, 0x7f, 0x7a, 0x7e, 0x7e, 0x7a, 0x4e, 0xaa, 0x1e, 0x4c,
0x95, 0x92, 0x19, 0x17, 0xb3, 0x63, 0x5e, 0xa5, 0x90, 0x24, 0x17, 0x07, 0x48, 0x79, 0x7c, 0x69,
0x51, 0x8e, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0x67, 0x10, 0x3b, 0x88, 0x1f, 0x5a, 0x94, 0x23, 0x24,
0xc2, 0xc5, 0x5a, 0x96, 0x98, 0x53, 0x9a, 0x2a, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x13, 0x04, 0xe1,
0x38, 0xe5, 0x73, 0x09, 0x27, 0xe7, 0xe7, 0xea, 0xa1, 0x19, 0xe7, 0xc4, 0xe1, 0x98, 0x57, 0x19,
0x00, 0xe2, 0x04, 0x30, 0x46, 0xa9, 0x12, 0xe5, 0xb8, 0x45, 0x4c, 0xcc, 0xee, 0x01, 0x4e, 0xab,
0x98, 0xe4, 0xdc, 0x21, 0x46, 0x05, 0x40, 0x95, 0xe8, 0x85, 0xa7, 0xe6, 0xe4, 0x78, 0xe7, 0xe5,
0x97, 0xe7, 0x85, 0x80, 0x94, 0x26, 0xb1, 0x81, 0xf5, 0x1a, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff,
0x45, 0x1f, 0x1a, 0xf2, 0xf3, 0x00, 0x00, 0x00,
}

139
vendor/github.com/golang/protobuf/ptypes/any/any.proto generated vendored Normal file
View File

@@ -0,0 +1,139 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
syntax = "proto3";
package google.protobuf;
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option go_package = "github.com/golang/protobuf/ptypes/any";
option java_package = "com.google.protobuf";
option java_outer_classname = "AnyProto";
option java_multiple_files = true;
option objc_class_prefix = "GPB";
// `Any` contains an arbitrary serialized protocol buffer message along with a
// URL that describes the type of the serialized message.
//
// Protobuf library provides support to pack/unpack Any values in the form
// of utility functions or additional generated methods of the Any type.
//
// Example 1: Pack and unpack a message in C++.
//
// Foo foo = ...;
// Any any;
// any.PackFrom(foo);
// ...
// if (any.UnpackTo(&foo)) {
// ...
// }
//
// Example 2: Pack and unpack a message in Java.
//
// Foo foo = ...;
// Any any = Any.pack(foo);
// ...
// if (any.is(Foo.class)) {
// foo = any.unpack(Foo.class);
// }
//
// Example 3: Pack and unpack a message in Python.
//
// foo = Foo(...)
// any = Any()
// any.Pack(foo)
// ...
// if any.Is(Foo.DESCRIPTOR):
// any.Unpack(foo)
// ...
//
// The pack methods provided by protobuf library will by default use
// 'type.googleapis.com/full.type.name' as the type URL and the unpack
// methods only use the fully qualified type name after the last '/'
// in the type URL, for example "foo.bar.com/x/y.z" will yield type
// name "y.z".
//
//
// JSON
// ====
// The JSON representation of an `Any` value uses the regular
// representation of the deserialized, embedded message, with an
// additional field `@type` which contains the type URL. Example:
//
// package google.profile;
// message Person {
// string first_name = 1;
// string last_name = 2;
// }
//
// {
// "@type": "type.googleapis.com/google.profile.Person",
// "firstName": <string>,
// "lastName": <string>
// }
//
// If the embedded message type is well-known and has a custom JSON
// representation, that representation will be embedded adding a field
// `value` which holds the custom JSON in addition to the `@type`
// field. Example (for message [google.protobuf.Duration][]):
//
// {
// "@type": "type.googleapis.com/google.protobuf.Duration",
// "value": "1.212s"
// }
//
message Any {
// A URL/resource name whose content describes the type of the
// serialized protocol buffer message.
//
// For URLs which use the scheme `http`, `https`, or no scheme, the
// following restrictions and interpretations apply:
//
// * If no scheme is provided, `https` is assumed.
// * The last segment of the URL's path must represent the fully
// qualified name of the type (as in `path/google.protobuf.Duration`).
// The name should be in a canonical form (e.g., leading "." is
// not accepted).
// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
// value in binary format, or produce an error.
// * Applications are allowed to cache lookup results based on the
// URL, or have them precompiled into a binary to avoid any
// lookup. Therefore, binary compatibility needs to be preserved
// on changes to types. (Use versioned type names to manage
// breaking changes.)
//
// Schemes other than `http`, `https` (or the empty scheme) might be
// used with implementation specific semantics.
//
string type_url = 1;
// Must be a valid serialized protocol buffer of the above specified type.
bytes value = 2;
}

113
vendor/github.com/golang/protobuf/ptypes/any_test.go generated vendored Normal file
View File

@@ -0,0 +1,113 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// 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.
package ptypes
import (
"testing"
"github.com/golang/protobuf/proto"
pb "github.com/golang/protobuf/protoc-gen-go/descriptor"
"github.com/golang/protobuf/ptypes/any"
)
func TestMarshalUnmarshal(t *testing.T) {
orig := &any.Any{Value: []byte("test")}
packed, err := MarshalAny(orig)
if err != nil {
t.Errorf("MarshalAny(%+v): got: _, %v exp: _, nil", orig, err)
}
unpacked := &any.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(&pb.FileDescriptorProto{})
if err != nil {
t.Fatal(err)
}
if Is(a, &pb.DescriptorProto{}) {
t.Error("FileDescriptorProto is not a DescriptorProto, but Is says it is")
}
if !Is(a, &pb.FileDescriptorProto{}) {
t.Error("FileDescriptorProto is indeed a FileDescriptorProto, but Is says it is not")
}
}
func TestIsDifferentUrlPrefixes(t *testing.T) {
m := &pb.FileDescriptorProto{}
a := &any.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 TestUnmarshalDynamic(t *testing.T) {
want := &pb.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 := &pb.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)
}
}

35
vendor/github.com/golang/protobuf/ptypes/doc.go generated vendored Normal file
View File

@@ -0,0 +1,35 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// 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.
/*
Package ptypes contains code for interacting with well-known types.
*/
package ptypes

102
vendor/github.com/golang/protobuf/ptypes/duration.go generated vendored Normal file
View File

@@ -0,0 +1,102 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// 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.
package ptypes
// This file implements conversions between google.protobuf.Duration
// and time.Duration.
import (
"errors"
"fmt"
"time"
durpb "github.com/golang/protobuf/ptypes/duration"
)
const (
// Range of a durpb.Duration in seconds, as specified in
// google/protobuf/duration.proto. This is about 10,000 years in seconds.
maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)
minSeconds = -maxSeconds
)
// validateDuration determines whether the durpb.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 (the range of durpb.Duration
// is about 10,000 years, and the range of time.Duration is about 290).
func validateDuration(d *durpb.Duration) error {
if d == nil {
return errors.New("duration: nil Duration")
}
if d.Seconds < minSeconds || d.Seconds > maxSeconds {
return fmt.Errorf("duration: %v: seconds out of range", d)
}
if d.Nanos <= -1e9 || d.Nanos >= 1e9 {
return fmt.Errorf("duration: %v: nanos out of range", d)
}
// Seconds and Nanos must have the same sign, unless d.Nanos is zero.
if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) {
return fmt.Errorf("duration: %v: seconds and nanos have different signs", d)
}
return nil
}
// Duration converts a durpb.Duration to a time.Duration. Duration
// returns an error if the durpb.Duration is invalid or is too large to be
// represented in a time.Duration.
func Duration(p *durpb.Duration) (time.Duration, error) {
if err := validateDuration(p); err != nil {
return 0, err
}
d := time.Duration(p.Seconds) * time.Second
if int64(d/time.Second) != p.Seconds {
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
}
if p.Nanos != 0 {
d += time.Duration(p.Nanos)
if (d < 0) != (p.Nanos < 0) {
return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
}
}
return d, nil
}
// DurationProto converts a time.Duration to a durpb.Duration.
func DurationProto(d time.Duration) *durpb.Duration {
nanos := d.Nanoseconds()
secs := nanos / 1e9
nanos -= secs * 1e9
return &durpb.Duration{
Seconds: secs,
Nanos: int32(nanos),
}
}

View File

@@ -0,0 +1,146 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: github.com/golang/protobuf/ptypes/duration/duration.proto
/*
Package duration is a generated protocol buffer package.
It is generated from these files:
github.com/golang/protobuf/ptypes/duration/duration.proto
It has these top-level messages:
Duration
*/
package duration
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import 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.ProtoPackageIsVersion2 // please upgrade the proto package
// A Duration represents a signed, fixed-length span of time represented
// as a count of seconds and fractions of seconds at nanosecond
// resolution. It is independent of any calendar and concepts like "day"
// or "month". It is related to Timestamp in that the difference between
// two Timestamp values is a Duration and it can be added or subtracted
// from a Timestamp. Range is approximately +-10,000 years.
//
// # Examples
//
// Example 1: Compute Duration from two Timestamps in pseudo code.
//
// Timestamp start = ...;
// Timestamp end = ...;
// Duration duration = ...;
//
// duration.seconds = end.seconds - start.seconds;
// duration.nanos = end.nanos - start.nanos;
//
// if (duration.seconds < 0 && duration.nanos > 0) {
// duration.seconds += 1;
// duration.nanos -= 1000000000;
// } else if (durations.seconds > 0 && duration.nanos < 0) {
// duration.seconds -= 1;
// duration.nanos += 1000000000;
// }
//
// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
//
// Timestamp start = ...;
// Duration duration = ...;
// Timestamp end = ...;
//
// end.seconds = start.seconds + duration.seconds;
// end.nanos = start.nanos + duration.nanos;
//
// if (end.nanos < 0) {
// end.seconds -= 1;
// end.nanos += 1000000000;
// } else if (end.nanos >= 1000000000) {
// end.seconds += 1;
// end.nanos -= 1000000000;
// }
//
// Example 3: Compute Duration from datetime.timedelta in Python.
//
// td = datetime.timedelta(days=3, minutes=10)
// duration = Duration()
// duration.FromTimedelta(td)
//
// # JSON Mapping
//
// In JSON format, the Duration type is encoded as a string rather than an
// object, where the string ends in the suffix "s" (indicating seconds) and
// is preceded by the number of seconds, with nanoseconds expressed as
// fractional seconds. For example, 3 seconds with 0 nanoseconds should be
// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
// be expressed in JSON format as "3.000000001s", and 3 seconds and 1
// microsecond should be expressed in JSON format as "3.000001s".
//
//
type Duration struct {
// Signed seconds of the span of time. Must be from -315,576,000,000
// to +315,576,000,000 inclusive. Note: these bounds are computed from:
// 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"`
// Signed fractions of a second at nanosecond resolution of the span
// of time. Durations less than one second are represented with a 0
// `seconds` field and a positive or negative `nanos` field. For durations
// of one second or more, a non-zero value for the `nanos` field must be
// of the same sign as the `seconds` field. Must be from -999,999,999
// to +999,999,999 inclusive.
Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"`
}
func (m *Duration) Reset() { *m = Duration{} }
func (m *Duration) String() string { return proto.CompactTextString(m) }
func (*Duration) ProtoMessage() {}
func (*Duration) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (*Duration) XXX_WellKnownType() string { return "Duration" }
func (m *Duration) GetSeconds() int64 {
if m != nil {
return m.Seconds
}
return 0
}
func (m *Duration) GetNanos() int32 {
if m != nil {
return m.Nanos
}
return 0
}
func init() {
proto.RegisterType((*Duration)(nil), "google.protobuf.Duration")
}
func init() {
proto.RegisterFile("github.com/golang/protobuf/ptypes/duration/duration.proto", fileDescriptor0)
}
var fileDescriptor0 = []byte{
// 189 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xb2, 0x4c, 0xcf, 0x2c, 0xc9,
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28,
0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0x28, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x4f, 0x29,
0x2d, 0x4a, 0x2c, 0xc9, 0xcc, 0xcf, 0x83, 0x33, 0xf4, 0xc0, 0x2a, 0x84, 0xf8, 0xd3, 0xf3, 0xf3,
0xd3, 0x73, 0x52, 0xf5, 0x60, 0xea, 0x95, 0xac, 0xb8, 0x38, 0x5c, 0xa0, 0x4a, 0x84, 0x24, 0xb8,
0xd8, 0x8b, 0x53, 0x93, 0xf3, 0xf3, 0x52, 0x8a, 0x25, 0x18, 0x15, 0x18, 0x35, 0x98, 0x83, 0x60,
0x5c, 0x21, 0x11, 0x2e, 0xd6, 0xbc, 0xc4, 0xbc, 0xfc, 0x62, 0x09, 0x26, 0x05, 0x46, 0x0d, 0xd6,
0x20, 0x08, 0xc7, 0xa9, 0x86, 0x4b, 0x38, 0x39, 0x3f, 0x57, 0x0f, 0xcd, 0x48, 0x27, 0x5e, 0x98,
0x81, 0x01, 0x20, 0x91, 0x00, 0xc6, 0x28, 0x2d, 0xe2, 0xdd, 0xfb, 0x83, 0x91, 0x71, 0x11, 0x13,
0xb3, 0x7b, 0x80, 0xd3, 0x2a, 0x26, 0x39, 0x77, 0x88, 0xb9, 0x01, 0x50, 0xa5, 0x7a, 0xe1, 0xa9,
0x39, 0x39, 0xde, 0x79, 0xf9, 0xe5, 0x79, 0x21, 0x20, 0x2d, 0x49, 0x6c, 0x60, 0x33, 0x8c, 0x01,
0x01, 0x00, 0x00, 0xff, 0xff, 0x45, 0x5a, 0x81, 0x3d, 0x0e, 0x01, 0x00, 0x00,
}

View File

@@ -0,0 +1,117 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
syntax = "proto3";
package google.protobuf;
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option cc_enable_arenas = true;
option go_package = "github.com/golang/protobuf/ptypes/duration";
option java_package = "com.google.protobuf";
option java_outer_classname = "DurationProto";
option java_multiple_files = true;
option objc_class_prefix = "GPB";
// A Duration represents a signed, fixed-length span of time represented
// as a count of seconds and fractions of seconds at nanosecond
// resolution. It is independent of any calendar and concepts like "day"
// or "month". It is related to Timestamp in that the difference between
// two Timestamp values is a Duration and it can be added or subtracted
// from a Timestamp. Range is approximately +-10,000 years.
//
// # Examples
//
// Example 1: Compute Duration from two Timestamps in pseudo code.
//
// Timestamp start = ...;
// Timestamp end = ...;
// Duration duration = ...;
//
// duration.seconds = end.seconds - start.seconds;
// duration.nanos = end.nanos - start.nanos;
//
// if (duration.seconds < 0 && duration.nanos > 0) {
// duration.seconds += 1;
// duration.nanos -= 1000000000;
// } else if (durations.seconds > 0 && duration.nanos < 0) {
// duration.seconds -= 1;
// duration.nanos += 1000000000;
// }
//
// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
//
// Timestamp start = ...;
// Duration duration = ...;
// Timestamp end = ...;
//
// end.seconds = start.seconds + duration.seconds;
// end.nanos = start.nanos + duration.nanos;
//
// if (end.nanos < 0) {
// end.seconds -= 1;
// end.nanos += 1000000000;
// } else if (end.nanos >= 1000000000) {
// end.seconds += 1;
// end.nanos -= 1000000000;
// }
//
// Example 3: Compute Duration from datetime.timedelta in Python.
//
// td = datetime.timedelta(days=3, minutes=10)
// duration = Duration()
// duration.FromTimedelta(td)
//
// # JSON Mapping
//
// In JSON format, the Duration type is encoded as a string rather than an
// object, where the string ends in the suffix "s" (indicating seconds) and
// is preceded by the number of seconds, with nanoseconds expressed as
// fractional seconds. For example, 3 seconds with 0 nanoseconds should be
// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
// be expressed in JSON format as "3.000000001s", and 3 seconds and 1
// microsecond should be expressed in JSON format as "3.000001s".
//
//
message Duration {
// Signed seconds of the span of time. Must be from -315,576,000,000
// to +315,576,000,000 inclusive. Note: these bounds are computed from:
// 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
int64 seconds = 1;
// Signed fractions of a second at nanosecond resolution of the span
// of time. Durations less than one second are represented with a 0
// `seconds` field and a positive or negative `nanos` field. For durations
// of one second or more, a non-zero value for the `nanos` field must be
// of the same sign as the `seconds` field. Must be from -999,999,999
// to +999,999,999 inclusive.
int32 nanos = 2;
}

View File

@@ -0,0 +1,121 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// 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.
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)
}
}
}
}

View File

@@ -0,0 +1,68 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: github.com/golang/protobuf/ptypes/empty/empty.proto
/*
Package empty is a generated protocol buffer package.
It is generated from these files:
github.com/golang/protobuf/ptypes/empty/empty.proto
It has these top-level messages:
Empty
*/
package empty
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import 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.ProtoPackageIsVersion2 // please upgrade the proto package
// A generic empty message that you can re-use to avoid defining duplicated
// empty messages in your APIs. A typical example is to use it as the request
// or the response type of an API method. For instance:
//
// service Foo {
// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
// }
//
// The JSON representation for `Empty` is empty JSON object `{}`.
type Empty struct {
}
func (m *Empty) Reset() { *m = Empty{} }
func (m *Empty) String() string { return proto.CompactTextString(m) }
func (*Empty) ProtoMessage() {}
func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (*Empty) XXX_WellKnownType() string { return "Empty" }
func init() {
proto.RegisterType((*Empty)(nil), "google.protobuf.Empty")
}
func init() {
proto.RegisterFile("github.com/golang/protobuf/ptypes/empty/empty.proto", fileDescriptor0)
}
var fileDescriptor0 = []byte{
// 147 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x32, 0x4e, 0xcf, 0x2c, 0xc9,
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28,
0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0x28, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x4f, 0xcd,
0x2d, 0x28, 0xa9, 0x84, 0x90, 0x7a, 0x60, 0x39, 0x21, 0xfe, 0xf4, 0xfc, 0xfc, 0xf4, 0x9c, 0x54,
0x3d, 0x98, 0x4a, 0x25, 0x76, 0x2e, 0x56, 0x57, 0x90, 0xbc, 0x53, 0x19, 0x97, 0x70, 0x72, 0x7e,
0xae, 0x1e, 0x9a, 0xbc, 0x13, 0x17, 0x58, 0x36, 0x00, 0xc4, 0x0d, 0x60, 0x8c, 0x52, 0x27, 0xd2,
0xce, 0x1f, 0x8c, 0x8c, 0x8b, 0x98, 0x98, 0xdd, 0x03, 0x9c, 0x56, 0x31, 0xc9, 0xb9, 0x43, 0x4c,
0x0c, 0x80, 0xaa, 0xd3, 0x0b, 0x4f, 0xcd, 0xc9, 0xf1, 0xce, 0xcb, 0x2f, 0xcf, 0x0b, 0x01, 0xa9,
0x4f, 0x62, 0x03, 0x1b, 0x60, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x6e, 0x8e, 0x0a, 0x06, 0xcf,
0x00, 0x00, 0x00,
}

View File

@@ -0,0 +1,52 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
syntax = "proto3";
package google.protobuf;
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option go_package = "github.com/golang/protobuf/ptypes/empty";
option java_package = "com.google.protobuf";
option java_outer_classname = "EmptyProto";
option java_multiple_files = true;
option objc_class_prefix = "GPB";
option cc_enable_arenas = true;
// A generic empty message that you can re-use to avoid defining duplicated
// empty messages in your APIs. A typical example is to use it as the request
// or the response type of an API method. For instance:
//
// service Foo {
// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
// }
//
// The JSON representation for `Empty` is empty JSON object `{}`.
message Empty {}

66
vendor/github.com/golang/protobuf/ptypes/regen.sh generated vendored Executable file
View File

@@ -0,0 +1,66 @@
#!/bin/bash -e
#
# This script fetches and rebuilds the "well-known types" protocol buffers.
# To run this you will need protoc and goprotobuf installed;
# see https://github.com/golang/protobuf for instructions.
# You also need Go and Git installed.
PKG=github.com/golang/protobuf/ptypes
UPSTREAM=https://github.com/google/protobuf
UPSTREAM_SUBDIR=src/google/protobuf
PROTO_FILES='
any.proto
duration.proto
empty.proto
struct.proto
timestamp.proto
wrappers.proto
'
function die() {
echo 1>&2 $*
exit 1
}
# Sanity check that the right tools are accessible.
for tool in go git protoc protoc-gen-go; do
q=$(which $tool) || die "didn't find $tool"
echo 1>&2 "$tool: $q"
done
tmpdir=$(mktemp -d -t regen-wkt.XXXXXX)
trap 'rm -rf $tmpdir' EXIT
echo -n 1>&2 "finding package dir... "
pkgdir=$(go list -f '{{.Dir}}' $PKG)
echo 1>&2 $pkgdir
base=$(echo $pkgdir | sed "s,/$PKG\$,,")
echo 1>&2 "base: $base"
cd $base
echo 1>&2 "fetching latest protos... "
git clone -q $UPSTREAM $tmpdir
# Pass 1: build mapping from upstream filename to our filename.
declare -A filename_map
for f in $(cd $PKG && find * -name '*.proto'); do
echo -n 1>&2 "looking for latest version of $f... "
up=$(cd $tmpdir/$UPSTREAM_SUBDIR && find * -name $(basename $f) | grep -v /testdata/)
echo 1>&2 $up
if [ $(echo $up | wc -w) != "1" ]; then
die "not exactly one match"
fi
filename_map[$up]=$f
done
# Pass 2: copy files
for up in "${!filename_map[@]}"; do
f=${filename_map[$up]}
shortname=$(basename $f | sed 's,\.proto$,,')
cp $tmpdir/$UPSTREAM_SUBDIR/$up $PKG/$f
done
# Run protoc once per package.
for dir in $(find $PKG -name '*.proto' | xargs dirname | sort | uniq); do
echo 1>&2 "* $dir"
protoc --go_out=. $dir/*.proto
done
echo 1>&2 "All OK"

View File

@@ -0,0 +1,382 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: github.com/golang/protobuf/ptypes/struct/struct.proto
/*
Package structpb is a generated protocol buffer package.
It is generated from these files:
github.com/golang/protobuf/ptypes/struct/struct.proto
It has these top-level messages:
Struct
Value
ListValue
*/
package structpb
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import 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.ProtoPackageIsVersion2 // please upgrade the proto package
// `NullValue` is a singleton enumeration to represent the null value for the
// `Value` type union.
//
// The JSON representation for `NullValue` is JSON `null`.
type NullValue int32
const (
// Null value.
NullValue_NULL_VALUE NullValue = 0
)
var NullValue_name = map[int32]string{
0: "NULL_VALUE",
}
var NullValue_value = map[string]int32{
"NULL_VALUE": 0,
}
func (x NullValue) String() string {
return proto.EnumName(NullValue_name, int32(x))
}
func (NullValue) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (NullValue) XXX_WellKnownType() string { return "NullValue" }
// `Struct` represents a structured data value, consisting of fields
// which map to dynamically typed values. In some languages, `Struct`
// might be supported by a native representation. For example, in
// scripting languages like JS a struct is represented as an
// object. The details of that representation are described together
// with the proto support for the language.
//
// The JSON representation for `Struct` is JSON object.
type Struct struct {
// Unordered map of dynamically typed values.
Fields map[string]*Value `protobuf:"bytes,1,rep,name=fields" json:"fields,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
}
func (m *Struct) Reset() { *m = Struct{} }
func (m *Struct) String() string { return proto.CompactTextString(m) }
func (*Struct) ProtoMessage() {}
func (*Struct) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (*Struct) XXX_WellKnownType() string { return "Struct" }
func (m *Struct) GetFields() map[string]*Value {
if m != nil {
return m.Fields
}
return nil
}
// `Value` represents a dynamically typed value which can be either
// null, a number, a string, a boolean, a recursive struct value, or a
// list of values. A producer of value is expected to set one of that
// variants, absence of any variant indicates an error.
//
// The JSON representation for `Value` is JSON value.
type Value struct {
// The kind of value.
//
// Types that are valid to be assigned to Kind:
// *Value_NullValue
// *Value_NumberValue
// *Value_StringValue
// *Value_BoolValue
// *Value_StructValue
// *Value_ListValue
Kind isValue_Kind `protobuf_oneof:"kind"`
}
func (m *Value) Reset() { *m = Value{} }
func (m *Value) String() string { return proto.CompactTextString(m) }
func (*Value) ProtoMessage() {}
func (*Value) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (*Value) XXX_WellKnownType() string { return "Value" }
type isValue_Kind interface {
isValue_Kind()
}
type Value_NullValue struct {
NullValue NullValue `protobuf:"varint,1,opt,name=null_value,json=nullValue,enum=google.protobuf.NullValue,oneof"`
}
type Value_NumberValue struct {
NumberValue float64 `protobuf:"fixed64,2,opt,name=number_value,json=numberValue,oneof"`
}
type Value_StringValue struct {
StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,oneof"`
}
type Value_BoolValue struct {
BoolValue bool `protobuf:"varint,4,opt,name=bool_value,json=boolValue,oneof"`
}
type Value_StructValue struct {
StructValue *Struct `protobuf:"bytes,5,opt,name=struct_value,json=structValue,oneof"`
}
type Value_ListValue struct {
ListValue *ListValue `protobuf:"bytes,6,opt,name=list_value,json=listValue,oneof"`
}
func (*Value_NullValue) isValue_Kind() {}
func (*Value_NumberValue) isValue_Kind() {}
func (*Value_StringValue) isValue_Kind() {}
func (*Value_BoolValue) isValue_Kind() {}
func (*Value_StructValue) isValue_Kind() {}
func (*Value_ListValue) isValue_Kind() {}
func (m *Value) GetKind() isValue_Kind {
if m != nil {
return m.Kind
}
return nil
}
func (m *Value) GetNullValue() NullValue {
if x, ok := m.GetKind().(*Value_NullValue); ok {
return x.NullValue
}
return NullValue_NULL_VALUE
}
func (m *Value) GetNumberValue() float64 {
if x, ok := m.GetKind().(*Value_NumberValue); ok {
return x.NumberValue
}
return 0
}
func (m *Value) GetStringValue() string {
if x, ok := m.GetKind().(*Value_StringValue); ok {
return x.StringValue
}
return ""
}
func (m *Value) GetBoolValue() bool {
if x, ok := m.GetKind().(*Value_BoolValue); ok {
return x.BoolValue
}
return false
}
func (m *Value) GetStructValue() *Struct {
if x, ok := m.GetKind().(*Value_StructValue); ok {
return x.StructValue
}
return nil
}
func (m *Value) GetListValue() *ListValue {
if x, ok := m.GetKind().(*Value_ListValue); ok {
return x.ListValue
}
return nil
}
// XXX_OneofFuncs is for the internal use of the proto package.
func (*Value) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
return _Value_OneofMarshaler, _Value_OneofUnmarshaler, _Value_OneofSizer, []interface{}{
(*Value_NullValue)(nil),
(*Value_NumberValue)(nil),
(*Value_StringValue)(nil),
(*Value_BoolValue)(nil),
(*Value_StructValue)(nil),
(*Value_ListValue)(nil),
}
}
func _Value_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
m := msg.(*Value)
// kind
switch x := m.Kind.(type) {
case *Value_NullValue:
b.EncodeVarint(1<<3 | proto.WireVarint)
b.EncodeVarint(uint64(x.NullValue))
case *Value_NumberValue:
b.EncodeVarint(2<<3 | proto.WireFixed64)
b.EncodeFixed64(math.Float64bits(x.NumberValue))
case *Value_StringValue:
b.EncodeVarint(3<<3 | proto.WireBytes)
b.EncodeStringBytes(x.StringValue)
case *Value_BoolValue:
t := uint64(0)
if x.BoolValue {
t = 1
}
b.EncodeVarint(4<<3 | proto.WireVarint)
b.EncodeVarint(t)
case *Value_StructValue:
b.EncodeVarint(5<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.StructValue); err != nil {
return err
}
case *Value_ListValue:
b.EncodeVarint(6<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.ListValue); err != nil {
return err
}
case nil:
default:
return fmt.Errorf("Value.Kind has unexpected type %T", x)
}
return nil
}
func _Value_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
m := msg.(*Value)
switch tag {
case 1: // kind.null_value
if wire != proto.WireVarint {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeVarint()
m.Kind = &Value_NullValue{NullValue(x)}
return true, err
case 2: // kind.number_value
if wire != proto.WireFixed64 {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeFixed64()
m.Kind = &Value_NumberValue{math.Float64frombits(x)}
return true, err
case 3: // kind.string_value
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeStringBytes()
m.Kind = &Value_StringValue{x}
return true, err
case 4: // kind.bool_value
if wire != proto.WireVarint {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeVarint()
m.Kind = &Value_BoolValue{x != 0}
return true, err
case 5: // kind.struct_value
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(Struct)
err := b.DecodeMessage(msg)
m.Kind = &Value_StructValue{msg}
return true, err
case 6: // kind.list_value
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(ListValue)
err := b.DecodeMessage(msg)
m.Kind = &Value_ListValue{msg}
return true, err
default:
return false, nil
}
}
func _Value_OneofSizer(msg proto.Message) (n int) {
m := msg.(*Value)
// kind
switch x := m.Kind.(type) {
case *Value_NullValue:
n += proto.SizeVarint(1<<3 | proto.WireVarint)
n += proto.SizeVarint(uint64(x.NullValue))
case *Value_NumberValue:
n += proto.SizeVarint(2<<3 | proto.WireFixed64)
n += 8
case *Value_StringValue:
n += proto.SizeVarint(3<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.StringValue)))
n += len(x.StringValue)
case *Value_BoolValue:
n += proto.SizeVarint(4<<3 | proto.WireVarint)
n += 1
case *Value_StructValue:
s := proto.Size(x.StructValue)
n += proto.SizeVarint(5<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case *Value_ListValue:
s := proto.Size(x.ListValue)
n += proto.SizeVarint(6<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case nil:
default:
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
}
return n
}
// `ListValue` is a wrapper around a repeated field of values.
//
// The JSON representation for `ListValue` is JSON array.
type ListValue struct {
// Repeated field of dynamically typed values.
Values []*Value `protobuf:"bytes,1,rep,name=values" json:"values,omitempty"`
}
func (m *ListValue) Reset() { *m = ListValue{} }
func (m *ListValue) String() string { return proto.CompactTextString(m) }
func (*ListValue) ProtoMessage() {}
func (*ListValue) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (*ListValue) XXX_WellKnownType() string { return "ListValue" }
func (m *ListValue) GetValues() []*Value {
if m != nil {
return m.Values
}
return nil
}
func init() {
proto.RegisterType((*Struct)(nil), "google.protobuf.Struct")
proto.RegisterType((*Value)(nil), "google.protobuf.Value")
proto.RegisterType((*ListValue)(nil), "google.protobuf.ListValue")
proto.RegisterEnum("google.protobuf.NullValue", NullValue_name, NullValue_value)
}
func init() {
proto.RegisterFile("github.com/golang/protobuf/ptypes/struct/struct.proto", fileDescriptor0)
}
var fileDescriptor0 = []byte{
// 417 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x41, 0x8b, 0xd3, 0x40,
0x14, 0x80, 0x3b, 0xc9, 0x36, 0x98, 0x17, 0x59, 0x97, 0x11, 0xb4, 0xac, 0xa0, 0xa1, 0x7b, 0x09,
0x22, 0x09, 0x56, 0x04, 0x31, 0x5e, 0x0c, 0xac, 0xbb, 0x60, 0x58, 0x62, 0x74, 0x57, 0xf0, 0x52,
0x9a, 0x34, 0x8d, 0xa1, 0xd3, 0x99, 0x90, 0xcc, 0x28, 0x3d, 0xfa, 0x2f, 0x3c, 0x7b, 0xf4, 0xe8,
0xaf, 0xf3, 0x28, 0x33, 0x93, 0x44, 0x69, 0x29, 0x78, 0x9a, 0xbe, 0x37, 0xdf, 0xfb, 0xe6, 0xbd,
0xd7, 0xc0, 0xf3, 0xb2, 0xe2, 0x9f, 0x45, 0xe6, 0xe7, 0x6c, 0x13, 0x94, 0x8c, 0x2c, 0x68, 0x19,
0xd4, 0x0d, 0xe3, 0x2c, 0x13, 0xab, 0xa0, 0xe6, 0xdb, 0xba, 0x68, 0x83, 0x96, 0x37, 0x22, 0xe7,
0xdd, 0xe1, 0xab, 0x5b, 0x7c, 0xa7, 0x64, 0xac, 0x24, 0x85, 0xdf, 0xb3, 0xd3, 0xef, 0x08, 0xac,
0xf7, 0x8a, 0xc0, 0x21, 0x58, 0xab, 0xaa, 0x20, 0xcb, 0x76, 0x82, 0x5c, 0xd3, 0x73, 0x66, 0x67,
0xfe, 0x0e, 0xec, 0x6b, 0xd0, 0x7f, 0xa3, 0xa8, 0x73, 0xca, 0x9b, 0x6d, 0xda, 0x95, 0x9c, 0xbe,
0x03, 0xe7, 0x9f, 0x34, 0x3e, 0x01, 0x73, 0x5d, 0x6c, 0x27, 0xc8, 0x45, 0x9e, 0x9d, 0xca, 0x9f,
0xf8, 0x09, 0x8c, 0xbf, 0x2c, 0x88, 0x28, 0x26, 0x86, 0x8b, 0x3c, 0x67, 0x76, 0x6f, 0x4f, 0x7e,
0x23, 0x6f, 0x53, 0x0d, 0xbd, 0x34, 0x5e, 0xa0, 0xe9, 0x2f, 0x03, 0xc6, 0x2a, 0x89, 0x43, 0x00,
0x2a, 0x08, 0x99, 0x6b, 0x81, 0x94, 0x1e, 0xcf, 0x4e, 0xf7, 0x04, 0x57, 0x82, 0x10, 0xc5, 0x5f,
0x8e, 0x52, 0x9b, 0xf6, 0x01, 0x3e, 0x83, 0xdb, 0x54, 0x6c, 0xb2, 0xa2, 0x99, 0xff, 0x7d, 0x1f,
0x5d, 0x8e, 0x52, 0x47, 0x67, 0x07, 0xa8, 0xe5, 0x4d, 0x45, 0xcb, 0x0e, 0x32, 0x65, 0xe3, 0x12,
0xd2, 0x59, 0x0d, 0x3d, 0x02, 0xc8, 0x18, 0xeb, 0xdb, 0x38, 0x72, 0x91, 0x77, 0x4b, 0x3e, 0x25,
0x73, 0x1a, 0x78, 0xa5, 0x2c, 0x22, 0xe7, 0x1d, 0x32, 0x56, 0xa3, 0xde, 0x3f, 0xb0, 0xc7, 0x4e,
0x2f, 0x72, 0x3e, 0x4c, 0x49, 0xaa, 0xb6, 0xaf, 0xb5, 0x54, 0xed, 0xfe, 0x94, 0x71, 0xd5, 0xf2,
0x61, 0x4a, 0xd2, 0x07, 0x91, 0x05, 0x47, 0xeb, 0x8a, 0x2e, 0xa7, 0x21, 0xd8, 0x03, 0x81, 0x7d,
0xb0, 0x94, 0xac, 0xff, 0x47, 0x0f, 0x2d, 0xbd, 0xa3, 0x1e, 0x3f, 0x00, 0x7b, 0x58, 0x22, 0x3e,
0x06, 0xb8, 0xba, 0x8e, 0xe3, 0xf9, 0xcd, 0xeb, 0xf8, 0xfa, 0xfc, 0x64, 0x14, 0x7d, 0x43, 0x70,
0x37, 0x67, 0x9b, 0x5d, 0x45, 0xe4, 0xe8, 0x69, 0x12, 0x19, 0x27, 0xe8, 0xd3, 0xd3, 0xff, 0xfd,
0x30, 0x43, 0x7d, 0xd4, 0xd9, 0x6f, 0x84, 0x7e, 0x18, 0xe6, 0x45, 0x12, 0xfd, 0x34, 0x1e, 0x5e,
0x68, 0x79, 0xd2, 0xf7, 0xf7, 0xb1, 0x20, 0xe4, 0x2d, 0x65, 0x5f, 0xe9, 0x07, 0x59, 0x99, 0x59,
0x4a, 0xf5, 0xec, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9b, 0x6e, 0x5d, 0x3c, 0xfe, 0x02, 0x00,
0x00,
}

View File

@@ -0,0 +1,96 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
syntax = "proto3";
package google.protobuf;
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option cc_enable_arenas = true;
option go_package = "github.com/golang/protobuf/ptypes/struct;structpb";
option java_package = "com.google.protobuf";
option java_outer_classname = "StructProto";
option java_multiple_files = true;
option objc_class_prefix = "GPB";
// `Struct` represents a structured data value, consisting of fields
// which map to dynamically typed values. In some languages, `Struct`
// might be supported by a native representation. For example, in
// scripting languages like JS a struct is represented as an
// object. The details of that representation are described together
// with the proto support for the language.
//
// The JSON representation for `Struct` is JSON object.
message Struct {
// Unordered map of dynamically typed values.
map<string, Value> fields = 1;
}
// `Value` represents a dynamically typed value which can be either
// null, a number, a string, a boolean, a recursive struct value, or a
// list of values. A producer of value is expected to set one of that
// variants, absence of any variant indicates an error.
//
// The JSON representation for `Value` is JSON value.
message Value {
// The kind of value.
oneof kind {
// Represents a null value.
NullValue null_value = 1;
// Represents a double value.
double number_value = 2;
// Represents a string value.
string string_value = 3;
// Represents a boolean value.
bool bool_value = 4;
// Represents a structured value.
Struct struct_value = 5;
// Represents a repeated `Value`.
ListValue list_value = 6;
}
}
// `NullValue` is a singleton enumeration to represent the null value for the
// `Value` type union.
//
// The JSON representation for `NullValue` is JSON `null`.
enum NullValue {
// Null value.
NULL_VALUE = 0;
}
// `ListValue` is a wrapper around a repeated field of values.
//
// The JSON representation for `ListValue` is JSON array.
message ListValue {
// Repeated field of dynamically typed values.
repeated Value values = 1;
}

134
vendor/github.com/golang/protobuf/ptypes/timestamp.go generated vendored Normal file
View File

@@ -0,0 +1,134 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// 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.
package ptypes
// This file implements operations on google.protobuf.Timestamp.
import (
"errors"
"fmt"
"time"
tspb "github.com/golang/protobuf/ptypes/timestamp"
)
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
)
// 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 *tspb.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
}
// Timestamp converts a google.protobuf.Timestamp proto 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.
func Timestamp(ts *tspb.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.
func TimestampNow() *tspb.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.
func TimestampProto(t time.Time) (*tspb.Timestamp, error) {
seconds := t.Unix()
nanos := int32(t.Sub(time.Unix(seconds, 0)))
ts := &tspb.Timestamp{
Seconds: seconds,
Nanos: nanos,
}
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.
func TimestampString(ts *tspb.Timestamp) string {
t, err := Timestamp(ts)
if err != nil {
return fmt.Sprintf("(%v)", err)
}
return t.Format(time.RFC3339Nano)
}

View File

@@ -0,0 +1,162 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: github.com/golang/protobuf/ptypes/timestamp/timestamp.proto
/*
Package timestamp is a generated protocol buffer package.
It is generated from these files:
github.com/golang/protobuf/ptypes/timestamp/timestamp.proto
It has these top-level messages:
Timestamp
*/
package timestamp
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import 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.ProtoPackageIsVersion2 // please upgrade the proto package
// A Timestamp represents a point in time independent of any time zone
// or calendar, represented as seconds and fractions of seconds at
// nanosecond resolution in UTC Epoch time. It is encoded using the
// Proleptic Gregorian Calendar which extends the Gregorian calendar
// backwards to year one. It is encoded assuming all minutes are 60
// seconds long, i.e. leap seconds are "smeared" so that no leap second
// table is needed for interpretation. Range is from
// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
// By restricting to that range, we ensure that we can convert to
// and from RFC 3339 date strings.
// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
//
// # Examples
//
// Example 1: Compute Timestamp from POSIX `time()`.
//
// Timestamp timestamp;
// timestamp.set_seconds(time(NULL));
// timestamp.set_nanos(0);
//
// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
//
// struct timeval tv;
// gettimeofday(&tv, NULL);
//
// Timestamp timestamp;
// timestamp.set_seconds(tv.tv_sec);
// timestamp.set_nanos(tv.tv_usec * 1000);
//
// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
//
// FILETIME ft;
// GetSystemTimeAsFileTime(&ft);
// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
//
// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
// Timestamp timestamp;
// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
//
// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
//
// long millis = System.currentTimeMillis();
//
// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
// .setNanos((int) ((millis % 1000) * 1000000)).build();
//
//
// Example 5: Compute Timestamp from current time in Python.
//
// timestamp = Timestamp()
// timestamp.GetCurrentTime()
//
// # JSON Mapping
//
// In JSON format, the Timestamp type is encoded as a string in the
// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
// where {year} is always expressed using four digits while {month}, {day},
// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
// is required, though only UTC (as indicated by "Z") is presently supported.
//
// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
// 01:30 UTC on January 15, 2017.
//
// In JavaScript, one can convert a Date object to this format using the
// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString]
// method. In Python, a standard `datetime.datetime` object can be converted
// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime)
// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one
// can use the Joda Time's [`ISODateTimeFormat.dateTime()`](
// http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime())
// to obtain a formatter capable of generating timestamps in this format.
//
//
type Timestamp struct {
// Represents seconds of UTC time since Unix epoch
// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
// 9999-12-31T23:59:59Z inclusive.
Seconds int64 `protobuf:"varint,1,opt,name=seconds" json:"seconds,omitempty"`
// Non-negative fractions of a second at nanosecond resolution. Negative
// second values with fractions must still have non-negative nanos values
// that count forward in time. Must be from 0 to 999,999,999
// inclusive.
Nanos int32 `protobuf:"varint,2,opt,name=nanos" json:"nanos,omitempty"`
}
func (m *Timestamp) Reset() { *m = Timestamp{} }
func (m *Timestamp) String() string { return proto.CompactTextString(m) }
func (*Timestamp) ProtoMessage() {}
func (*Timestamp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (*Timestamp) XXX_WellKnownType() string { return "Timestamp" }
func (m *Timestamp) GetSeconds() int64 {
if m != nil {
return m.Seconds
}
return 0
}
func (m *Timestamp) GetNanos() int32 {
if m != nil {
return m.Nanos
}
return 0
}
func init() {
proto.RegisterType((*Timestamp)(nil), "google.protobuf.Timestamp")
}
func init() {
proto.RegisterFile("github.com/golang/protobuf/ptypes/timestamp/timestamp.proto", fileDescriptor0)
}
var fileDescriptor0 = []byte{
// 190 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xb2, 0x4e, 0xcf, 0x2c, 0xc9,
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28,
0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0x28, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x2f, 0xc9,
0xcc, 0x4d, 0x2d, 0x2e, 0x49, 0xcc, 0x2d, 0x40, 0xb0, 0xf4, 0xc0, 0x6a, 0x84, 0xf8, 0xd3, 0xf3,
0xf3, 0xd3, 0x73, 0x52, 0xf5, 0x60, 0x3a, 0x94, 0xac, 0xb9, 0x38, 0x43, 0x60, 0x6a, 0x84, 0x24,
0xb8, 0xd8, 0x8b, 0x53, 0x93, 0xf3, 0xf3, 0x52, 0x8a, 0x25, 0x18, 0x15, 0x18, 0x35, 0x98, 0x83,
0x60, 0x5c, 0x21, 0x11, 0x2e, 0xd6, 0xbc, 0xc4, 0xbc, 0xfc, 0x62, 0x09, 0x26, 0x05, 0x46, 0x0d,
0xd6, 0x20, 0x08, 0xc7, 0xa9, 0x8e, 0x4b, 0x38, 0x39, 0x3f, 0x57, 0x0f, 0xcd, 0x4c, 0x27, 0x3e,
0xb8, 0x89, 0x01, 0x20, 0xa1, 0x00, 0xc6, 0x28, 0x6d, 0x12, 0xdc, 0xfc, 0x83, 0x91, 0x71, 0x11,
0x13, 0xb3, 0x7b, 0x80, 0xd3, 0x2a, 0x26, 0x39, 0x77, 0x88, 0xc9, 0x01, 0x50, 0xb5, 0x7a, 0xe1,
0xa9, 0x39, 0x39, 0xde, 0x79, 0xf9, 0xe5, 0x79, 0x21, 0x20, 0x3d, 0x49, 0x6c, 0x60, 0x43, 0x8c,
0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x6b, 0x59, 0x0a, 0x4d, 0x13, 0x01, 0x00, 0x00,
}

View File

@@ -0,0 +1,133 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
syntax = "proto3";
package google.protobuf;
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option cc_enable_arenas = true;
option go_package = "github.com/golang/protobuf/ptypes/timestamp";
option java_package = "com.google.protobuf";
option java_outer_classname = "TimestampProto";
option java_multiple_files = true;
option objc_class_prefix = "GPB";
// A Timestamp represents a point in time independent of any time zone
// or calendar, represented as seconds and fractions of seconds at
// nanosecond resolution in UTC Epoch time. It is encoded using the
// Proleptic Gregorian Calendar which extends the Gregorian calendar
// backwards to year one. It is encoded assuming all minutes are 60
// seconds long, i.e. leap seconds are "smeared" so that no leap second
// table is needed for interpretation. Range is from
// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
// By restricting to that range, we ensure that we can convert to
// and from RFC 3339 date strings.
// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
//
// # Examples
//
// Example 1: Compute Timestamp from POSIX `time()`.
//
// Timestamp timestamp;
// timestamp.set_seconds(time(NULL));
// timestamp.set_nanos(0);
//
// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
//
// struct timeval tv;
// gettimeofday(&tv, NULL);
//
// Timestamp timestamp;
// timestamp.set_seconds(tv.tv_sec);
// timestamp.set_nanos(tv.tv_usec * 1000);
//
// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
//
// FILETIME ft;
// GetSystemTimeAsFileTime(&ft);
// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
//
// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
// Timestamp timestamp;
// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
//
// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
//
// long millis = System.currentTimeMillis();
//
// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
// .setNanos((int) ((millis % 1000) * 1000000)).build();
//
//
// Example 5: Compute Timestamp from current time in Python.
//
// timestamp = Timestamp()
// timestamp.GetCurrentTime()
//
// # JSON Mapping
//
// In JSON format, the Timestamp type is encoded as a string in the
// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
// where {year} is always expressed using four digits while {month}, {day},
// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
// is required, though only UTC (as indicated by "Z") is presently supported.
//
// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
// 01:30 UTC on January 15, 2017.
//
// In JavaScript, one can convert a Date object to this format using the
// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString]
// method. In Python, a standard `datetime.datetime` object can be converted
// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime)
// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one
// can use the Joda Time's [`ISODateTimeFormat.dateTime()`](
// http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime())
// to obtain a formatter capable of generating timestamps in this format.
//
//
message Timestamp {
// Represents seconds of UTC time since Unix epoch
// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
// 9999-12-31T23:59:59Z inclusive.
int64 seconds = 1;
// Non-negative fractions of a second at nanosecond resolution. Negative
// second values with fractions must still have non-negative nanos values
// that count forward in time. Must be from 0 to 999,999,999
// inclusive.
int32 nanos = 2;
}

View File

@@ -0,0 +1,153 @@
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// 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.
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"},
{&tspb.Timestamp{Seconds: minValidSeconds - 1, Nanos: 0}, "(timestamp: seconds:-62135596801 before 0001-01-01)"},
} {
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)
}
}

View File

@@ -0,0 +1,262 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: github.com/golang/protobuf/ptypes/wrappers/wrappers.proto
/*
Package wrappers is a generated protocol buffer package.
It is generated from these files:
github.com/golang/protobuf/ptypes/wrappers/wrappers.proto
It has these top-level messages:
DoubleValue
FloatValue
Int64Value
UInt64Value
Int32Value
UInt32Value
BoolValue
StringValue
BytesValue
*/
package wrappers
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import 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.ProtoPackageIsVersion2 // please upgrade the proto package
// Wrapper message for `double`.
//
// The JSON representation for `DoubleValue` is JSON number.
type DoubleValue struct {
// The double value.
Value float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"`
}
func (m *DoubleValue) Reset() { *m = DoubleValue{} }
func (m *DoubleValue) String() string { return proto.CompactTextString(m) }
func (*DoubleValue) ProtoMessage() {}
func (*DoubleValue) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (*DoubleValue) XXX_WellKnownType() string { return "DoubleValue" }
func (m *DoubleValue) GetValue() float64 {
if m != nil {
return m.Value
}
return 0
}
// Wrapper message for `float`.
//
// The JSON representation for `FloatValue` is JSON number.
type FloatValue struct {
// The float value.
Value float32 `protobuf:"fixed32,1,opt,name=value" json:"value,omitempty"`
}
func (m *FloatValue) Reset() { *m = FloatValue{} }
func (m *FloatValue) String() string { return proto.CompactTextString(m) }
func (*FloatValue) ProtoMessage() {}
func (*FloatValue) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (*FloatValue) XXX_WellKnownType() string { return "FloatValue" }
func (m *FloatValue) GetValue() float32 {
if m != nil {
return m.Value
}
return 0
}
// Wrapper message for `int64`.
//
// The JSON representation for `Int64Value` is JSON string.
type Int64Value struct {
// The int64 value.
Value int64 `protobuf:"varint,1,opt,name=value" json:"value,omitempty"`
}
func (m *Int64Value) Reset() { *m = Int64Value{} }
func (m *Int64Value) String() string { return proto.CompactTextString(m) }
func (*Int64Value) ProtoMessage() {}
func (*Int64Value) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (*Int64Value) XXX_WellKnownType() string { return "Int64Value" }
func (m *Int64Value) GetValue() int64 {
if m != nil {
return m.Value
}
return 0
}
// Wrapper message for `uint64`.
//
// The JSON representation for `UInt64Value` is JSON string.
type UInt64Value struct {
// The uint64 value.
Value uint64 `protobuf:"varint,1,opt,name=value" json:"value,omitempty"`
}
func (m *UInt64Value) Reset() { *m = UInt64Value{} }
func (m *UInt64Value) String() string { return proto.CompactTextString(m) }
func (*UInt64Value) ProtoMessage() {}
func (*UInt64Value) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (*UInt64Value) XXX_WellKnownType() string { return "UInt64Value" }
func (m *UInt64Value) GetValue() uint64 {
if m != nil {
return m.Value
}
return 0
}
// Wrapper message for `int32`.
//
// The JSON representation for `Int32Value` is JSON number.
type Int32Value struct {
// The int32 value.
Value int32 `protobuf:"varint,1,opt,name=value" json:"value,omitempty"`
}
func (m *Int32Value) Reset() { *m = Int32Value{} }
func (m *Int32Value) String() string { return proto.CompactTextString(m) }
func (*Int32Value) ProtoMessage() {}
func (*Int32Value) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (*Int32Value) XXX_WellKnownType() string { return "Int32Value" }
func (m *Int32Value) GetValue() int32 {
if m != nil {
return m.Value
}
return 0
}
// Wrapper message for `uint32`.
//
// The JSON representation for `UInt32Value` is JSON number.
type UInt32Value struct {
// The uint32 value.
Value uint32 `protobuf:"varint,1,opt,name=value" json:"value,omitempty"`
}
func (m *UInt32Value) Reset() { *m = UInt32Value{} }
func (m *UInt32Value) String() string { return proto.CompactTextString(m) }
func (*UInt32Value) ProtoMessage() {}
func (*UInt32Value) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
func (*UInt32Value) XXX_WellKnownType() string { return "UInt32Value" }
func (m *UInt32Value) GetValue() uint32 {
if m != nil {
return m.Value
}
return 0
}
// Wrapper message for `bool`.
//
// The JSON representation for `BoolValue` is JSON `true` and `false`.
type BoolValue struct {
// The bool value.
Value bool `protobuf:"varint,1,opt,name=value" json:"value,omitempty"`
}
func (m *BoolValue) Reset() { *m = BoolValue{} }
func (m *BoolValue) String() string { return proto.CompactTextString(m) }
func (*BoolValue) ProtoMessage() {}
func (*BoolValue) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
func (*BoolValue) XXX_WellKnownType() string { return "BoolValue" }
func (m *BoolValue) GetValue() bool {
if m != nil {
return m.Value
}
return false
}
// Wrapper message for `string`.
//
// The JSON representation for `StringValue` is JSON string.
type StringValue struct {
// The string value.
Value string `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"`
}
func (m *StringValue) Reset() { *m = StringValue{} }
func (m *StringValue) String() string { return proto.CompactTextString(m) }
func (*StringValue) ProtoMessage() {}
func (*StringValue) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
func (*StringValue) XXX_WellKnownType() string { return "StringValue" }
func (m *StringValue) GetValue() string {
if m != nil {
return m.Value
}
return ""
}
// Wrapper message for `bytes`.
//
// The JSON representation for `BytesValue` is JSON string.
type BytesValue struct {
// The bytes value.
Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
}
func (m *BytesValue) Reset() { *m = BytesValue{} }
func (m *BytesValue) String() string { return proto.CompactTextString(m) }
func (*BytesValue) ProtoMessage() {}
func (*BytesValue) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
func (*BytesValue) XXX_WellKnownType() string { return "BytesValue" }
func (m *BytesValue) GetValue() []byte {
if m != nil {
return m.Value
}
return nil
}
func init() {
proto.RegisterType((*DoubleValue)(nil), "google.protobuf.DoubleValue")
proto.RegisterType((*FloatValue)(nil), "google.protobuf.FloatValue")
proto.RegisterType((*Int64Value)(nil), "google.protobuf.Int64Value")
proto.RegisterType((*UInt64Value)(nil), "google.protobuf.UInt64Value")
proto.RegisterType((*Int32Value)(nil), "google.protobuf.Int32Value")
proto.RegisterType((*UInt32Value)(nil), "google.protobuf.UInt32Value")
proto.RegisterType((*BoolValue)(nil), "google.protobuf.BoolValue")
proto.RegisterType((*StringValue)(nil), "google.protobuf.StringValue")
proto.RegisterType((*BytesValue)(nil), "google.protobuf.BytesValue")
}
func init() {
proto.RegisterFile("github.com/golang/protobuf/ptypes/wrappers/wrappers.proto", fileDescriptor0)
}
var fileDescriptor0 = []byte{
// 257 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xb2, 0x4c, 0xcf, 0x2c, 0xc9,
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0xd7, 0x2f, 0x28,
0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0x28, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, 0x2f, 0x2f,
0x4a, 0x2c, 0x28, 0x48, 0x2d, 0x42, 0x30, 0xf4, 0xc0, 0x2a, 0x84, 0xf8, 0xd3, 0xf3, 0xf3, 0xd3,
0x73, 0x52, 0xf5, 0x60, 0xea, 0x95, 0x94, 0xb9, 0xb8, 0x5d, 0xf2, 0x4b, 0x93, 0x72, 0x52, 0xc3,
0x12, 0x73, 0x4a, 0x53, 0x85, 0x44, 0xb8, 0x58, 0xcb, 0x40, 0x0c, 0x09, 0x46, 0x05, 0x46, 0x0d,
0xc6, 0x20, 0x08, 0x47, 0x49, 0x89, 0x8b, 0xcb, 0x2d, 0x27, 0x3f, 0xb1, 0x04, 0x8b, 0x1a, 0x26,
0x24, 0x35, 0x9e, 0x79, 0x25, 0x66, 0x26, 0x58, 0xd4, 0x30, 0xc3, 0xd4, 0x28, 0x73, 0x71, 0x87,
0xe2, 0x52, 0xc4, 0x82, 0x6a, 0x90, 0xb1, 0x11, 0x16, 0x35, 0xac, 0x68, 0x06, 0x61, 0x55, 0xc4,
0x0b, 0x53, 0xa4, 0xc8, 0xc5, 0xe9, 0x94, 0x9f, 0x9f, 0x83, 0x45, 0x09, 0x07, 0x92, 0x39, 0xc1,
0x25, 0x45, 0x99, 0x79, 0xe9, 0x58, 0x14, 0x71, 0x22, 0x39, 0xc8, 0xa9, 0xb2, 0x24, 0xb5, 0x18,
0x8b, 0x1a, 0x1e, 0xa8, 0x1a, 0xa7, 0x1a, 0x2e, 0xe1, 0xe4, 0xfc, 0x5c, 0x3d, 0xb4, 0xd0, 0x75,
0xe2, 0x0d, 0x87, 0x06, 0x7f, 0x00, 0x48, 0x24, 0x80, 0x31, 0x4a, 0x8b, 0xf8, 0xa8, 0xfb, 0xc1,
0xc8, 0xb8, 0x88, 0x89, 0xd9, 0x3d, 0xc0, 0x69, 0x15, 0x93, 0x9c, 0x3b, 0xc4, 0xdc, 0x00, 0xa8,
0x52, 0xbd, 0xf0, 0xd4, 0x9c, 0x1c, 0xef, 0xbc, 0xfc, 0xf2, 0xbc, 0x10, 0x90, 0x96, 0x24, 0x36,
0xb0, 0x19, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xee, 0x36, 0x8d, 0xd8, 0x19, 0x02, 0x00,
0x00,
}

View File

@@ -0,0 +1,118 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// 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.
// Wrappers for primitive (non-message) types. These types are useful
// for embedding primitives in the `google.protobuf.Any` type and for places
// where we need to distinguish between the absence of a primitive
// typed field and its default value.
syntax = "proto3";
package google.protobuf;
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option cc_enable_arenas = true;
option go_package = "github.com/golang/protobuf/ptypes/wrappers";
option java_package = "com.google.protobuf";
option java_outer_classname = "WrappersProto";
option java_multiple_files = true;
option objc_class_prefix = "GPB";
// Wrapper message for `double`.
//
// The JSON representation for `DoubleValue` is JSON number.
message DoubleValue {
// The double value.
double value = 1;
}
// Wrapper message for `float`.
//
// The JSON representation for `FloatValue` is JSON number.
message FloatValue {
// The float value.
float value = 1;
}
// Wrapper message for `int64`.
//
// The JSON representation for `Int64Value` is JSON string.
message Int64Value {
// The int64 value.
int64 value = 1;
}
// Wrapper message for `uint64`.
//
// The JSON representation for `UInt64Value` is JSON string.
message UInt64Value {
// The uint64 value.
uint64 value = 1;
}
// Wrapper message for `int32`.
//
// The JSON representation for `Int32Value` is JSON number.
message Int32Value {
// The int32 value.
int32 value = 1;
}
// Wrapper message for `uint32`.
//
// The JSON representation for `UInt32Value` is JSON number.
message UInt32Value {
// The uint32 value.
uint32 value = 1;
}
// Wrapper message for `bool`.
//
// The JSON representation for `BoolValue` is JSON `true` and `false`.
message BoolValue {
// The bool value.
bool value = 1;
}
// Wrapper message for `string`.
//
// The JSON representation for `StringValue` is JSON string.
message StringValue {
// The string value.
string value = 1;
}
// Wrapper message for `bytes`.
//
// The JSON representation for `BytesValue` is JSON string.
message BytesValue {
// The bytes value.
bytes value = 1;
}