Commit acd23e15 authored by Clayton Coleman's avatar Clayton Coleman

bump(github.com/gogo/protobuf):9dc510915846dd5a05607d3b5bf41f5ca5cce972

parent 38f926db
......@@ -427,9 +427,119 @@
"Rev": "c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f"
},
{
"ImportPath": "github.com/gogo/protobuf/gogoproto",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/defaultcheck",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/description",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/embedcheck",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/enumstringer",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/equal",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/face",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/gostring",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/grpc",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/marshalto",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/oneofcheck",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/populate",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/size",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/stringer",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/testgen",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/union",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/plugin/unmarshal",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/proto",
"Comment": "v0.1-55-g2093b57",
"Rev": "2093b57e5ca2ccbee4626814100bc1aada691b18"
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/descriptor",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/generator",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/plugin",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/sortkeys",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/gogo/protobuf/vanity",
"Comment": "v0.1-108-g9dc5109",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972"
},
{
"ImportPath": "github.com/golang/glog",
......
# Extensions for Protocol Buffers to create more go like structures.
#
# Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
# http://github.com/gogo/protobuf/gogoproto
#
# 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.
#
# 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 --gogo_out=Mgoogle/protobuf/descriptor.proto=github.com/gogo/protobuf/protoc-gen-gogo/descriptor:. --proto_path=../../../../:../protobuf/:. *.proto
restore:
cp gogo.pb.golden gogo.pb.go
preserve:
cp gogo.pb.go gogo.pb.golden
// Extensions for Protocol Buffers to create more go like structures.
//
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/protobuf/gogoproto
//
// 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.
//
// 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 gogoproto provides extensions for protocol buffers to achieve:
- fast marshalling and unmarshalling.
- peace of mind by optionally generating test and benchmark code.
- more canonical Go structures.
- less typing by optionally generating extra helper code.
- goprotobuf compatibility
More Canonical Go Structures
A lot of time working with a goprotobuf struct will lead you to a place where you create another struct that is easier to work with and then have a function to copy the values between the two structs.
You might also find that basic structs that started their life as part of an API need to be sent over the wire. With gob, you could just send it. With goprotobuf, you need to make a parallel struct.
Gogoprotobuf tries to fix these problems with the nullable, embed, customtype and customname field extensions.
- nullable, if false, a field is generated without a pointer (see warning below).
- embed, if true, the field is generated as an embedded field.
- customtype, It works with the Marshal and Unmarshal methods, to allow you to have your own types in your struct, but marshal to bytes. For example, custom.Uuid or custom.Fixed128
- customname (beta), Changes the generated fieldname. This is especially useful when generated methods conflict with fieldnames.
- casttype (beta), Changes the generated fieldtype. All generated code assumes that this type is castable to the protocol buffer field type. It does not work for structs or enums.
- castkey (beta), Changes the generated fieldtype for a map key. All generated code assumes that this type is castable to the protocol buffer field type. Only supported on maps.
- castvalue (beta), Changes the generated fieldtype for a map value. All generated code assumes that this type is castable to the protocol buffer field type. Only supported on maps.
Warning about nullable: According to the Protocol Buffer specification, you should be able to tell whether a field is set or unset. With the option nullable=false this feature is lost, since your non-nullable fields will always be set. It can be seen as a layer on top of Protocol Buffers, where before and after marshalling all non-nullable fields are set and they cannot be unset.
Let us look at:
github.com/gogo/protobuf/test/example/example.proto
for a quicker overview.
The following message:
package test;
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
message A {
optional string Description = 1 [(gogoproto.nullable) = false];
optional int64 Number = 2 [(gogoproto.nullable) = false];
optional bytes Id = 3 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uuid", (gogoproto.nullable) = false];
}
Will generate a go struct which looks a lot like this:
type A struct {
Description string
Number int64
Id github_com_gogo_protobuf_test_custom.Uuid
}
You will see there are no pointers, since all fields are non-nullable.
You will also see a custom type which marshals to a string.
Be warned it is your responsibility to test your custom types thoroughly.
You should think of every possible empty and nil case for your marshaling, unmarshaling and size methods.
Next we will embed the message A in message B.
message B {
optional A A = 1 [(gogoproto.nullable) = false, (gogoproto.embed) = true];
repeated bytes G = 2 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uint128", (gogoproto.nullable) = false];
}
See below that A is embedded in B.
type B struct {
A
G []github_com_gogo_protobuf_test_custom.Uint128
}
Also see the repeated custom type.
type Uint128 [2]uint64
Next we will create a custom name for one of our fields.
message C {
optional int64 size = 1 [(gogoproto.customname) = "MySize"];
}
See below that the field's name is MySize and not Size.
type C struct {
MySize *int64
}
The is useful when having a protocol buffer message with a field name which conflicts with a generated method.
As an example, having a field name size and using the sizer plugin to generate a Size method will cause a go compiler error.
Using customname you can fix this error without changing the field name.
This is typically useful when working with a protocol buffer that was designed before these methods and/or the go language were avialable.
Gogoprotobuf also has some more subtle changes, these could be changed back:
- the generated package name for imports do not have the extra /filename.pb,
but are actually the imports specified in the .proto file.
Gogoprotobuf also has lost some features which should be brought back with time:
- Marshalling and unmarshalling with reflect and without the unsafe package,
this requires work in pointer_reflect.go
Why does nullable break protocol buffer specifications:
The protocol buffer specification states, somewhere, that you should be able to tell whether a
field is set or unset. With the option nullable=false this feature is lost,
since your non-nullable fields will always be set. It can be seen as a layer on top of
protocol buffers, where before and after marshalling all non-nullable fields are set
and they cannot be unset.
Goprotobuf Compatibility:
Gogoprotobuf is compatible with Goprotobuf, because it is compatible with protocol buffers.
Gogoprotobuf generates the same code as goprotobuf if no extensions are used.
The enumprefix, getters and stringer extensions can be used to remove some of the unnecessary code generated by goprotobuf:
- gogoproto_import, if false, the generated code imports github.com/golang/protobuf/proto instead of github.com/gogo/protobuf/proto.
- goproto_enum_prefix, if false, generates the enum constant names without the messagetype prefix
- goproto_enum_stringer (experimental), if false, the enum is generated without the default string method, this is useful for rather using enum_stringer, or allowing you to write your own string method.
- goproto_getters, if false, the message is generated without get methods, this is useful when you would rather want to use face
- goproto_stringer, if false, the message is generated without the default string method, this is useful for rather using stringer, or allowing you to write your own string method.
- goproto_extensions_map (beta), if false, the extensions field is generated as type []byte instead of type map[int32]proto.Extension
- goproto_unrecognized (beta), if false, XXX_unrecognized field is not generated. This is useful in conjunction with gogoproto.nullable=false, to generate structures completely devoid of pointers and reduce GC pressure at the cost of losing information about unrecognized fields.
Less Typing and Peace of Mind is explained in their specific plugin folders godoc:
- github.com/gogo/protobuf/plugin/<extension_name>
If you do not use any of these extension the code that is generated
will be the same as if goprotobuf has generated it.
The most complete way to see examples is to look at
github.com/gogo/protobuf/test/thetest.proto
Gogoprototest is a seperate project,
because we want to keep gogoprotobuf independant of goprotobuf,
but we still want to test it thoroughly.
*/
package gogoproto
// Code generated by protoc-gen-go.
// source: gogo.proto
// DO NOT EDIT!
package gogoproto
import proto "github.com/gogo/protobuf/proto"
import json "encoding/json"
import math "math"
import google_protobuf "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
// Reference proto, json, and math imports to suppress error if they are not otherwise used.
var _ = proto.Marshal
var _ = &json.SyntaxError{}
var _ = math.Inf
var E_Nullable = &proto.ExtensionDesc{
ExtendedType: (*google_protobuf.FieldOptions)(nil),
ExtensionType: (*bool)(nil),
Field: 51235,
Name: "gogoproto.nullable",
Tag: "varint,51235,opt,name=nullable",
}
var E_Embed = &proto.ExtensionDesc{
ExtendedType: (*google_protobuf.FieldOptions)(nil),
ExtensionType: (*bool)(nil),
Field: 51236,
Name: "gogoproto.embed",
Tag: "varint,51236,opt,name=embed",
}
var E_Customtype = &proto.ExtensionDesc{
ExtendedType: (*google_protobuf.FieldOptions)(nil),
ExtensionType: (*string)(nil),
Field: 51237,
Name: "gogoproto.customtype",
Tag: "bytes,51237,opt,name=customtype",
}
func init() {
proto.RegisterExtension(E_Nullable)
proto.RegisterExtension(E_Embed)
proto.RegisterExtension(E_Customtype)
}
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/protobuf/gogoproto
//
// 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.
//
// 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 = "proto2";
package gogoproto;
import "google/protobuf/descriptor.proto";
option java_package = "com.google.protobuf";
option java_outer_classname = "GoGoProtos";
extend google.protobuf.EnumOptions {
optional bool goproto_enum_prefix = 62001;
optional bool goproto_enum_stringer = 62021;
optional bool enum_stringer = 62022;
}
extend google.protobuf.FileOptions {
optional bool goproto_getters_all = 63001;
optional bool goproto_enum_prefix_all = 63002;
optional bool goproto_stringer_all = 63003;
optional bool verbose_equal_all = 63004;
optional bool face_all = 63005;
optional bool gostring_all = 63006;
optional bool populate_all = 63007;
optional bool stringer_all = 63008;
optional bool onlyone_all = 63009;
optional bool equal_all = 63013;
optional bool description_all = 63014;
optional bool testgen_all = 63015;
optional bool benchgen_all = 63016;
optional bool marshaler_all = 63017;
optional bool unmarshaler_all = 63018;
optional bool sizer_all = 63020;
optional bool goproto_enum_stringer_all = 63021;
optional bool enum_stringer_all = 63022;
optional bool unsafe_marshaler_all = 63023;
optional bool unsafe_unmarshaler_all = 63024;
optional bool goproto_extensions_map_all = 63025;
optional bool goproto_unrecognized_all = 63026;
optional bool gogoproto_import = 63027;
}
extend google.protobuf.MessageOptions {
optional bool goproto_getters = 64001;
optional bool goproto_stringer = 64003;
optional bool verbose_equal = 64004;
optional bool face = 64005;
optional bool gostring = 64006;
optional bool populate = 64007;
optional bool stringer = 67008;
optional bool onlyone = 64009;
optional bool equal = 64013;
optional bool description = 64014;
optional bool testgen = 64015;
optional bool benchgen = 64016;
optional bool marshaler = 64017;
optional bool unmarshaler = 64018;
optional bool sizer = 64020;
optional bool unsafe_marshaler = 64023;
optional bool unsafe_unmarshaler = 64024;
optional bool goproto_extensions_map = 64025;
optional bool goproto_unrecognized = 64026;
}
extend google.protobuf.FieldOptions {
optional bool nullable = 65001;
optional bool embed = 65002;
optional string customtype = 65003;
optional string customname = 65004;
optional string jsontag = 65005;
optional string moretags = 65006;
optional string casttype = 65007;
optional string castkey = 65008;
optional string castvalue = 65009;
}
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/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.
//
// 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.
/*
The defaultcheck plugin is used to check whether nullable is not used incorrectly.
For instance:
An error is caused if a nullable field:
- has a default value,
- is an enum which does not start at zero,
- is used for an extension,
- is used for a native proto3 type,
- is used for a repeated native type.
An error is also caused if a field with a default value is used in a message:
- which is a face.
- without getters.
It is enabled by the following extensions:
- nullable
For incorrect usage of nullable with tests see:
github.com/gogo/protobuf/test/nullableconflict
*/
package defaultcheck
import (
"fmt"
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
"os"
)
type plugin struct {
*generator.Generator
}
func NewPlugin() *plugin {
return &plugin{}
}
func (p *plugin) Name() string {
return "defaultcheck"
}
func (p *plugin) Init(g *generator.Generator) {
p.Generator = g
}
func (p *plugin) Generate(file *generator.FileDescriptor) {
proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
for _, msg := range file.Messages() {
getters := gogoproto.HasGoGetters(file.FileDescriptorProto, msg.DescriptorProto)
face := gogoproto.IsFace(file.FileDescriptorProto, msg.DescriptorProto)
for _, field := range msg.GetField() {
if len(field.GetDefaultValue()) > 0 {
if !getters {
fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot have a default value and not have a getter method", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
os.Exit(1)
}
if face {
fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot have a default value be in a face", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
os.Exit(1)
}
}
if gogoproto.IsNullable(field) {
continue
}
if len(field.GetDefaultValue()) > 0 {
fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be non-nullable and have a default value", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
os.Exit(1)
}
if !field.IsMessage() && !gogoproto.IsCustomType(field) {
if field.IsRepeated() {
fmt.Fprintf(os.Stderr, "WARNING: field %v.%v is a repeated non-nullable native type, nullable=false has no effect\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
} else if proto3 {
fmt.Fprintf(os.Stderr, "ERROR: field %v.%v is a native type and in proto3 syntax with nullable=false there exists conflicting implementations when encoding zero values", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
os.Exit(1)
}
if field.IsBytes() {
fmt.Fprintf(os.Stderr, "WARNING: field %v.%v is a non-nullable bytes type, nullable=false has no effect\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
}
}
if !field.IsEnum() {
continue
}
enum := p.ObjectNamed(field.GetTypeName()).(*generator.EnumDescriptor)
if len(enum.Value) == 0 || enum.Value[0].GetNumber() != 0 {
fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be non-nullable and be an enum type %v which does not start with zero", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name), enum.GetName())
os.Exit(1)
}
}
}
for _, e := range file.GetExtension() {
if !gogoproto.IsNullable(e) {
fmt.Fprintf(os.Stderr, "ERROR: extended field %v cannot be nullable %v", generator.CamelCase(e.GetName()), generator.CamelCase(*e.Name))
os.Exit(1)
}
}
}
func (p *plugin) GenerateImports(*generator.FileDescriptor) {}
func init() {
generator.RegisterPlugin(NewPlugin())
}
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/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.
//
// 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.
/*
The description (experimental) plugin generates a Description method for each message.
The Description method returns a populated google_protobuf.FileDescriptorSet struct.
This contains the description of the files used to generate this message.
It is enabled by the following extensions:
- description
- description_all
The description plugin also generates a test given it is enabled using one of the following extensions:
- testgen
- testgen_all
Let us look at:
github.com/gogo/protobuf/test/example/example.proto
Btw all the output can be seen at:
github.com/gogo/protobuf/test/example/*
The following message:
message B {
option (gogoproto.description) = true;
optional A A = 1 [(gogoproto.nullable) = false, (gogoproto.embed) = true];
repeated bytes G = 2 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uint128", (gogoproto.nullable) = false];
}
given to the description plugin, will generate the following code:
func (this *B) Description() (desc *google_protobuf.FileDescriptorSet) {
return ExampleDescription()
}
and the following test code:
func TestDescription(t *testing9.T) {
ExampleDescription()
}
The hope is to use this struct in some way instead of reflect.
This package is subject to change, since a use has not been figured out yet.
*/
package description
import (
"fmt"
"github.com/gogo/protobuf/gogoproto"
descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
)
type plugin struct {
*generator.Generator
used bool
}
func NewPlugin() *plugin {
return &plugin{}
}
func (p *plugin) Name() string {
return "description"
}
func (p *plugin) Init(g *generator.Generator) {
p.Generator = g
}
func (p *plugin) Generate(file *generator.FileDescriptor) {
p.used = false
localName := generator.FileName(file)
for _, message := range file.Messages() {
if !gogoproto.HasDescription(file.FileDescriptorProto, message.DescriptorProto) {
continue
}
if message.DescriptorProto.GetOptions().GetMapEntry() {
continue
}
p.used = true
ccTypeName := generator.CamelCaseSlice(message.TypeName())
p.P(`func (this *`, ccTypeName, `) Description() (desc *descriptor.FileDescriptorSet) {`)
p.In()
p.P(`return `, localName, `Description()`)
p.Out()
p.P(`}`)
}
if p.used {
p.P(`func `, localName, `Description() (desc *descriptor.FileDescriptorSet) {`)
p.In()
//Don't generate SourceCodeInfo, since it will create too much code.
ss := make([]*descriptor.SourceCodeInfo, 0)
for _, f := range p.Generator.AllFiles().GetFile() {
ss = append(ss, f.SourceCodeInfo)
f.SourceCodeInfo = nil
}
s := fmt.Sprintf("%#v", p.Generator.AllFiles())
for i, f := range p.Generator.AllFiles().GetFile() {
f.SourceCodeInfo = ss[i]
}
p.P(`return `, s)
p.Out()
p.P(`}`)
}
}
func (this *plugin) GenerateImports(file *generator.FileDescriptor) {
if this.used {
this.P(`import "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"`)
}
}
func init() {
generator.RegisterPlugin(NewPlugin())
}
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/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.
//
// 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 description
import (
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/plugin/testgen"
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
)
type test struct {
*generator.Generator
}
func NewTest(g *generator.Generator) testgen.TestPlugin {
return &test{g}
}
func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
used := false
testingPkg := imports.NewImport("testing")
for _, message := range file.Messages() {
if !gogoproto.HasDescription(file.FileDescriptorProto, message.DescriptorProto) ||
!gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
continue
}
if message.DescriptorProto.GetOptions().GetMapEntry() {
continue
}
used = true
}
if used {
localName := generator.FileName(file)
p.P(`func Test`, localName, `Description(t *`, testingPkg.Use(), `.T) {`)
p.In()
p.P(localName, `Description()`)
p.Out()
p.P(`}`)
}
return used
}
func init() {
testgen.RegisterTestPlugin(NewTest)
}
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/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.
//
// 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.
/*
The embedcheck plugin is used to check whether embed is not used incorrectly.
For instance:
An embedded message has a generated string method, but the is a member of a message which does not.
This causes a warning.
An error is caused by a namespace conflict.
It is enabled by the following extensions:
- embed
- embed_all
For incorrect usage of embed with tests see:
github.com/gogo/protobuf/test/embedconflict
*/
package embedcheck
import (
"fmt"
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
"os"
)
type plugin struct {
*generator.Generator
}
func NewPlugin() *plugin {
return &plugin{}
}
func (p *plugin) Name() string {
return "embedcheck"
}
func (p *plugin) Init(g *generator.Generator) {
p.Generator = g
}
var overwriters []map[string]gogoproto.EnableFunc = []map[string]gogoproto.EnableFunc{
{
"stringer": gogoproto.IsStringer,
},
{
"gostring": gogoproto.HasGoString,
},
{
"equal": gogoproto.HasEqual,
},
{
"verboseequal": gogoproto.HasVerboseEqual,
},
{
"size": gogoproto.IsSizer,
},
{
"unmarshaler": gogoproto.IsUnmarshaler,
"unsafe_unmarshaler": gogoproto.IsUnsafeUnmarshaler,
},
{
"marshaler": gogoproto.IsMarshaler,
"unsafe_marshaler": gogoproto.IsUnsafeMarshaler,
},
}
func (p *plugin) Generate(file *generator.FileDescriptor) {
for _, msg := range file.Messages() {
for _, os := range overwriters {
possible := true
for _, overwriter := range os {
if overwriter(file.FileDescriptorProto, msg.DescriptorProto) {
possible = false
}
}
if possible {
p.checkOverwrite(msg, os)
}
}
p.checkNameSpace(msg)
for _, field := range msg.GetField() {
if gogoproto.IsEmbed(field) && gogoproto.IsCustomName(field) {
fmt.Fprintf(os.Stderr, "ERROR: field %v with custom name %v cannot be embedded", *field.Name, gogoproto.GetCustomName(field))
os.Exit(1)
}
}
p.checkRepeated(msg)
}
for _, e := range file.GetExtension() {
if gogoproto.IsEmbed(e) {
fmt.Fprintf(os.Stderr, "ERROR: extended field %v cannot be embedded", generator.CamelCase(*e.Name))
os.Exit(1)
}
}
}
func (p *plugin) checkNameSpace(message *generator.Descriptor) map[string]bool {
ccTypeName := generator.CamelCaseSlice(message.TypeName())
names := make(map[string]bool)
for _, field := range message.Field {
fieldname := generator.CamelCase(*field.Name)
if field.IsMessage() && gogoproto.IsEmbed(field) {
desc := p.ObjectNamed(field.GetTypeName())
moreNames := p.checkNameSpace(desc.(*generator.Descriptor))
for another := range moreNames {
if names[another] {
fmt.Fprintf(os.Stderr, "ERROR: duplicate embedded fieldname %v in type %v\n", fieldname, ccTypeName)
os.Exit(1)
}
names[another] = true
}
} else {
if names[fieldname] {
fmt.Fprintf(os.Stderr, "ERROR: duplicate embedded fieldname %v in type %v\n", fieldname, ccTypeName)
os.Exit(1)
}
names[fieldname] = true
}
}
return names
}
func (p *plugin) checkOverwrite(message *generator.Descriptor, enablers map[string]gogoproto.EnableFunc) {
ccTypeName := generator.CamelCaseSlice(message.TypeName())
names := []string{}
for name := range enablers {
names = append(names, name)
}
for _, field := range message.Field {
if field.IsMessage() && gogoproto.IsEmbed(field) {
fieldname := generator.CamelCase(*field.Name)
desc := p.ObjectNamed(field.GetTypeName())
msg := desc.(*generator.Descriptor)
for errStr, enabled := range enablers {
if enabled(msg.File(), msg.DescriptorProto) {
fmt.Fprintf(os.Stderr, "WARNING: found non-%v %v with embedded %v %v\n", names, ccTypeName, errStr, fieldname)
}
}
p.checkOverwrite(msg, enablers)
}
}
}
func (p *plugin) checkRepeated(message *generator.Descriptor) {
ccTypeName := generator.CamelCaseSlice(message.TypeName())
for _, field := range message.Field {
if !gogoproto.IsEmbed(field) {
continue
}
if field.IsBytes() {
fieldname := generator.CamelCase(*field.Name)
fmt.Fprintf(os.Stderr, "ERROR: found embedded bytes field %s in message %s\n", fieldname, ccTypeName)
os.Exit(1)
}
if !field.IsRepeated() {
continue
}
fieldname := generator.CamelCase(*field.Name)
fmt.Fprintf(os.Stderr, "ERROR: found repeated embedded field %s in message %s\n", fieldname, ccTypeName)
os.Exit(1)
}
}
func (p *plugin) GenerateImports(*generator.FileDescriptor) {}
func init() {
generator.RegisterPlugin(NewPlugin())
}
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/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.
//
// 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.
/*
The enumstringer (experimental) plugin generates a String method for each enum.
It is enabled by the following extensions:
- enum_stringer
- enum_stringer_all
This package is subject to change.
*/
package enumstringer
import (
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
)
type enumstringer struct {
*generator.Generator
generator.PluginImports
atleastOne bool
localName string
}
func NewEnumStringer() *enumstringer {
return &enumstringer{}
}
func (p *enumstringer) Name() string {
return "enumstringer"
}
func (p *enumstringer) Init(g *generator.Generator) {
p.Generator = g
}
func (p *enumstringer) Generate(file *generator.FileDescriptor) {
p.PluginImports = generator.NewPluginImports(p.Generator)
p.atleastOne = false
p.localName = generator.FileName(file)
strconvPkg := p.NewImport("strconv")
for _, enum := range file.Enums() {
if !gogoproto.IsEnumStringer(file.FileDescriptorProto, enum.EnumDescriptorProto) {
continue
}
if gogoproto.IsGoEnumStringer(file.FileDescriptorProto, enum.EnumDescriptorProto) {
panic("old enum string method needs to be disabled, please use gogoproto.old_enum_stringer or gogoproto.old_enum_string_all and set it to false")
}
p.atleastOne = true
ccTypeName := generator.CamelCaseSlice(enum.TypeName())
p.P("func (x ", ccTypeName, ") String() string {")
p.In()
p.P(`s, ok := `, ccTypeName, `_name[int32(x)]`)
p.P(`if ok {`)
p.In()
p.P(`return s`)
p.Out()
p.P(`}`)
p.P(`return `, strconvPkg.Use(), `.Itoa(int(x))`)
p.Out()
p.P(`}`)
}
if !p.atleastOne {
return
}
}
func init() {
generator.RegisterPlugin(NewEnumStringer())
}
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/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.
//
// 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 equal
import (
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/plugin/testgen"
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
)
type test struct {
*generator.Generator
}
func NewTest(g *generator.Generator) testgen.TestPlugin {
return &test{g}
}
func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
used := false
randPkg := imports.NewImport("math/rand")
timePkg := imports.NewImport("time")
testingPkg := imports.NewImport("testing")
protoPkg := imports.NewImport("github.com/gogo/protobuf/proto")
if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
protoPkg = imports.NewImport("github.com/golang/protobuf/proto")
}
for _, message := range file.Messages() {
ccTypeName := generator.CamelCaseSlice(message.TypeName())
if !gogoproto.HasVerboseEqual(file.FileDescriptorProto, message.DescriptorProto) {
continue
}
if message.DescriptorProto.GetOptions().GetMapEntry() {
continue
}
if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
used = true
p.P(`func Test`, ccTypeName, `VerboseEqual(t *`, testingPkg.Use(), `.T) {`)
p.In()
p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(`, timePkg.Use(), `.Now().UnixNano()))`)
p.P(`p := NewPopulated`, ccTypeName, `(popr, false)`)
p.P(`data, err := `, protoPkg.Use(), `.Marshal(p)`)
p.P(`if err != nil {`)
p.In()
p.P(`panic(err)`)
p.Out()
p.P(`}`)
p.P(`msg := &`, ccTypeName, `{}`)
p.P(`if err := `, protoPkg.Use(), `.Unmarshal(data, msg); err != nil {`)
p.In()
p.P(`panic(err)`)
p.Out()
p.P(`}`)
p.P(`if err := p.VerboseEqual(msg); err != nil {`)
p.In()
p.P(`t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err)`)
p.Out()
p.P(`}`)
p.Out()
p.P(`}`)
}
}
return used
}
func init() {
testgen.RegisterTestPlugin(NewTest)
}
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/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.
//
// 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.
/*
The face plugin generates a function will be generated which can convert a structure which satisfies an interface (face) to the specified structure.
This interface contains getters for each of the fields in the struct.
The specified struct is also generated with the getters.
This means that getters should be turned off so as not to conflict with face getters.
This allows it to satisfy its own face.
It is enabled by the following extensions:
- face
- face_all
Turn off getters by using the following extensions:
- getters
- getters_all
The face plugin also generates a test given it is enabled using one of the following extensions:
- testgen
- testgen_all
Let us look at:
github.com/gogo/protobuf/test/example/example.proto
Btw all the output can be seen at:
github.com/gogo/protobuf/test/example/*
The following message:
message A {
option (gogoproto.face) = true;
option (gogoproto.goproto_getters) = false;
optional string Description = 1 [(gogoproto.nullable) = false];
optional int64 Number = 2 [(gogoproto.nullable) = false];
optional bytes Id = 3 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uuid", (gogoproto.nullable) = false];
}
given to the face plugin, will generate the following code:
type AFace interface {
Proto() github_com_gogo_protobuf_proto.Message
GetDescription() string
GetNumber() int64
GetId() github_com_gogo_protobuf_test_custom.Uuid
}
func (this *A) Proto() github_com_gogo_protobuf_proto.Message {
return this
}
func (this *A) TestProto() github_com_gogo_protobuf_proto.Message {
return NewAFromFace(this)
}
func (this *A) GetDescription() string {
return this.Description
}
func (this *A) GetNumber() int64 {
return this.Number
}
func (this *A) GetId() github_com_gogo_protobuf_test_custom.Uuid {
return this.Id
}
func NewAFromFace(that AFace) *A {
this := &A{}
this.Description = that.GetDescription()
this.Number = that.GetNumber()
this.Id = that.GetId()
return this
}
and the following test code:
func TestAFace(t *testing7.T) {
popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano()))
p := NewPopulatedA(popr, true)
msg := p.TestProto()
if !p.Equal(msg) {
t.Fatalf("%#v !Face Equal %#v", msg, p)
}
}
The struct A, representing the message, will also be generated just like always.
As you can see A satisfies its own Face, AFace.
Creating another struct which satisfies AFace is very easy.
Simply create all these methods specified in AFace.
Implementing The Proto method is done with the helper function NewAFromFace:
func (this *MyStruct) Proto() proto.Message {
return NewAFromFace(this)
}
just the like TestProto method which is used to test the NewAFromFace function.
*/
package face
import (
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
)
type plugin struct {
*generator.Generator
generator.PluginImports
}
func NewPlugin() *plugin {
return &plugin{}
}
func (p *plugin) Name() string {
return "face"
}
func (p *plugin) Init(g *generator.Generator) {
p.Generator = g
}
func (p *plugin) Generate(file *generator.FileDescriptor) {
p.PluginImports = generator.NewPluginImports(p.Generator)
protoPkg := p.NewImport("github.com/gogo/protobuf/proto")
if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
protoPkg = p.NewImport("github.com/golang/protobuf/proto")
}
for _, message := range file.Messages() {
if !gogoproto.IsFace(file.FileDescriptorProto, message.DescriptorProto) {
continue
}
if message.DescriptorProto.GetOptions().GetMapEntry() {
continue
}
if message.DescriptorProto.HasExtension() {
panic("face does not support message with extensions")
}
if gogoproto.HasGoGetters(file.FileDescriptorProto, message.DescriptorProto) {
panic("face requires getters to be disabled please use gogoproto.getters or gogoproto.getters_all and set it to false")
}
ccTypeName := generator.CamelCaseSlice(message.TypeName())
p.P(`type `, ccTypeName, `Face interface{`)
p.In()
p.P(`Proto() `, protoPkg.Use(), `.Message`)
for _, field := range message.Field {
fieldname := p.GetFieldName(message, field)
goTyp, _ := p.GoType(message, field)
if p.IsMap(field) {
m := p.GoMapType(nil, field)
goTyp = m.GoType
}
p.P(`Get`, fieldname, `() `, goTyp)
}
p.Out()
p.P(`}`)
p.P(``)
p.P(`func (this *`, ccTypeName, `) Proto() `, protoPkg.Use(), `.Message {`)
p.In()
p.P(`return this`)
p.Out()
p.P(`}`)
p.P(``)
p.P(`func (this *`, ccTypeName, `) TestProto() `, protoPkg.Use(), `.Message {`)
p.In()
p.P(`return New`, ccTypeName, `FromFace(this)`)
p.Out()
p.P(`}`)
p.P(``)
for _, field := range message.Field {
fieldname := p.GetFieldName(message, field)
goTyp, _ := p.GoType(message, field)
if generator.IsMap(file.FileDescriptorProto, field) {
m := p.GoMapType(nil, field)
goTyp = m.GoType
}
p.P(`func (this *`, ccTypeName, `) Get`, fieldname, `() `, goTyp, `{`)
p.In()
p.P(` return this.`, fieldname)
p.Out()
p.P(`}`)
p.P(``)
}
p.P(``)
p.P(`func New`, ccTypeName, `FromFace(that `, ccTypeName, `Face) *`, ccTypeName, ` {`)
p.In()
p.P(`this := &`, ccTypeName, `{}`)
for _, field := range message.Field {
fieldname := p.GetFieldName(message, field)
p.P(`this.`, fieldname, ` = that.Get`, fieldname, `()`)
}
p.P(`return this`)
p.Out()
p.P(`}`)
p.P(``)
}
}
func init() {
generator.RegisterPlugin(NewPlugin())
}
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/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.
//
// 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 face
import (
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/plugin/testgen"
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
)
type test struct {
*generator.Generator
}
func NewTest(g *generator.Generator) testgen.TestPlugin {
return &test{g}
}
func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
used := false
randPkg := imports.NewImport("math/rand")
timePkg := imports.NewImport("time")
testingPkg := imports.NewImport("testing")
for _, message := range file.Messages() {
ccTypeName := generator.CamelCaseSlice(message.TypeName())
if !gogoproto.IsFace(file.FileDescriptorProto, message.DescriptorProto) {
continue
}
if message.DescriptorProto.GetOptions().GetMapEntry() {
continue
}
if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
used = true
p.P(`func Test`, ccTypeName, `Face(t *`, testingPkg.Use(), `.T) {`)
p.In()
p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(`, timePkg.Use(), `.Now().UnixNano()))`)
p.P(`p := NewPopulated`, ccTypeName, `(popr, true)`)
p.P(`msg := p.TestProto()`)
p.P(`if !p.Equal(msg) {`)
p.In()
p.P(`t.Fatalf("%#v !Face Equal %#v", msg, p)`)
p.Out()
p.P(`}`)
p.Out()
p.P(`}`)
}
}
return used
}
func init() {
testgen.RegisterTestPlugin(NewTest)
}
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/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.
//
// 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 gostring
import (
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/plugin/testgen"
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
)
type test struct {
*generator.Generator
}
func NewTest(g *generator.Generator) testgen.TestPlugin {
return &test{g}
}
func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
used := false
randPkg := imports.NewImport("math/rand")
timePkg := imports.NewImport("time")
testingPkg := imports.NewImport("testing")
fmtPkg := imports.NewImport("fmt")
parserPkg := imports.NewImport("go/parser")
for _, message := range file.Messages() {
ccTypeName := generator.CamelCaseSlice(message.TypeName())
if !gogoproto.HasGoString(file.FileDescriptorProto, message.DescriptorProto) {
continue
}
if message.DescriptorProto.GetOptions().GetMapEntry() {
continue
}
if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
used = true
p.P(`func Test`, ccTypeName, `GoString(t *`, testingPkg.Use(), `.T) {`)
p.In()
p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(`, timePkg.Use(), `.Now().UnixNano()))`)
p.P(`p := NewPopulated`, ccTypeName, `(popr, false)`)
p.P(`s1 := p.GoString()`)
p.P(`s2 := `, fmtPkg.Use(), `.Sprintf("%#v", p)`)
p.P(`if s1 != s2 {`)
p.In()
p.P(`t.Fatalf("GoString want %v got %v", s1, s2)`)
p.Out()
p.P(`}`)
p.P(`_, err := `, parserPkg.Use(), `.ParseExpr(s1)`)
p.P(`if err != nil {`)
p.In()
p.P(`panic(err)`)
p.Out()
p.P(`}`)
p.Out()
p.P(`}`)
}
}
return used
}
func init() {
testgen.RegisterTestPlugin(NewTest)
}
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/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.
//
// 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.
/*
The oneofcheck plugin is used to check whether oneof is not used incorrectly.
For instance:
An error is caused if a oneof field:
- is used in a face
- is an embedded field
*/
package oneofcheck
import (
"fmt"
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
"os"
)
type plugin struct {
*generator.Generator
}
func NewPlugin() *plugin {
return &plugin{}
}
func (p *plugin) Name() string {
return "oneofcheck"
}
func (p *plugin) Init(g *generator.Generator) {
p.Generator = g
}
func (p *plugin) Generate(file *generator.FileDescriptor) {
for _, msg := range file.Messages() {
face := gogoproto.IsFace(file.FileDescriptorProto, msg.DescriptorProto)
for _, field := range msg.GetField() {
if field.OneofIndex == nil {
continue
}
if face {
fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be in a face and oneof\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
os.Exit(1)
}
if gogoproto.IsEmbed(field) {
fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be in an oneof and an embedded field\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
os.Exit(1)
}
if !gogoproto.IsNullable(field) {
fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be in an oneof and a non-nullable field\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
os.Exit(1)
}
if gogoproto.IsUnion(file.FileDescriptorProto, msg.DescriptorProto) {
fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be in an oneof and in an union (deprecated)\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
os.Exit(1)
}
}
}
}
func (p *plugin) GenerateImports(*generator.FileDescriptor) {}
func init() {
generator.RegisterPlugin(NewPlugin())
}
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/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.
//
// 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 size
import (
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/plugin/testgen"
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
)
type test struct {
*generator.Generator
}
func NewTest(g *generator.Generator) testgen.TestPlugin {
return &test{g}
}
func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
used := false
randPkg := imports.NewImport("math/rand")
timePkg := imports.NewImport("time")
testingPkg := imports.NewImport("testing")
protoPkg := imports.NewImport("github.com/gogo/protobuf/proto")
if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
protoPkg = imports.NewImport("github.com/golang/protobuf/proto")
}
for _, message := range file.Messages() {
ccTypeName := generator.CamelCaseSlice(message.TypeName())
if !gogoproto.IsSizer(file.FileDescriptorProto, message.DescriptorProto) {
continue
}
if message.DescriptorProto.GetOptions().GetMapEntry() {
continue
}
if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
used = true
p.P(`func Test`, ccTypeName, `Size(t *`, testingPkg.Use(), `.T) {`)
p.In()
p.P(`seed := `, timePkg.Use(), `.Now().UnixNano()`)
p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(seed))`)
p.P(`p := NewPopulated`, ccTypeName, `(popr, true)`)
p.P(`size2 := `, protoPkg.Use(), `.Size(p)`)
p.P(`data, err := `, protoPkg.Use(), `.Marshal(p)`)
p.P(`if err != nil {`)
p.In()
p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
p.Out()
p.P(`}`)
p.P(`size := p.Size()`)
p.P(`if len(data) != size {`)
p.In()
p.P(`t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data))`)
p.Out()
p.P(`}`)
p.P(`if size2 != size {`)
p.In()
p.P(`t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2)`)
p.Out()
p.P(`}`)
p.P(`size3 := `, protoPkg.Use(), `.Size(p)`)
p.P(`if size3 != size {`)
p.In()
p.P(`t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3)`)
p.Out()
p.P(`}`)
p.Out()
p.P(`}`)
p.P()
}
if gogoproto.HasBenchGen(file.FileDescriptorProto, message.DescriptorProto) {
used = true
p.P(`func Benchmark`, ccTypeName, `Size(b *`, testingPkg.Use(), `.B) {`)
p.In()
p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(616))`)
p.P(`total := 0`)
p.P(`pops := make([]*`, ccTypeName, `, 1000)`)
p.P(`for i := 0; i < 1000; i++ {`)
p.In()
p.P(`pops[i] = NewPopulated`, ccTypeName, `(popr, false)`)
p.Out()
p.P(`}`)
p.P(`b.ResetTimer()`)
p.P(`for i := 0; i < b.N; i++ {`)
p.In()
p.P(`total += pops[i%1000].Size()`)
p.Out()
p.P(`}`)
p.P(`b.SetBytes(int64(total / b.N))`)
p.Out()
p.P(`}`)
p.P()
}
}
return used
}
func init() {
testgen.RegisterTestPlugin(NewTest)
}
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/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.
//
// 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 stringer
import (
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/plugin/testgen"
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
)
type test struct {
*generator.Generator
}
func NewTest(g *generator.Generator) testgen.TestPlugin {
return &test{g}
}
func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
used := false
randPkg := imports.NewImport("math/rand")
timePkg := imports.NewImport("time")
testingPkg := imports.NewImport("testing")
fmtPkg := imports.NewImport("fmt")
for _, message := range file.Messages() {
ccTypeName := generator.CamelCaseSlice(message.TypeName())
if !gogoproto.IsStringer(file.FileDescriptorProto, message.DescriptorProto) {
continue
}
if message.DescriptorProto.GetOptions().GetMapEntry() {
continue
}
if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
used = true
p.P(`func Test`, ccTypeName, `Stringer(t *`, testingPkg.Use(), `.T) {`)
p.In()
p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(`, timePkg.Use(), `.Now().UnixNano()))`)
p.P(`p := NewPopulated`, ccTypeName, `(popr, false)`)
p.P(`s1 := p.String()`)
p.P(`s2 := `, fmtPkg.Use(), `.Sprintf("%v", p)`)
p.P(`if s1 != s2 {`)
p.In()
p.P(`t.Fatalf("String want %v got %v", s1, s2)`)
p.Out()
p.P(`}`)
p.Out()
p.P(`}`)
}
}
return used
}
func init() {
testgen.RegisterTestPlugin(NewTest)
}
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/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.
//
// 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.
/*
The onlyone plugin generates code for the onlyone extension.
All fields must be nullable and only one of the fields may be set, like a union.
Two methods are generated
GetValue() interface{}
and
SetValue(v interface{}) (set bool)
These provide easier interaction with a onlyone.
The onlyone extension is not called union as this causes compile errors in the C++ generated code.
There can only be one ;)
It is enabled by the following extensions:
- onlyone
- onlyone_all
The onlyone plugin also generates a test given it is enabled using one of the following extensions:
- testgen
- testgen_all
Lets look at:
github.com/gogo/protobuf/test/example/example.proto
Btw all the output can be seen at:
github.com/gogo/protobuf/test/example/*
The following message:
message U {
option (gogoproto.onlyone) = true;
optional A A = 1;
optional B B = 2;
}
given to the onlyone plugin, will generate code which looks a lot like this:
func (this *U) GetValue() interface{} {
if this.A != nil {
return this.A
}
if this.B != nil {
return this.B
}
return nil
}
func (this *U) SetValue(value interface{}) bool {
switch vt := value.(type) {
case *A:
this.A = vt
case *B:
this.B = vt
default:
return false
}
return true
}
and the following test code:
func TestUUnion(t *testing.T) {
popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano()))
p := NewPopulatedU(popr)
v := p.GetValue()
msg := &U{}
if !msg.SetValue(v) {
t.Fatalf("Union: Could not set Value")
}
if !p.Equal(msg) {
t.Fatalf("%#v !Union Equal %#v", msg, p)
}
}
*/
package union
import (
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
)
type union struct {
*generator.Generator
generator.PluginImports
}
func NewUnion() *union {
return &union{}
}
func (p *union) Name() string {
return "union"
}
func (p *union) Init(g *generator.Generator) {
p.Generator = g
}
func (p *union) Generate(file *generator.FileDescriptor) {
p.PluginImports = generator.NewPluginImports(p.Generator)
for _, message := range file.Messages() {
if !gogoproto.IsUnion(file.FileDescriptorProto, message.DescriptorProto) {
continue
}
if message.DescriptorProto.HasExtension() {
panic("onlyone does not currently support extensions")
}
if message.DescriptorProto.GetOptions().GetMapEntry() {
continue
}
ccTypeName := generator.CamelCaseSlice(message.TypeName())
p.P(`func (this *`, ccTypeName, `) GetValue() interface{} {`)
p.In()
for _, field := range message.Field {
fieldname := p.GetFieldName(message, field)
if fieldname == "Value" {
panic("cannot have a onlyone message " + ccTypeName + " with a field named Value")
}
p.P(`if this.`, fieldname, ` != nil {`)
p.In()
p.P(`return this.`, fieldname)
p.Out()
p.P(`}`)
}
p.P(`return nil`)
p.Out()
p.P(`}`)
p.P(``)
p.P(`func (this *`, ccTypeName, `) SetValue(value interface{}) bool {`)
p.In()
p.P(`switch vt := value.(type) {`)
p.In()
for _, field := range message.Field {
fieldname := p.GetFieldName(message, field)
goTyp, _ := p.GoType(message, field)
p.P(`case `, goTyp, `:`)
p.In()
p.P(`this.`, fieldname, ` = vt`)
p.Out()
}
p.P(`default:`)
p.In()
for _, field := range message.Field {
fieldname := p.GetFieldName(message, field)
if field.IsMessage() {
goTyp, _ := p.GoType(message, field)
obj := p.ObjectNamed(field.GetTypeName()).(*generator.Descriptor)
if gogoproto.IsUnion(obj.File(), obj.DescriptorProto) {
p.P(`this.`, fieldname, ` = new(`, generator.GoTypeToName(goTyp), `)`)
p.P(`if set := this.`, fieldname, `.SetValue(value); set {`)
p.In()
p.P(`return true`)
p.Out()
p.P(`}`)
p.P(`this.`, fieldname, ` = nil`)
}
}
}
p.P(`return false`)
p.Out()
p.P(`}`)
p.P(`return true`)
p.Out()
p.P(`}`)
}
}
func init() {
generator.RegisterPlugin(NewUnion())
}
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/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.
//
// 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 union
import (
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/plugin/testgen"
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
)
type test struct {
*generator.Generator
}
func NewTest(g *generator.Generator) testgen.TestPlugin {
return &test{g}
}
func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
used := false
randPkg := imports.NewImport("math/rand")
timePkg := imports.NewImport("time")
testingPkg := imports.NewImport("testing")
for _, message := range file.Messages() {
if !gogoproto.IsUnion(file.FileDescriptorProto, message.DescriptorProto) ||
!gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
continue
}
if message.DescriptorProto.GetOptions().GetMapEntry() {
continue
}
used = true
ccTypeName := generator.CamelCaseSlice(message.TypeName())
p.P(`func Test`, ccTypeName, `OnlyOne(t *`, testingPkg.Use(), `.T) {`)
p.In()
p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(`, timePkg.Use(), `.Now().UnixNano()))`)
p.P(`p := NewPopulated`, ccTypeName, `(popr, true)`)
p.P(`v := p.GetValue()`)
p.P(`msg := &`, ccTypeName, `{}`)
p.P(`if !msg.SetValue(v) {`)
p.In()
p.P(`t.Fatalf("OnlyOne: Could not set Value")`)
p.Out()
p.P(`}`)
p.P(`if !p.Equal(msg) {`)
p.In()
p.P(`t.Fatalf("%#v !OnlyOne Equal %#v", msg, p)`)
p.Out()
p.P(`}`)
p.Out()
p.P(`}`)
}
return used
}
func init() {
testgen.RegisterTestPlugin(NewTest)
}
......@@ -30,7 +30,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Protocol buffer deep copy and merge.
// TODO: MessageSet and RawMessage.
// TODO: RawMessage.
package proto
......
......@@ -602,9 +602,13 @@ func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error
return err
}
nb := int(nn) // number of bytes of encoded bools
fin := o.index + nb
if fin < o.index {
return errOverflow
}
y := *v
for i := 0; i < nb; i++ {
for o.index < fin {
u, err := p.valDec(o)
if err != nil {
return err
......
......@@ -1115,9 +1115,8 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
return nil
}
keys := v.MapKeys()
sort.Sort(mapKeys(keys))
for _, key := range keys {
// Don't sort map keys. It is not required by the spec, and C++ doesn't do it.
for _, key := range v.MapKeys() {
val := v.MapIndex(key)
// The only illegal map entry values are nil message pointers.
......
......@@ -30,7 +30,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Protocol buffer comparison.
// TODO: MessageSet.
package proto
......
......@@ -216,7 +216,7 @@ The resulting file, test.pb.go, is:
To create and play with a Test object:
package main
package main
import (
"log"
......
......@@ -44,11 +44,11 @@ import (
"sort"
)
// ErrNoMessageTypeId occurs when a protocol buffer does not have a message type ID.
// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
// A message type ID is required for storing a protocol buffer in a message set.
var ErrNoMessageTypeId = errors.New("proto does not have a message type ID")
var errNoMessageTypeID = errors.New("proto does not have a message type ID")
// The first two types (_MessageSet_Item and MessageSet)
// The first two types (_MessageSet_Item and messageSet)
// model what the protocol compiler produces for the following protocol message:
// message MessageSet {
// repeated group Item = 1 {
......@@ -58,27 +58,20 @@ var ErrNoMessageTypeId = errors.New("proto does not have a message type ID")
// }
// That is the MessageSet wire format. We can't use a proto to generate these
// because that would introduce a circular dependency between it and this package.
//
// When a proto1 proto has a field that looks like:
// optional message<MessageSet> info = 3;
// the protocol compiler produces a field in the generated struct that looks like:
// Info *_proto_.MessageSet `protobuf:"bytes,3,opt,name=info"`
// The package is automatically inserted so there is no need for that proto file to
// import this package.
type _MessageSet_Item struct {
TypeId *int32 `protobuf:"varint,2,req,name=type_id"`
Message []byte `protobuf:"bytes,3,req,name=message"`
}
type MessageSet struct {
type messageSet struct {
Item []*_MessageSet_Item `protobuf:"group,1,rep"`
XXX_unrecognized []byte
// TODO: caching?
}
// Make sure MessageSet is a Message.
var _ Message = (*MessageSet)(nil)
// Make sure messageSet is a Message.
var _ Message = (*messageSet)(nil)
// messageTypeIder is an interface satisfied by a protocol buffer type
// that may be stored in a MessageSet.
......@@ -86,7 +79,7 @@ type messageTypeIder interface {
MessageTypeId() int32
}
func (ms *MessageSet) find(pb Message) *_MessageSet_Item {
func (ms *messageSet) find(pb Message) *_MessageSet_Item {
mti, ok := pb.(messageTypeIder)
if !ok {
return nil
......@@ -100,24 +93,24 @@ func (ms *MessageSet) find(pb Message) *_MessageSet_Item {
return nil
}
func (ms *MessageSet) Has(pb Message) bool {
func (ms *messageSet) Has(pb Message) bool {
if ms.find(pb) != nil {
return true
}
return false
}
func (ms *MessageSet) Unmarshal(pb Message) error {
func (ms *messageSet) Unmarshal(pb Message) error {
if item := ms.find(pb); item != nil {
return Unmarshal(item.Message, pb)
}
if _, ok := pb.(messageTypeIder); !ok {
return ErrNoMessageTypeId
return errNoMessageTypeID
}
return nil // TODO: return error instead?
}
func (ms *MessageSet) Marshal(pb Message) error {
func (ms *messageSet) Marshal(pb Message) error {
msg, err := Marshal(pb)
if err != nil {
return err
......@@ -130,7 +123,7 @@ func (ms *MessageSet) Marshal(pb Message) error {
mti, ok := pb.(messageTypeIder)
if !ok {
return ErrNoMessageTypeId
return errNoMessageTypeID
}
mtid := mti.MessageTypeId()
......@@ -141,9 +134,9 @@ func (ms *MessageSet) Marshal(pb Message) error {
return nil
}
func (ms *MessageSet) Reset() { *ms = MessageSet{} }
func (ms *MessageSet) String() string { return CompactTextString(ms) }
func (*MessageSet) ProtoMessage() {}
func (ms *messageSet) Reset() { *ms = messageSet{} }
func (ms *messageSet) String() string { return CompactTextString(ms) }
func (*messageSet) ProtoMessage() {}
// Support for the message_set_wire_format message option.
......@@ -169,7 +162,7 @@ func MarshalMessageSet(m map[int32]Extension) ([]byte, error) {
}
sort.Ints(ids)
ms := &MessageSet{Item: make([]*_MessageSet_Item, 0, len(m))}
ms := &messageSet{Item: make([]*_MessageSet_Item, 0, len(m))}
for _, id := range ids {
e := m[int32(id)]
// Remove the wire type and field number varint, as well as the length varint.
......@@ -186,7 +179,7 @@ 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 {
ms := new(MessageSet)
ms := new(messageSet)
if err := Unmarshal(buf, ms); err != nil {
return err
}
......
......@@ -42,6 +42,7 @@ package proto
import (
"fmt"
"log"
"os"
"reflect"
"sort"
......@@ -740,6 +741,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
prop.Prop = make([]*Properties, t.NumField())
prop.order = make([]int, t.NumField())
isOneofMessage := false
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
p := new(Properties)
......@@ -761,6 +763,9 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
prop.unrecField = toField(&f)
}
oneof := f.Tag.Get("protobuf_oneof") != "" // special case
if oneof {
isOneofMessage = true
}
prop.Prop[i] = p
prop.order[i] = i
if debug {
......@@ -781,7 +786,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
type oneofMessage interface {
XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), []interface{})
}
if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok {
if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); isOneofMessage && ok {
var oots []interface{}
prop.oneofMarshaler, prop.oneofUnmarshaler, oots = om.XXX_OneofFuncs()
prop.stype = t
......@@ -876,3 +881,35 @@ func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[
}
enumStringMaps[typeName] = unusedNameMap
}
// EnumValueMap returns the mapping from names to integers of the
// enum type enumType, or a nil if not found.
func EnumValueMap(enumType string) map[string]int32 {
return enumValueMaps[enumType]
}
// A registry of all linked message types.
// The string is a fully-qualified proto name ("pkg.Message").
var (
protoTypes = make(map[string]reflect.Type)
revProtoTypes = make(map[reflect.Type]string)
)
// RegisterType is called from generated code and maps from the fully qualified
// proto name to the type (pointer to struct) of the protocol buffer.
func RegisterType(x Message, name string) {
if _, ok := protoTypes[name]; ok {
// TODO: Some day, make this a panic.
log.Printf("proto: duplicate proto type registered: %s", name)
return
}
t := reflect.TypeOf(x)
protoTypes[name] = t
revProtoTypes[t] = name
}
// MessageName returns the fully-qualified proto name for the given message type.
func MessageName(x Message) string { 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] }
......@@ -122,5 +122,8 @@ func (m *MessageWithMap) GetByteMapping() map[bool][]byte {
}
func init() {
proto.RegisterType((*Message)(nil), "proto3_proto.Message")
proto.RegisterType((*Nested)(nil), "proto3_proto.Nested")
proto.RegisterType((*MessageWithMap)(nil), "proto3_proto.MessageWithMap")
proto.RegisterEnum("proto3_proto.Message_Humour", Message_Humour_name, Message_Humour_value)
}
......@@ -175,20 +175,12 @@ func writeName(w *textWriter, props *Properties) error {
return nil
}
var (
messageSetType = reflect.TypeOf((*MessageSet)(nil)).Elem()
)
// raw is the interface satisfied by RawMessage.
type raw interface {
Bytes() []byte
}
func writeStruct(w *textWriter, sv reflect.Value) error {
if sv.Type() == messageSetType {
return writeMessageSet(w, sv.Addr().Interface().(*MessageSet))
}
st := sv.Type()
sprops := GetProperties(st)
for i := 0; i < sv.NumField(); i++ {
......@@ -387,7 +379,13 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
}
// Extensions (the XXX_extensions field).
pv := sv.Addr()
pv := sv
if pv.CanAddr() {
pv = sv.Addr()
} else {
pv = reflect.New(sv.Type())
pv.Elem().Set(sv)
}
if pv.Type().Implements(extendableProtoType) {
if err := writeExtensions(w, pv); err != nil {
return err
......@@ -550,45 +548,7 @@ func writeString(w *textWriter, s string) error {
return w.WriteByte('"')
}
func writeMessageSet(w *textWriter, ms *MessageSet) error {
for _, item := range ms.Item {
id := *item.TypeId
if msd, ok := messageSetMap[id]; ok {
// Known message set type.
if _, err := fmt.Fprintf(w, "[%s]: <\n", msd.name); err != nil {
return err
}
w.indent()
pb := reflect.New(msd.t.Elem())
if err := Unmarshal(item.Message, pb.Interface().(Message)); err != nil {
if _, ferr := fmt.Fprintf(w, "/* bad message: %v */\n", err); ferr != nil {
return ferr
}
} else {
if err := writeStruct(w, pb.Elem()); err != nil {
return err
}
}
} else {
// Unknown type.
if _, err := fmt.Fprintf(w, "[%d]: <\n", id); err != nil {
return err
}
w.indent()
if err := writeUnknownStruct(w, item.Message); err != nil {
return err
}
}
w.unindent()
if _, err := w.Write(gtNewline); err != nil {
return err
}
}
return nil
}
func writeUnknownStruct(w *textWriter, data []byte) error {
func writeUnknownStruct(w *textWriter, data []byte) (err error) {
if !w.compact {
if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
return err
......
......@@ -715,18 +715,32 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error {
fv.Set(reflect.ValueOf(bytes))
return nil
}
// Repeated field. May already exist.
flen := fv.Len()
if flen == fv.Cap() {
nav := reflect.MakeSlice(at, flen, 2*flen+1)
reflect.Copy(nav, fv)
fv.Set(nav)
// Repeated field.
if tok.value == "[" {
// Repeated field with list notation, like [1,2,3].
for {
fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
err := p.readAny(fv.Index(fv.Len()-1), props)
if err != nil {
return err
}
tok := p.next()
if tok.err != nil {
return tok.err
}
if tok.value == "]" {
break
}
if tok.value != "," {
return p.errorf("Expected ']' or ',' found %q", tok.value)
}
}
return nil
}
fv.SetLen(flen + 1)
// Read one.
// One value of the repeated field.
p.back()
return p.readAny(fv.Index(flen), props)
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.
switch tok.value {
......
# 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.
regenerate:
protoc --gogo_out=. -I=../../protobuf/google/protobuf ../../protobuf/google/protobuf/descriptor.proto
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/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.
//
// 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
import (
"strings"
)
func (msg *DescriptorProto) GetMapFields() (*FieldDescriptorProto, *FieldDescriptorProto) {
if !msg.GetOptions().GetMapEntry() {
return nil, nil
}
return msg.GetField()[0], msg.GetField()[1]
}
func dotToUnderscore(r rune) rune {
if r == '.' {
return '_'
}
return r
}
func (field *FieldDescriptorProto) WireType() (wire int) {
switch *field.Type {
case FieldDescriptorProto_TYPE_DOUBLE:
return 1
case FieldDescriptorProto_TYPE_FLOAT:
return 5
case FieldDescriptorProto_TYPE_INT64:
return 0
case FieldDescriptorProto_TYPE_UINT64:
return 0
case FieldDescriptorProto_TYPE_INT32:
return 0
case FieldDescriptorProto_TYPE_UINT32:
return 0
case FieldDescriptorProto_TYPE_FIXED64:
return 1
case FieldDescriptorProto_TYPE_FIXED32:
return 5
case FieldDescriptorProto_TYPE_BOOL:
return 0
case FieldDescriptorProto_TYPE_STRING:
return 2
case FieldDescriptorProto_TYPE_GROUP:
return 2
case FieldDescriptorProto_TYPE_MESSAGE:
return 2
case FieldDescriptorProto_TYPE_BYTES:
return 2
case FieldDescriptorProto_TYPE_ENUM:
return 0
case FieldDescriptorProto_TYPE_SFIXED32:
return 5
case FieldDescriptorProto_TYPE_SFIXED64:
return 1
case FieldDescriptorProto_TYPE_SINT32:
return 0
case FieldDescriptorProto_TYPE_SINT64:
return 0
}
panic("unreachable")
}
func (field *FieldDescriptorProto) GetKeyUint64() (x uint64) {
packed := field.IsPacked()
wireType := field.WireType()
fieldNumber := field.GetNumber()
if packed {
wireType = 2
}
x = uint64(uint32(fieldNumber)<<3 | uint32(wireType))
return x
}
func (field *FieldDescriptorProto) GetKey() []byte {
x := field.GetKeyUint64()
i := 0
keybuf := make([]byte, 0)
for i = 0; x > 127; i++ {
keybuf = append(keybuf, 0x80|uint8(x&0x7F))
x >>= 7
}
keybuf = append(keybuf, uint8(x))
return keybuf
}
func (desc *FileDescriptorSet) GetField(packageName, messageName, fieldName string) *FieldDescriptorProto {
msg := desc.GetMessage(packageName, messageName)
if msg == nil {
return nil
}
for _, field := range msg.GetField() {
if field.GetName() == fieldName {
return field
}
}
return nil
}
func (file *FileDescriptorProto) GetMessage(typeName string) *DescriptorProto {
for _, msg := range file.GetMessageType() {
if msg.GetName() == typeName {
return msg
}
for _, nes := range msg.GetNestedType() {
if nes.GetName() == typeName {
return nes
}
if msg.GetName()+"."+nes.GetName() == typeName {
return nes
}
}
}
return nil
}
func (desc *FileDescriptorSet) GetMessage(packageName string, typeName string) *DescriptorProto {
for _, file := range desc.GetFile() {
if strings.Map(dotToUnderscore, file.GetPackage()) != strings.Map(dotToUnderscore, packageName) {
continue
}
for _, msg := range file.GetMessageType() {
if msg.GetName() == typeName {
return msg
}
}
for _, msg := range file.GetMessageType() {
for _, nes := range msg.GetNestedType() {
if nes.GetName() == typeName {
return nes
}
if msg.GetName()+"."+nes.GetName() == typeName {
return nes
}
}
}
}
return nil
}
func (desc *FileDescriptorSet) IsProto3(packageName string, typeName string) bool {
for _, file := range desc.GetFile() {
if strings.Map(dotToUnderscore, file.GetPackage()) != strings.Map(dotToUnderscore, packageName) {
continue
}
for _, msg := range file.GetMessageType() {
if msg.GetName() == typeName {
return file.GetSyntax() == "proto3"
}
}
for _, msg := range file.GetMessageType() {
for _, nes := range msg.GetNestedType() {
if nes.GetName() == typeName {
return file.GetSyntax() == "proto3"
}
if msg.GetName()+"."+nes.GetName() == typeName {
return file.GetSyntax() == "proto3"
}
}
}
}
return false
}
func (msg *DescriptorProto) IsExtendable() bool {
return len(msg.GetExtensionRange()) > 0
}
func (desc *FileDescriptorSet) FindExtension(packageName string, typeName string, fieldName string) (extPackageName string, field *FieldDescriptorProto) {
parent := desc.GetMessage(packageName, typeName)
if parent == nil {
return "", nil
}
if !parent.IsExtendable() {
return "", nil
}
extendee := "." + packageName + "." + typeName
for _, file := range desc.GetFile() {
for _, ext := range file.GetExtension() {
if strings.Map(dotToUnderscore, file.GetPackage()) == strings.Map(dotToUnderscore, packageName) {
if !(ext.GetExtendee() == typeName || ext.GetExtendee() == extendee) {
continue
}
} else {
if ext.GetExtendee() != extendee {
continue
}
}
if ext.GetName() == fieldName {
return file.GetPackage(), ext
}
}
}
return "", nil
}
func (desc *FileDescriptorSet) FindExtensionByFieldNumber(packageName string, typeName string, fieldNum int32) (extPackageName string, field *FieldDescriptorProto) {
parent := desc.GetMessage(packageName, typeName)
if parent == nil {
return "", nil
}
if !parent.IsExtendable() {
return "", nil
}
extendee := "." + packageName + "." + typeName
for _, file := range desc.GetFile() {
for _, ext := range file.GetExtension() {
if strings.Map(dotToUnderscore, file.GetPackage()) == strings.Map(dotToUnderscore, packageName) {
if !(ext.GetExtendee() == typeName || ext.GetExtendee() == extendee) {
continue
}
} else {
if ext.GetExtendee() != extendee {
continue
}
}
if ext.GetNumber() == fieldNum {
return file.GetPackage(), ext
}
}
}
return "", nil
}
func (desc *FileDescriptorSet) FindMessage(packageName string, typeName string, fieldName string) (msgPackageName string, msgName string) {
parent := desc.GetMessage(packageName, typeName)
if parent == nil {
return "", ""
}
field := parent.GetFieldDescriptor(fieldName)
if field == nil {
var extPackageName string
extPackageName, field = desc.FindExtension(packageName, typeName, fieldName)
if field == nil {
return "", ""
}
packageName = extPackageName
}
typeNames := strings.Split(field.GetTypeName(), ".")
if len(typeNames) == 1 {
msg := desc.GetMessage(packageName, typeName)
if msg == nil {
return "", ""
}
return packageName, msg.GetName()
}
if len(typeNames) > 2 {
for i := 1; i < len(typeNames)-1; i++ {
packageName = strings.Join(typeNames[1:len(typeNames)-i], ".")
typeName = strings.Join(typeNames[len(typeNames)-i:], ".")
msg := desc.GetMessage(packageName, typeName)
if msg != nil {
typeNames := strings.Split(msg.GetName(), ".")
if len(typeNames) == 1 {
return packageName, msg.GetName()
}
return strings.Join(typeNames[1:len(typeNames)-1], "."), typeNames[len(typeNames)-1]
}
}
}
return "", ""
}
func (msg *DescriptorProto) GetFieldDescriptor(fieldName string) *FieldDescriptorProto {
for _, field := range msg.GetField() {
if field.GetName() == fieldName {
return field
}
}
return nil
}
func (desc *FileDescriptorSet) GetEnum(packageName string, typeName string) *EnumDescriptorProto {
for _, file := range desc.GetFile() {
if strings.Map(dotToUnderscore, file.GetPackage()) != strings.Map(dotToUnderscore, packageName) {
continue
}
for _, enum := range file.GetEnumType() {
if enum.GetName() == typeName {
return enum
}
}
}
return nil
}
func (f *FieldDescriptorProto) IsEnum() bool {
return *f.Type == FieldDescriptorProto_TYPE_ENUM
}
func (f *FieldDescriptorProto) IsMessage() bool {
return *f.Type == FieldDescriptorProto_TYPE_MESSAGE
}
func (f *FieldDescriptorProto) IsBytes() bool {
return *f.Type == FieldDescriptorProto_TYPE_BYTES
}
func (f *FieldDescriptorProto) IsRepeated() bool {
return f.Label != nil && *f.Label == FieldDescriptorProto_LABEL_REPEATED
}
func (f *FieldDescriptorProto) IsString() bool {
return *f.Type == FieldDescriptorProto_TYPE_STRING
}
func (f *FieldDescriptorProto) IsRequired() bool {
return f.Label != nil && *f.Label == FieldDescriptorProto_LABEL_REQUIRED
}
func (f *FieldDescriptorProto) IsPacked() bool {
return f.Options != nil && f.GetOptions().GetPacked()
}
func (m *DescriptorProto) HasExtension() bool {
return len(m.ExtensionRange) > 0
}
# 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.
# Not stored here, but plugin.proto is in https://github.com/google/protobuf/
# at src/google/protobuf/compiler/plugin.proto
# Also we need to fix an import.
regenerate:
protoc --gogo_out=Mgoogle/protobuf/descriptor.proto=github.com/gogo/protobuf/protoc-gen-gogo/descriptor:. -I=../../protobuf/google/protobuf/compiler/:../../protobuf/ ../../protobuf/google/protobuf/compiler/plugin.proto
// Code generated by protoc-gen-gogo.
// source: plugin.proto
// DO NOT EDIT!
/*
Package plugin_go is a generated protocol buffer package.
It is generated from these files:
plugin.proto
It has these top-level messages:
CodeGeneratorRequest
CodeGeneratorResponse
*/
package plugin_go
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import google_protobuf "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// 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:"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.
ProtoFile []*google_protobuf.FileDescriptorProto `protobuf:"bytes,15,rep,name=proto_file" json:"proto_file,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *CodeGeneratorRequest) Reset() { *m = CodeGeneratorRequest{} }
func (m *CodeGeneratorRequest) String() string { return proto.CompactTextString(m) }
func (*CodeGeneratorRequest) ProtoMessage() {}
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
}
// 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 (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:"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 (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((*CodeGeneratorRequest)(nil), "google.protobuf.compiler.CodeGeneratorRequest")
proto.RegisterType((*CodeGeneratorResponse)(nil), "google.protobuf.compiler.CodeGeneratorResponse")
proto.RegisterType((*CodeGeneratorResponse_File)(nil), "google.protobuf.compiler.CodeGeneratorResponse.File")
}
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/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.
//
// 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 sortkeys
import (
"sort"
)
func Strings(l []string) {
sort.Strings(l)
}
func Float64s(l []float64) {
sort.Float64s(l)
}
func Float32s(l []float32) {
sort.Sort(Float32Slice(l))
}
func Int64s(l []int64) {
sort.Sort(Int64Slice(l))
}
func Int32s(l []int32) {
sort.Sort(Int32Slice(l))
}
func Uint64s(l []uint64) {
sort.Sort(Uint64Slice(l))
}
func Uint32s(l []uint32) {
sort.Sort(Uint32Slice(l))
}
func Bools(l []bool) {
sort.Sort(BoolSlice(l))
}
type BoolSlice []bool
func (p BoolSlice) Len() int { return len(p) }
func (p BoolSlice) Less(i, j int) bool { return p[j] }
func (p BoolSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
type Int64Slice []int64
func (p Int64Slice) Len() int { return len(p) }
func (p Int64Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p Int64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
type Int32Slice []int32
func (p Int32Slice) Len() int { return len(p) }
func (p Int32Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p Int32Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
type Uint64Slice []uint64
func (p Uint64Slice) Len() int { return len(p) }
func (p Uint64Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p Uint64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
type Uint32Slice []uint32
func (p Uint32Slice) Len() int { return len(p) }
func (p Uint32Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p Uint32Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
type Float32Slice []float32
func (p Float32Slice) Len() int { return len(p) }
func (p Float32Slice) Less(i, j int) bool { return p[i] < p[j] }
func (p Float32Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
// Extensions for Protocol Buffers to create more go like structures.
//
// Copyright (c) 2015, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/protobuf/gogoproto
//
// 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.
//
// 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 command
import (
"io/ioutil"
"os"
"github.com/gogo/protobuf/proto"
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
plugin "github.com/gogo/protobuf/protoc-gen-gogo/plugin"
_ "github.com/gogo/protobuf/plugin/grpc"
_ "github.com/gogo/protobuf/plugin/defaultcheck"
_ "github.com/gogo/protobuf/plugin/description"
_ "github.com/gogo/protobuf/plugin/embedcheck"
_ "github.com/gogo/protobuf/plugin/enumstringer"
_ "github.com/gogo/protobuf/plugin/equal"
_ "github.com/gogo/protobuf/plugin/face"
_ "github.com/gogo/protobuf/plugin/gostring"
_ "github.com/gogo/protobuf/plugin/marshalto"
_ "github.com/gogo/protobuf/plugin/oneofcheck"
_ "github.com/gogo/protobuf/plugin/populate"
_ "github.com/gogo/protobuf/plugin/size"
_ "github.com/gogo/protobuf/plugin/stringer"
_ "github.com/gogo/protobuf/plugin/union"
_ "github.com/gogo/protobuf/plugin/unmarshal"
"github.com/gogo/protobuf/plugin/testgen"
"go/format"
"strings"
)
func Read() *plugin.CodeGeneratorRequest {
g := generator.New()
data, err := ioutil.ReadAll(os.Stdin)
if err != nil {
g.Error(err, "reading input")
}
if err := proto.Unmarshal(data, g.Request); err != nil {
g.Error(err, "parsing input proto")
}
if len(g.Request.FileToGenerate) == 0 {
g.Fail("no files to generate")
}
return g.Request
}
func Generate(req *plugin.CodeGeneratorRequest) *plugin.CodeGeneratorResponse {
// Begin by allocating a generator. The request and response structures are stored there
// so we can do error handling easily - the response structure contains the field to
// report failure.
g := generator.New()
g.Request = req
g.CommandLineParameters(g.Request.GetParameter())
// Create a wrapped version of the Descriptors and EnumDescriptors that
// point to the file that defines them.
g.WrapTypes()
g.SetPackageNames()
g.BuildTypeNameMap()
g.GenerateAllFiles()
gtest := generator.New()
data, err := proto.Marshal(req)
if err != nil {
g.Error(err, "failed to marshal modified proto")
}
if err := proto.Unmarshal(data, gtest.Request); err != nil {
g.Error(err, "parsing modified proto")
}
if len(gtest.Request.FileToGenerate) == 0 {
gtest.Fail("no files to generate")
}
gtest.CommandLineParameters(gtest.Request.GetParameter())
// Create a wrapped version of the Descriptors and EnumDescriptors that
// point to the file that defines them.
gtest.WrapTypes()
gtest.SetPackageNames()
gtest.BuildTypeNameMap()
gtest.GeneratePlugin(testgen.NewPlugin())
for i := 0; i < len(gtest.Response.File); i++ {
if strings.Contains(*gtest.Response.File[i].Content, `//These tests are generated by github.com/gogo/protobuf/plugin/testgen`) {
gtest.Response.File[i].Name = proto.String(strings.Replace(*gtest.Response.File[i].Name, ".pb.go", "pb_test.go", -1))
g.Response.File = append(g.Response.File, gtest.Response.File[i])
}
}
for i := 0; i < len(g.Response.File); i++ {
formatted, err := format.Source([]byte(g.Response.File[i].GetContent()))
if err != nil {
g.Error(err, "go format error")
}
fmts := string(formatted)
g.Response.File[i].Content = &fmts
}
return g.Response
}
func Write(resp *plugin.CodeGeneratorResponse) {
g := generator.New()
// Send back the results.
data, err := proto.Marshal(resp)
if err != nil {
g.Error(err, "failed to marshal output proto")
}
_, err = os.Stdout.Write(data)
if err != nil {
g.Error(err, "failed to write output proto")
}
}
// Extensions for Protocol Buffers to create more go like structures.
//
// Copyright (c) 2015, Vastech SA (PTY) LTD. rights reserved.
// http://github.com/gogo/protobuf/gogoproto
//
// 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.
//
// 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 vanity
import (
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/proto"
descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
)
func EnumHasBoolExtension(enum *descriptor.EnumDescriptorProto, extension *proto.ExtensionDesc) bool {
if enum.Options == nil {
return false
}
value, err := proto.GetExtension(enum.Options, extension)
if err != nil {
return false
}
if value == nil {
return false
}
if value.(*bool) == nil {
return false
}
return true
}
func SetBoolEnumOption(extension *proto.ExtensionDesc, value bool) func(enum *descriptor.EnumDescriptorProto) {
return func(enum *descriptor.EnumDescriptorProto) {
if EnumHasBoolExtension(enum, extension) {
return
}
if enum.Options == nil {
enum.Options = &descriptor.EnumOptions{}
}
if err := proto.SetExtension(enum.Options, extension, &value); err != nil {
panic(err)
}
}
}
func TurnOffGoEnumPrefix(enum *descriptor.EnumDescriptorProto) {
SetBoolEnumOption(gogoproto.E_GoprotoEnumPrefix, false)(enum)
}
func TurnOffGoEnumStringer(enum *descriptor.EnumDescriptorProto) {
SetBoolEnumOption(gogoproto.E_GoprotoEnumStringer, false)(enum)
}
func TurnOnEnumStringer(enum *descriptor.EnumDescriptorProto) {
SetBoolEnumOption(gogoproto.E_EnumStringer, true)(enum)
}
// Extensions for Protocol Buffers to create more go like structures.
//
// Copyright (c) 2015, Vastech SA (PTY) LTD. rights reserved.
// http://github.com/gogo/protobuf/gogoproto
//
// 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.
//
// 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 vanity
import (
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/proto"
descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
)
func FieldHasBoolExtension(field *descriptor.FieldDescriptorProto, extension *proto.ExtensionDesc) bool {
if field.Options == nil {
return false
}
value, err := proto.GetExtension(field.Options, extension)
if err != nil {
return false
}
if value == nil {
return false
}
if value.(*bool) == nil {
return false
}
return true
}
func SetBoolFieldOption(extension *proto.ExtensionDesc, value bool) func(field *descriptor.FieldDescriptorProto) {
return func(field *descriptor.FieldDescriptorProto) {
if FieldHasBoolExtension(field, extension) {
return
}
if field.Options == nil {
field.Options = &descriptor.FieldOptions{}
}
if err := proto.SetExtension(field.Options, extension, &value); err != nil {
panic(err)
}
}
}
func TurnOffNullable(field *descriptor.FieldDescriptorProto) {
if field.IsRepeated() && !field.IsMessage() {
return
}
SetBoolFieldOption(gogoproto.E_Nullable, false)(field)
}
func TurnOffNullableForNativeTypesWithoutDefaultsOnly(field *descriptor.FieldDescriptorProto) {
if field.IsRepeated() || field.IsMessage() {
return
}
if field.DefaultValue != nil {
return
}
SetBoolFieldOption(gogoproto.E_Nullable, false)(field)
}
// Extensions for Protocol Buffers to create more go like structures.
//
// Copyright (c) 2015, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/protobuf/gogoproto
//
// 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.
//
// 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 vanity
import (
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/proto"
descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
"strings"
)
func NotInPackageGoogleProtobuf(file *descriptor.FileDescriptorProto) bool {
return !strings.HasPrefix(file.GetPackage(), "google.protobuf")
}
func FilterFiles(files []*descriptor.FileDescriptorProto, f func(file *descriptor.FileDescriptorProto) bool) []*descriptor.FileDescriptorProto {
filtered := make([]*descriptor.FileDescriptorProto, 0, len(files))
for i := range files {
if !f(files[i]) {
continue
}
filtered = append(filtered, files[i])
}
return filtered
}
func FileHasBoolExtension(file *descriptor.FileDescriptorProto, extension *proto.ExtensionDesc) bool {
if file.Options == nil {
return false
}
value, err := proto.GetExtension(file.Options, extension)
if err != nil {
return false
}
if value == nil {
return false
}
if value.(*bool) == nil {
return false
}
return true
}
func SetBoolFileOption(extension *proto.ExtensionDesc, value bool) func(file *descriptor.FileDescriptorProto) {
return func(file *descriptor.FileDescriptorProto) {
if FileHasBoolExtension(file, extension) {
return
}
if file.Options == nil {
file.Options = &descriptor.FileOptions{}
}
if err := proto.SetExtension(file.Options, extension, &value); err != nil {
panic(err)
}
}
}
func TurnOffGoGettersAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_GoprotoGettersAll, false)(file)
}
func TurnOffGoEnumPrefixAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_GoprotoEnumPrefixAll, false)(file)
}
func TurnOffGoStringerAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_GoprotoStringerAll, false)(file)
}
func TurnOnVerboseEqualAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_VerboseEqualAll, true)(file)
}
func TurnOnFaceAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_FaceAll, true)(file)
}
func TurnOnGoStringAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_GostringAll, true)(file)
}
func TurnOnPopulateAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_PopulateAll, true)(file)
}
func TurnOnStringerAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_StringerAll, true)(file)
}
func TurnOnEqualAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_EqualAll, true)(file)
}
func TurnOnDescriptionAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_DescriptionAll, true)(file)
}
func TurnOnTestGenAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_TestgenAll, true)(file)
}
func TurnOnBenchGenAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_BenchgenAll, true)(file)
}
func TurnOnMarshalerAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_MarshalerAll, true)(file)
}
func TurnOnUnmarshalerAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_UnmarshalerAll, true)(file)
}
func TurnOnSizerAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_SizerAll, true)(file)
}
func TurnOffGoEnumStringerAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_GoprotoEnumStringerAll, false)(file)
}
func TurnOnEnumStringerAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_EnumStringerAll, true)(file)
}
func TurnOnUnsafeUnmarshalerAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_UnsafeUnmarshalerAll, true)(file)
}
func TurnOnUnsafeMarshalerAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_UnsafeMarshalerAll, true)(file)
}
func TurnOffGoExtensionsMapAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_GoprotoExtensionsMapAll, false)(file)
}
func TurnOffGoUnrecognizedAll(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_GoprotoUnrecognizedAll, false)(file)
}
func TurnOffGogoImport(file *descriptor.FileDescriptorProto) {
SetBoolFileOption(gogoproto.E_GogoprotoImport, false)(file)
}
// Extensions for Protocol Buffers to create more go like structures.
//
// Copyright (c) 2015, Vastech SA (PTY) LTD. All rights reserved.
// http://github.com/gogo/protobuf/gogoproto
//
// 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.
//
// 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 vanity
import descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
func ForEachFile(files []*descriptor.FileDescriptorProto, f func(file *descriptor.FileDescriptorProto)) {
for _, file := range files {
f(file)
}
}
func OnlyProto2(files []*descriptor.FileDescriptorProto) []*descriptor.FileDescriptorProto {
outs := make([]*descriptor.FileDescriptorProto, 0, len(files))
for i, file := range files {
if file.GetSyntax() == "proto3" {
continue
}
outs = append(outs, files[i])
}
return outs
}
func OnlyProto3(files []*descriptor.FileDescriptorProto) []*descriptor.FileDescriptorProto {
outs := make([]*descriptor.FileDescriptorProto, 0, len(files))
for i, file := range files {
if file.GetSyntax() != "proto3" {
continue
}
outs = append(outs, files[i])
}
return outs
}
func ForEachMessageInFiles(files []*descriptor.FileDescriptorProto, f func(msg *descriptor.DescriptorProto)) {
for _, file := range files {
ForEachMessage(file.MessageType, f)
}
}
func ForEachMessage(msgs []*descriptor.DescriptorProto, f func(msg *descriptor.DescriptorProto)) {
for _, msg := range msgs {
f(msg)
ForEachMessage(msg.NestedType, f)
}
}
func ForEachFieldInFilesExcludingExtensions(files []*descriptor.FileDescriptorProto, f func(field *descriptor.FieldDescriptorProto)) {
for _, file := range files {
ForEachFieldExcludingExtensions(file.MessageType, f)
}
}
func ForEachFieldInFiles(files []*descriptor.FileDescriptorProto, f func(field *descriptor.FieldDescriptorProto)) {
for _, file := range files {
for _, ext := range file.Extension {
f(ext)
}
ForEachField(file.MessageType, f)
}
}
func ForEachFieldExcludingExtensions(msgs []*descriptor.DescriptorProto, f func(field *descriptor.FieldDescriptorProto)) {
for _, msg := range msgs {
for _, field := range msg.Field {
f(field)
}
ForEachField(msg.NestedType, f)
}
}
func ForEachField(msgs []*descriptor.DescriptorProto, f func(field *descriptor.FieldDescriptorProto)) {
for _, msg := range msgs {
for _, field := range msg.Field {
f(field)
}
for _, ext := range msg.Extension {
f(ext)
}
ForEachField(msg.NestedType, f)
}
}
func ForEachEnumInFiles(files []*descriptor.FileDescriptorProto, f func(enum *descriptor.EnumDescriptorProto)) {
for _, file := range files {
for _, enum := range file.EnumType {
f(enum)
}
}
}
func ForEachEnum(msgs []*descriptor.DescriptorProto, f func(field *descriptor.EnumDescriptorProto)) {
for _, msg := range msgs {
for _, field := range msg.EnumType {
f(field)
}
ForEachEnum(msg.NestedType, f)
}
}
// Extensions for Protocol Buffers to create more go like structures.
//
// Copyright (c) 2015, Vastech SA (PTY) LTD. rights reserved.
// http://github.com/gogo/protobuf/gogoproto
//
// 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.
//
// 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 vanity
import (
"github.com/gogo/protobuf/gogoproto"
"github.com/gogo/protobuf/proto"
descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
)
func MessageHasBoolExtension(msg *descriptor.DescriptorProto, extension *proto.ExtensionDesc) bool {
if msg.Options == nil {
return false
}
value, err := proto.GetExtension(msg.Options, extension)
if err != nil {
return false
}
if value == nil {
return false
}
if value.(*bool) == nil {
return false
}
return true
}
func SetBoolMessageOption(extension *proto.ExtensionDesc, value bool) func(msg *descriptor.DescriptorProto) {
return func(msg *descriptor.DescriptorProto) {
if MessageHasBoolExtension(msg, extension) {
return
}
if msg.Options == nil {
msg.Options = &descriptor.MessageOptions{}
}
if err := proto.SetExtension(msg.Options, extension, &value); err != nil {
panic(err)
}
}
}
func TurnOffGoGetters(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_GoprotoGetters, false)(msg)
}
func TurnOffGoStringer(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_GoprotoStringer, false)(msg)
}
func TurnOnVerboseEqual(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_VerboseEqual, true)(msg)
}
func TurnOnFace(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_Face, true)(msg)
}
func TurnOnGoString(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_Face, true)(msg)
}
func TurnOnPopulate(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_Populate, true)(msg)
}
func TurnOnStringer(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_Stringer, true)(msg)
}
func TurnOnEqual(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_Equal, true)(msg)
}
func TurnOnDescription(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_Description, true)(msg)
}
func TurnOnTestGen(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_Testgen, true)(msg)
}
func TurnOnBenchGen(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_Benchgen, true)(msg)
}
func TurnOnMarshaler(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_Marshaler, true)(msg)
}
func TurnOnUnmarshaler(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_Unmarshaler, true)(msg)
}
func TurnOnSizer(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_Sizer, true)(msg)
}
func TurnOnUnsafeUnmarshaler(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_UnsafeUnmarshaler, true)(msg)
}
func TurnOnUnsafeMarshaler(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_UnsafeMarshaler, true)(msg)
}
func TurnOffGoExtensionsMap(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_GoprotoExtensionsMap, false)(msg)
}
func TurnOffGoUnrecognized(msg *descriptor.DescriptorProto) {
SetBoolMessageOption(gogoproto.E_GoprotoUnrecognized, false)(msg)
}
regenerate:
go install github.com/gogo/protobuf/protoc-gen-gogofast
protoc --gogofast_out=./fast/ vanity.proto
protoc --proto_path=../../:../../../../../:../../protobuf/:. --gogofast_out=./fast/ gogovanity.proto
protoc-min-version -version="3.0.0" --proto_path=../../:../../../../../:../../protobuf/:. --gogofast_out=./fast/ proto3.proto
go install github.com/gogo/protobuf/protoc-gen-gogofaster
protoc --gogofaster_out=./faster/ vanity.proto
protoc --proto_path=../../:../../../../../:../../protobuf/:. --gogofaster_out=./faster/ gogovanity.proto
protoc-min-version -version="3.0.0" --proto_path=../../:../../../../../:../../protobuf/:. --gogofaster_out=./faster/ proto3.proto
go install github.com/gogo/protobuf/protoc-gen-gogoslick
protoc --gogoslick_out=./slick/ vanity.proto
protoc --proto_path=../../:../../../../../:../../protobuf/:. --gogoslick_out=./slick/ gogovanity.proto
protoc-min-version -version="3.0.0" --proto_path=../../:../../../../../:../../protobuf/:. --gogoslick_out=./slick/ proto3.proto
test:
go install github.com/gogo/protobuf/protoc-gen-gofast
protoc --gofast_out=./gofast/ vanity.proto
go test ./...
// Code generated by protoc-gen-gogo.
// source: gogovanity.proto
// DO NOT EDIT!
/*
Package vanity is a generated protocol buffer package.
It is generated from these files:
gogovanity.proto
It has these top-level messages:
B
*/
package vanity
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import _ "github.com/gogo/protobuf/gogoproto"
import io "io"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
type B struct {
String_ *string `protobuf:"bytes,1,opt,name=String" json:"String,omitempty"`
Int64 *int64 `protobuf:"varint,2,opt,name=Int64" json:"Int64,omitempty"`
Int32 *int32 `protobuf:"varint,3,opt,name=Int32,def=1234" json:"Int32,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *B) Reset() { *m = B{} }
func (m *B) String() string { return proto.CompactTextString(m) }
func (*B) ProtoMessage() {}
const Default_B_Int32 int32 = 1234
func (m *B) GetString_() string {
if m != nil && m.String_ != nil {
return *m.String_
}
return ""
}
func (m *B) GetInt64() int64 {
if m != nil && m.Int64 != nil {
return *m.Int64
}
return 0
}
func (m *B) GetInt32() int32 {
if m != nil && m.Int32 != nil {
return *m.Int32
}
return Default_B_Int32
}
func init() {
proto.RegisterType((*B)(nil), "vanity.B")
}
func (m *B) Marshal() (data []byte, err error) {
size := m.Size()
data = make([]byte, size)
n, err := m.MarshalTo(data)
if err != nil {
return nil, err
}
return data[:n], nil
}
func (m *B) MarshalTo(data []byte) (int, error) {
var i int
_ = i
var l int
_ = l
if m.String_ != nil {
data[i] = 0xa
i++
i = encodeVarintGogovanity(data, i, uint64(len(*m.String_)))
i += copy(data[i:], *m.String_)
}
if m.Int64 != nil {
data[i] = 0x10
i++
i = encodeVarintGogovanity(data, i, uint64(*m.Int64))
}
if m.Int32 != nil {
data[i] = 0x18
i++
i = encodeVarintGogovanity(data, i, uint64(*m.Int32))
}
if m.XXX_unrecognized != nil {
i += copy(data[i:], m.XXX_unrecognized)
}
return i, nil
}
func encodeFixed64Gogovanity(data []byte, offset int, v uint64) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
data[offset+4] = uint8(v >> 32)
data[offset+5] = uint8(v >> 40)
data[offset+6] = uint8(v >> 48)
data[offset+7] = uint8(v >> 56)
return offset + 8
}
func encodeFixed32Gogovanity(data []byte, offset int, v uint32) int {
data[offset] = uint8(v)
data[offset+1] = uint8(v >> 8)
data[offset+2] = uint8(v >> 16)
data[offset+3] = uint8(v >> 24)
return offset + 4
}
func encodeVarintGogovanity(data []byte, offset int, v uint64) int {
for v >= 1<<7 {
data[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
data[offset] = uint8(v)
return offset + 1
}
func (m *B) Size() (n int) {
var l int
_ = l
if m.String_ != nil {
l = len(*m.String_)
n += 1 + l + sovGogovanity(uint64(l))
}
if m.Int64 != nil {
n += 1 + sovGogovanity(uint64(*m.Int64))
}
if m.Int32 != nil {
n += 1 + sovGogovanity(uint64(*m.Int32))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovGogovanity(x uint64) (n int) {
for {
n++
x >>= 7
if x == 0 {
break
}
}
return n
}
func sozGogovanity(x uint64) (n int) {
return sovGogovanity(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *B) Unmarshal(data []byte) error {
l := len(data)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGogovanity
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: B: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: B: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field String_", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGogovanity
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthGogovanity
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
s := string(data[iNdEx:postIndex])
m.String_ = &s
iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Int64", wireType)
}
var v int64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGogovanity
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
v |= (int64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.Int64 = &v
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Int32", wireType)
}
var v int32
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGogovanity
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
v |= (int32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.Int32 = &v
default:
iNdEx = preIndex
skippy, err := skipGogovanity(data[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthGogovanity
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, data[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipGogovanity(data []byte) (n int, err error) {
l := len(data)
iNdEx := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGogovanity
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGogovanity
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if data[iNdEx-1] < 0x80 {
break
}
}
return iNdEx, nil
case 1:
iNdEx += 8
return iNdEx, nil
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGogovanity
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
iNdEx += length
if length < 0 {
return 0, ErrInvalidLengthGogovanity
}
return iNdEx, nil
case 3:
for {
var innerWire uint64
var start int = iNdEx
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowGogovanity
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
innerWire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
innerWireType := int(innerWire & 0x7)
if innerWireType == 4 {
break
}
next, err := skipGogovanity(data[start:])
if err != nil {
return 0, err
}
iNdEx = start + next
}
return iNdEx, nil
case 4:
return iNdEx, nil
case 5:
iNdEx += 4
return iNdEx, nil
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
}
panic("unreachable")
}
var (
ErrInvalidLengthGogovanity = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowGogovanity = fmt.Errorf("proto: integer overflow")
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment