mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 02:43:36 +00:00
vendor files
This commit is contained in:
526
vendor/github.com/gogo/protobuf/plugin/compare/compare.go
generated
vendored
Normal file
526
vendor/github.com/gogo/protobuf/plugin/compare/compare.go
generated
vendored
Normal file
@ -0,0 +1,526 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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 compare
|
||||
|
||||
import (
|
||||
"github.com/gogo/protobuf/gogoproto"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
|
||||
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
|
||||
"github.com/gogo/protobuf/vanity"
|
||||
)
|
||||
|
||||
type plugin struct {
|
||||
*generator.Generator
|
||||
generator.PluginImports
|
||||
fmtPkg generator.Single
|
||||
bytesPkg generator.Single
|
||||
sortkeysPkg generator.Single
|
||||
protoPkg generator.Single
|
||||
}
|
||||
|
||||
func NewPlugin() *plugin {
|
||||
return &plugin{}
|
||||
}
|
||||
|
||||
func (p *plugin) Name() string {
|
||||
return "compare"
|
||||
}
|
||||
|
||||
func (p *plugin) Init(g *generator.Generator) {
|
||||
p.Generator = g
|
||||
}
|
||||
|
||||
func (p *plugin) Generate(file *generator.FileDescriptor) {
|
||||
p.PluginImports = generator.NewPluginImports(p.Generator)
|
||||
p.fmtPkg = p.NewImport("fmt")
|
||||
p.bytesPkg = p.NewImport("bytes")
|
||||
p.sortkeysPkg = p.NewImport("github.com/gogo/protobuf/sortkeys")
|
||||
p.protoPkg = p.NewImport("github.com/gogo/protobuf/proto")
|
||||
|
||||
for _, msg := range file.Messages() {
|
||||
if msg.DescriptorProto.GetOptions().GetMapEntry() {
|
||||
continue
|
||||
}
|
||||
if gogoproto.HasCompare(file.FileDescriptorProto, msg.DescriptorProto) {
|
||||
p.generateMessage(file, msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *plugin) generateNullableField(fieldname string) {
|
||||
p.P(`if this.`, fieldname, ` != nil && that1.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
p.P(`if *this.`, fieldname, ` != *that1.`, fieldname, `{`)
|
||||
p.In()
|
||||
p.P(`if *this.`, fieldname, ` < *that1.`, fieldname, `{`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`} else if this.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`} else if that1.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
|
||||
func (p *plugin) generateMsgNullAndTypeCheck(ccTypeName string) {
|
||||
p.P(`if that == nil {`)
|
||||
p.In()
|
||||
p.P(`if this == nil {`)
|
||||
p.In()
|
||||
p.P(`return 0`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(``)
|
||||
p.P(`that1, ok := that.(*`, ccTypeName, `)`)
|
||||
p.P(`if !ok {`)
|
||||
p.In()
|
||||
p.P(`that2, ok := that.(`, ccTypeName, `)`)
|
||||
p.P(`if ok {`)
|
||||
p.In()
|
||||
p.P(`that1 = &that2`)
|
||||
p.Out()
|
||||
p.P(`} else {`)
|
||||
p.In()
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`if that1 == nil {`)
|
||||
p.In()
|
||||
p.P(`if this == nil {`)
|
||||
p.In()
|
||||
p.P(`return 0`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`} else if this == nil {`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
|
||||
func (p *plugin) generateField(file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto) {
|
||||
proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
|
||||
fieldname := p.GetOneOfFieldName(message, field)
|
||||
repeated := field.IsRepeated()
|
||||
ctype := gogoproto.IsCustomType(field)
|
||||
nullable := gogoproto.IsNullable(field)
|
||||
// oneof := field.OneofIndex != nil
|
||||
if !repeated {
|
||||
if ctype {
|
||||
if nullable {
|
||||
p.P(`if that1.`, fieldname, ` == nil {`)
|
||||
p.In()
|
||||
p.P(`if this.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`} else if this.`, fieldname, ` == nil {`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`} else if c := this.`, fieldname, `.Compare(*that1.`, fieldname, `); c != 0 {`)
|
||||
} else {
|
||||
p.P(`if c := this.`, fieldname, `.Compare(that1.`, fieldname, `); c != 0 {`)
|
||||
}
|
||||
p.In()
|
||||
p.P(`return c`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else {
|
||||
if field.IsMessage() || p.IsGroup(field) {
|
||||
if nullable {
|
||||
p.P(`if c := this.`, fieldname, `.Compare(that1.`, fieldname, `); c != 0 {`)
|
||||
} else {
|
||||
p.P(`if c := this.`, fieldname, `.Compare(&that1.`, fieldname, `); c != 0 {`)
|
||||
}
|
||||
p.In()
|
||||
p.P(`return c`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if field.IsBytes() {
|
||||
p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `, that1.`, fieldname, `); c != 0 {`)
|
||||
p.In()
|
||||
p.P(`return c`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if field.IsString() {
|
||||
if nullable && !proto3 {
|
||||
p.generateNullableField(fieldname)
|
||||
} else {
|
||||
p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`)
|
||||
p.In()
|
||||
p.P(`if this.`, fieldname, ` < that1.`, fieldname, `{`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
} else if field.IsBool() {
|
||||
if nullable && !proto3 {
|
||||
p.P(`if this.`, fieldname, ` != nil && that1.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
p.P(`if *this.`, fieldname, ` != *that1.`, fieldname, `{`)
|
||||
p.In()
|
||||
p.P(`if !*this.`, fieldname, ` {`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`} else if this.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`} else if that1.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else {
|
||||
p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`)
|
||||
p.In()
|
||||
p.P(`if !this.`, fieldname, ` {`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
} else {
|
||||
if nullable && !proto3 {
|
||||
p.generateNullableField(fieldname)
|
||||
} else {
|
||||
p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`)
|
||||
p.In()
|
||||
p.P(`if this.`, fieldname, ` < that1.`, fieldname, `{`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p.P(`if len(this.`, fieldname, `) != len(that1.`, fieldname, `) {`)
|
||||
p.In()
|
||||
p.P(`if len(this.`, fieldname, `) < len(that1.`, fieldname, `) {`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`for i := range this.`, fieldname, ` {`)
|
||||
p.In()
|
||||
if ctype {
|
||||
p.P(`if c := this.`, fieldname, `[i].Compare(that1.`, fieldname, `[i]); c != 0 {`)
|
||||
p.In()
|
||||
p.P(`return c`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else {
|
||||
if p.IsMap(field) {
|
||||
m := p.GoMapType(nil, field)
|
||||
valuegoTyp, _ := p.GoType(nil, m.ValueField)
|
||||
valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField)
|
||||
nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp)
|
||||
|
||||
mapValue := m.ValueAliasField
|
||||
if mapValue.IsMessage() || p.IsGroup(mapValue) {
|
||||
if nullable && valuegoTyp == valuegoAliasTyp {
|
||||
p.P(`if c := this.`, fieldname, `[i].Compare(that1.`, fieldname, `[i]); c != 0 {`)
|
||||
} else {
|
||||
// Compare() has a pointer receiver, but map value is a value type
|
||||
a := `this.` + fieldname + `[i]`
|
||||
b := `that1.` + fieldname + `[i]`
|
||||
if valuegoTyp != valuegoAliasTyp {
|
||||
// cast back to the type that has the generated methods on it
|
||||
a = `(` + valuegoTyp + `)(` + a + `)`
|
||||
b = `(` + valuegoTyp + `)(` + b + `)`
|
||||
}
|
||||
p.P(`a := `, a)
|
||||
p.P(`b := `, b)
|
||||
if nullable {
|
||||
p.P(`if c := a.Compare(b); c != 0 {`)
|
||||
} else {
|
||||
p.P(`if c := (&a).Compare(&b); c != 0 {`)
|
||||
}
|
||||
}
|
||||
p.In()
|
||||
p.P(`return c`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if mapValue.IsBytes() {
|
||||
p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `[i], that1.`, fieldname, `[i]); c != 0 {`)
|
||||
p.In()
|
||||
p.P(`return c`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if mapValue.IsString() {
|
||||
p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
|
||||
p.In()
|
||||
p.P(`if this.`, fieldname, `[i] < that1.`, fieldname, `[i] {`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else {
|
||||
p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
|
||||
p.In()
|
||||
p.P(`if this.`, fieldname, `[i] < that1.`, fieldname, `[i] {`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
} else if field.IsMessage() || p.IsGroup(field) {
|
||||
if nullable {
|
||||
p.P(`if c := this.`, fieldname, `[i].Compare(that1.`, fieldname, `[i]); c != 0 {`)
|
||||
p.In()
|
||||
p.P(`return c`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else {
|
||||
p.P(`if c := this.`, fieldname, `[i].Compare(&that1.`, fieldname, `[i]); c != 0 {`)
|
||||
p.In()
|
||||
p.P(`return c`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
} else if field.IsBytes() {
|
||||
p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `[i], that1.`, fieldname, `[i]); c != 0 {`)
|
||||
p.In()
|
||||
p.P(`return c`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if field.IsString() {
|
||||
p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
|
||||
p.In()
|
||||
p.P(`if this.`, fieldname, `[i] < that1.`, fieldname, `[i] {`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if field.IsBool() {
|
||||
p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
|
||||
p.In()
|
||||
p.P(`if !this.`, fieldname, `[i] {`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else {
|
||||
p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
|
||||
p.In()
|
||||
p.P(`if this.`, fieldname, `[i] < that1.`, fieldname, `[i] {`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *plugin) generateMessage(file *generator.FileDescriptor, message *generator.Descriptor) {
|
||||
ccTypeName := generator.CamelCaseSlice(message.TypeName())
|
||||
p.P(`func (this *`, ccTypeName, `) Compare(that interface{}) int {`)
|
||||
p.In()
|
||||
p.generateMsgNullAndTypeCheck(ccTypeName)
|
||||
oneofs := make(map[string]struct{})
|
||||
|
||||
for _, field := range message.Field {
|
||||
oneof := field.OneofIndex != nil
|
||||
if oneof {
|
||||
fieldname := p.GetFieldName(message, field)
|
||||
if _, ok := oneofs[fieldname]; ok {
|
||||
continue
|
||||
} else {
|
||||
oneofs[fieldname] = struct{}{}
|
||||
}
|
||||
p.P(`if that1.`, fieldname, ` == nil {`)
|
||||
p.In()
|
||||
p.P(`if this.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`} else if this.`, fieldname, ` == nil {`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`} else if c := this.`, fieldname, `.Compare(that1.`, fieldname, `); c != 0 {`)
|
||||
p.In()
|
||||
p.P(`return c`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else {
|
||||
p.generateField(file, message, field)
|
||||
}
|
||||
}
|
||||
if message.DescriptorProto.HasExtension() {
|
||||
if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
p.P(`thismap := `, p.protoPkg.Use(), `.GetUnsafeExtensionsMap(this)`)
|
||||
p.P(`thatmap := `, p.protoPkg.Use(), `.GetUnsafeExtensionsMap(that1)`)
|
||||
p.P(`extkeys := make([]int32, 0, len(thismap)+len(thatmap))`)
|
||||
p.P(`for k, _ := range thismap {`)
|
||||
p.In()
|
||||
p.P(`extkeys = append(extkeys, k)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`for k, _ := range thatmap {`)
|
||||
p.In()
|
||||
p.P(`if _, ok := thismap[k]; !ok {`)
|
||||
p.In()
|
||||
p.P(`extkeys = append(extkeys, k)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(p.sortkeysPkg.Use(), `.Int32s(extkeys)`)
|
||||
p.P(`for _, k := range extkeys {`)
|
||||
p.In()
|
||||
p.P(`if v, ok := thismap[k]; ok {`)
|
||||
p.In()
|
||||
p.P(`if v2, ok := thatmap[k]; ok {`)
|
||||
p.In()
|
||||
p.P(`if c := v.Compare(&v2); c != 0 {`)
|
||||
p.In()
|
||||
p.P(`return c`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`} else {`)
|
||||
p.In()
|
||||
p.P(`return 1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`} else {`)
|
||||
p.In()
|
||||
p.P(`return -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else {
|
||||
fieldname := "XXX_extensions"
|
||||
p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `, that1.`, fieldname, `); c != 0 {`)
|
||||
p.In()
|
||||
p.P(`return c`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
fieldname := "XXX_unrecognized"
|
||||
p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `, that1.`, fieldname, `); c != 0 {`)
|
||||
p.In()
|
||||
p.P(`return c`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
p.P(`return 0`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
|
||||
//Generate Compare methods for oneof fields
|
||||
m := proto.Clone(message.DescriptorProto).(*descriptor.DescriptorProto)
|
||||
for _, field := range m.Field {
|
||||
oneof := field.OneofIndex != nil
|
||||
if !oneof {
|
||||
continue
|
||||
}
|
||||
ccTypeName := p.OneOfTypeName(message, field)
|
||||
p.P(`func (this *`, ccTypeName, `) Compare(that interface{}) int {`)
|
||||
p.In()
|
||||
|
||||
p.generateMsgNullAndTypeCheck(ccTypeName)
|
||||
vanity.TurnOffNullableForNativeTypes(field)
|
||||
p.generateField(file, message, field)
|
||||
|
||||
p.P(`return 0`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
generator.RegisterPlugin(NewPlugin())
|
||||
}
|
118
vendor/github.com/gogo/protobuf/plugin/compare/comparetest.go
generated
vendored
Normal file
118
vendor/github.com/gogo/protobuf/plugin/compare/comparetest.go
generated
vendored
Normal file
@ -0,0 +1,118 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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 compare
|
||||
|
||||
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")
|
||||
unsafePkg := imports.NewImport("unsafe")
|
||||
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.HasCompare(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
continue
|
||||
}
|
||||
if message.DescriptorProto.GetOptions().GetMapEntry() {
|
||||
continue
|
||||
}
|
||||
|
||||
if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
used = true
|
||||
hasUnsafe := gogoproto.IsUnsafeMarshaler(file.FileDescriptorProto, message.DescriptorProto) ||
|
||||
gogoproto.IsUnsafeUnmarshaler(file.FileDescriptorProto, message.DescriptorProto)
|
||||
p.P(`func Test`, ccTypeName, `Compare(t *`, testingPkg.Use(), `.T) {`)
|
||||
p.In()
|
||||
if hasUnsafe {
|
||||
p.P(`var bigendian uint32 = 0x01020304`)
|
||||
p.P(`if *(*byte)(`, unsafePkg.Use(), `.Pointer(&bigendian)) == 1 {`)
|
||||
p.In()
|
||||
p.P(`t.Skip("unsafe does not work on big endian architectures")`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
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 c := p.Compare(msg); c != 0 {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("%#v !Compare %#v, since %d", msg, p, c)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`p2 := NewPopulated`, ccTypeName, `(popr, false)`)
|
||||
p.P(`c := p.Compare(p2)`)
|
||||
p.P(`c2 := p2.Compare(p)`)
|
||||
p.P(`if c != (-1 * c2) {`)
|
||||
p.In()
|
||||
p.P(`t.Errorf("p.Compare(p2) = %d", c)`)
|
||||
p.P(`t.Errorf("p2.Compare(p) = %d", c2)`)
|
||||
p.P(`t.Errorf("p = %#v", p)`)
|
||||
p.P(`t.Errorf("p2 = %#v", p2)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
|
||||
}
|
||||
return used
|
||||
}
|
||||
|
||||
func init() {
|
||||
testgen.RegisterTestPlugin(NewTest)
|
||||
}
|
133
vendor/github.com/gogo/protobuf/plugin/defaultcheck/defaultcheck.go
generated
vendored
Normal file
133
vendor/github.com/gogo/protobuf/plugin/defaultcheck/defaultcheck.go
generated
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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())
|
||||
}
|
201
vendor/github.com/gogo/protobuf/plugin/description/description.go
generated
vendored
Normal file
201
vendor/github.com/gogo/protobuf/plugin/description/description.go
generated
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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 (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"github.com/gogo/protobuf/gogoproto"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
|
||||
"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 "description"
|
||||
}
|
||||
|
||||
func (p *plugin) Init(g *generator.Generator) {
|
||||
p.Generator = g
|
||||
}
|
||||
|
||||
func (p *plugin) Generate(file *generator.FileDescriptor) {
|
||||
used := false
|
||||
localName := generator.FileName(file)
|
||||
|
||||
p.PluginImports = generator.NewPluginImports(p.Generator)
|
||||
descriptorPkg := p.NewImport("github.com/gogo/protobuf/protoc-gen-gogo/descriptor")
|
||||
protoPkg := p.NewImport("github.com/gogo/protobuf/proto")
|
||||
gzipPkg := p.NewImport("compress/gzip")
|
||||
bytesPkg := p.NewImport("bytes")
|
||||
ioutilPkg := p.NewImport("io/ioutil")
|
||||
|
||||
for _, message := range file.Messages() {
|
||||
if !gogoproto.HasDescription(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
continue
|
||||
}
|
||||
if message.DescriptorProto.GetOptions().GetMapEntry() {
|
||||
continue
|
||||
}
|
||||
used = true
|
||||
ccTypeName := generator.CamelCaseSlice(message.TypeName())
|
||||
p.P(`func (this *`, ccTypeName, `) Description() (desc *`, descriptorPkg.Use(), `.FileDescriptorSet) {`)
|
||||
p.In()
|
||||
p.P(`return `, localName, `Description()`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
|
||||
if used {
|
||||
|
||||
p.P(`func `, localName, `Description() (desc *`, descriptorPkg.Use(), `.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
|
||||
}
|
||||
b, err := proto.Marshal(p.Generator.AllFiles())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i, f := range p.Generator.AllFiles().GetFile() {
|
||||
f.SourceCodeInfo = ss[i]
|
||||
}
|
||||
p.P(`d := &`, descriptorPkg.Use(), `.FileDescriptorSet{}`)
|
||||
var buf bytes.Buffer
|
||||
w, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression)
|
||||
w.Write(b)
|
||||
w.Close()
|
||||
b = buf.Bytes()
|
||||
p.P("var gzipped = []byte{")
|
||||
p.In()
|
||||
p.P("// ", len(b), " bytes of a gzipped FileDescriptorSet")
|
||||
for len(b) > 0 {
|
||||
n := 16
|
||||
if n > len(b) {
|
||||
n = len(b)
|
||||
}
|
||||
|
||||
s := ""
|
||||
for _, c := range b[:n] {
|
||||
s += fmt.Sprintf("0x%02x,", c)
|
||||
}
|
||||
p.P(s)
|
||||
|
||||
b = b[n:]
|
||||
}
|
||||
p.Out()
|
||||
p.P("}")
|
||||
p.P(`r := `, bytesPkg.Use(), `.NewReader(gzipped)`)
|
||||
p.P(`gzipr, err := `, gzipPkg.Use(), `.NewReader(r)`)
|
||||
p.P(`if err != nil {`)
|
||||
p.In()
|
||||
p.P(`panic(err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`ungzipped, err := `, ioutilPkg.Use(), `.ReadAll(gzipr)`)
|
||||
p.P(`if err != nil {`)
|
||||
p.In()
|
||||
p.P(`panic(err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`if err := `, protoPkg.Use(), `.Unmarshal(ungzipped, d); err != nil {`)
|
||||
p.In()
|
||||
p.P(`panic(err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return d`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
generator.RegisterPlugin(NewPlugin())
|
||||
}
|
73
vendor/github.com/gogo/protobuf/plugin/description/descriptiontest.go
generated
vendored
Normal file
73
vendor/github.com/gogo/protobuf/plugin/description/descriptiontest.go
generated
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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)
|
||||
}
|
199
vendor/github.com/gogo/protobuf/plugin/embedcheck/embedcheck.go
generated
vendored
Normal file
199
vendor/github.com/gogo/protobuf/plugin/embedcheck/embedcheck.go
generated
vendored
Normal file
@ -0,0 +1,199 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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,
|
||||
"protosizer": gogoproto.IsProtoSizer,
|
||||
},
|
||||
{
|
||||
"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())
|
||||
}
|
104
vendor/github.com/gogo/protobuf/plugin/enumstringer/enumstringer.go
generated
vendored
Normal file
104
vendor/github.com/gogo/protobuf/plugin/enumstringer/enumstringer.go
generated
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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("Go enum stringer conflicts with new enumstringer plugin: please use gogoproto.goproto_enum_stringer or gogoproto.goproto_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())
|
||||
}
|
645
vendor/github.com/gogo/protobuf/plugin/equal/equal.go
generated
vendored
Normal file
645
vendor/github.com/gogo/protobuf/plugin/equal/equal.go
generated
vendored
Normal file
@ -0,0 +1,645 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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 equal plugin generates an Equal and a VerboseEqual method for each message.
|
||||
These equal methods are quite obvious.
|
||||
The only difference is that VerboseEqual returns a non nil error if it is not equal.
|
||||
This error contains more detail on exactly which part of the message was not equal to the other message.
|
||||
The idea is that this is useful for debugging.
|
||||
|
||||
Equal is enabled using the following extensions:
|
||||
|
||||
- equal
|
||||
- equal_all
|
||||
|
||||
While VerboseEqual is enable dusing the following extensions:
|
||||
|
||||
- verbose_equal
|
||||
- verbose_equal_all
|
||||
|
||||
The equal 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:
|
||||
|
||||
option (gogoproto.equal_all) = true;
|
||||
option (gogoproto.verbose_equal_all) = true;
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
given to the equal plugin, will generate the following code:
|
||||
|
||||
func (this *B) VerboseEqual(that interface{}) error {
|
||||
if that == nil {
|
||||
if this == nil {
|
||||
return nil
|
||||
}
|
||||
return fmt2.Errorf("that == nil && this != nil")
|
||||
}
|
||||
|
||||
that1, ok := that.(*B)
|
||||
if !ok {
|
||||
return fmt2.Errorf("that is not of type *B")
|
||||
}
|
||||
if that1 == nil {
|
||||
if this == nil {
|
||||
return nil
|
||||
}
|
||||
return fmt2.Errorf("that is type *B but is nil && this != nil")
|
||||
} else if this == nil {
|
||||
return fmt2.Errorf("that is type *B but is not nil && this == nil")
|
||||
}
|
||||
if !this.A.Equal(&that1.A) {
|
||||
return fmt2.Errorf("A this(%v) Not Equal that(%v)", this.A, that1.A)
|
||||
}
|
||||
if len(this.G) != len(that1.G) {
|
||||
return fmt2.Errorf("G this(%v) Not Equal that(%v)", len(this.G), len(that1.G))
|
||||
}
|
||||
for i := range this.G {
|
||||
if !this.G[i].Equal(that1.G[i]) {
|
||||
return fmt2.Errorf("G this[%v](%v) Not Equal that[%v](%v)", i, this.G[i], i, that1.G[i])
|
||||
}
|
||||
}
|
||||
if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
|
||||
return fmt2.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *B) Equal(that interface{}) bool {
|
||||
if that == nil {
|
||||
if this == nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
that1, ok := that.(*B)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if that1 == nil {
|
||||
if this == nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
} else if this == nil {
|
||||
return false
|
||||
}
|
||||
if !this.A.Equal(&that1.A) {
|
||||
return false
|
||||
}
|
||||
if len(this.G) != len(that1.G) {
|
||||
return false
|
||||
}
|
||||
for i := range this.G {
|
||||
if !this.G[i].Equal(that1.G[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
and the following test code:
|
||||
|
||||
func TestBVerboseEqual(t *testing8.T) {
|
||||
popr := math_rand8.New(math_rand8.NewSource(time8.Now().UnixNano()))
|
||||
p := NewPopulatedB(popr, false)
|
||||
dAtA, err := github_com_gogo_protobuf_proto2.Marshal(p)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
msg := &B{}
|
||||
if err := github_com_gogo_protobuf_proto2.Unmarshal(dAtA, msg); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := p.VerboseEqual(msg); err != nil {
|
||||
t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err)
|
||||
}
|
||||
|
||||
*/
|
||||
package equal
|
||||
|
||||
import (
|
||||
"github.com/gogo/protobuf/gogoproto"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
|
||||
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
|
||||
"github.com/gogo/protobuf/vanity"
|
||||
)
|
||||
|
||||
type plugin struct {
|
||||
*generator.Generator
|
||||
generator.PluginImports
|
||||
fmtPkg generator.Single
|
||||
bytesPkg generator.Single
|
||||
protoPkg generator.Single
|
||||
}
|
||||
|
||||
func NewPlugin() *plugin {
|
||||
return &plugin{}
|
||||
}
|
||||
|
||||
func (p *plugin) Name() string {
|
||||
return "equal"
|
||||
}
|
||||
|
||||
func (p *plugin) Init(g *generator.Generator) {
|
||||
p.Generator = g
|
||||
}
|
||||
|
||||
func (p *plugin) Generate(file *generator.FileDescriptor) {
|
||||
p.PluginImports = generator.NewPluginImports(p.Generator)
|
||||
p.fmtPkg = p.NewImport("fmt")
|
||||
p.bytesPkg = p.NewImport("bytes")
|
||||
p.protoPkg = p.NewImport("github.com/gogo/protobuf/proto")
|
||||
|
||||
for _, msg := range file.Messages() {
|
||||
if msg.DescriptorProto.GetOptions().GetMapEntry() {
|
||||
continue
|
||||
}
|
||||
if gogoproto.HasVerboseEqual(file.FileDescriptorProto, msg.DescriptorProto) {
|
||||
p.generateMessage(file, msg, true)
|
||||
}
|
||||
if gogoproto.HasEqual(file.FileDescriptorProto, msg.DescriptorProto) {
|
||||
p.generateMessage(file, msg, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *plugin) generateNullableField(fieldname string, verbose bool) {
|
||||
p.P(`if this.`, fieldname, ` != nil && that1.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
p.P(`if *this.`, fieldname, ` != *that1.`, fieldname, `{`)
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", *this.`, fieldname, `, *that1.`, fieldname, `)`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`} else if this.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("this.`, fieldname, ` == nil && that.`, fieldname, ` != nil")`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`} else if that1.`, fieldname, ` != nil {`)
|
||||
}
|
||||
|
||||
func (p *plugin) generateMsgNullAndTypeCheck(ccTypeName string, verbose bool) {
|
||||
p.P(`if that == nil {`)
|
||||
p.In()
|
||||
p.P(`if this == nil {`)
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return nil`)
|
||||
} else {
|
||||
p.P(`return true`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("that == nil && this != nil")`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(``)
|
||||
p.P(`that1, ok := that.(*`, ccTypeName, `)`)
|
||||
p.P(`if !ok {`)
|
||||
p.In()
|
||||
p.P(`that2, ok := that.(`, ccTypeName, `)`)
|
||||
p.P(`if ok {`)
|
||||
p.In()
|
||||
p.P(`that1 = &that2`)
|
||||
p.Out()
|
||||
p.P(`} else {`)
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("that is not of type *`, ccTypeName, `")`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`if that1 == nil {`)
|
||||
p.In()
|
||||
p.P(`if this == nil {`)
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return nil`)
|
||||
} else {
|
||||
p.P(`return true`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("that is type *`, ccTypeName, ` but is nil && this != nil")`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`} else if this == nil {`)
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("that is type *`, ccTypeName, ` but is not nil && this == nil")`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
|
||||
func (p *plugin) generateField(file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto, verbose bool) {
|
||||
proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
|
||||
fieldname := p.GetOneOfFieldName(message, field)
|
||||
repeated := field.IsRepeated()
|
||||
ctype := gogoproto.IsCustomType(field)
|
||||
nullable := gogoproto.IsNullable(field)
|
||||
isDuration := gogoproto.IsStdDuration(field)
|
||||
isTimestamp := gogoproto.IsStdTime(field)
|
||||
// oneof := field.OneofIndex != nil
|
||||
if !repeated {
|
||||
if ctype || isTimestamp {
|
||||
if nullable {
|
||||
p.P(`if that1.`, fieldname, ` == nil {`)
|
||||
p.In()
|
||||
p.P(`if this.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("this.`, fieldname, ` != nil && that1.`, fieldname, ` == nil")`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`} else if !this.`, fieldname, `.Equal(*that1.`, fieldname, `) {`)
|
||||
} else {
|
||||
p.P(`if !this.`, fieldname, `.Equal(that1.`, fieldname, `) {`)
|
||||
}
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if isDuration {
|
||||
if nullable {
|
||||
p.generateNullableField(fieldname, verbose)
|
||||
} else {
|
||||
p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`)
|
||||
}
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else {
|
||||
if field.IsMessage() || p.IsGroup(field) {
|
||||
if nullable {
|
||||
p.P(`if !this.`, fieldname, `.Equal(that1.`, fieldname, `) {`)
|
||||
} else {
|
||||
p.P(`if !this.`, fieldname, `.Equal(&that1.`, fieldname, `) {`)
|
||||
}
|
||||
} else if field.IsBytes() {
|
||||
p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `, that1.`, fieldname, `) {`)
|
||||
} else if field.IsString() {
|
||||
if nullable && !proto3 {
|
||||
p.generateNullableField(fieldname, verbose)
|
||||
} else {
|
||||
p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`)
|
||||
}
|
||||
} else {
|
||||
if nullable && !proto3 {
|
||||
p.generateNullableField(fieldname, verbose)
|
||||
} else {
|
||||
p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`)
|
||||
}
|
||||
}
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
} else {
|
||||
p.P(`if len(this.`, fieldname, `) != len(that1.`, fieldname, `) {`)
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", len(this.`, fieldname, `), len(that1.`, fieldname, `))`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`for i := range this.`, fieldname, ` {`)
|
||||
p.In()
|
||||
if ctype && !p.IsMap(field) {
|
||||
p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`)
|
||||
} else if isTimestamp {
|
||||
if nullable {
|
||||
p.P(`if !this.`, fieldname, `[i].Equal(*that1.`, fieldname, `[i]) {`)
|
||||
} else {
|
||||
p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`)
|
||||
}
|
||||
} else if isDuration {
|
||||
if nullable {
|
||||
p.P(`if dthis, dthat := this.`, fieldname, `[i], that1.`, fieldname, `[i]; (dthis != nil && dthat != nil && *dthis != *dthat) || (dthis != nil && dthat == nil) || (dthis == nil && dthat != nil) {`)
|
||||
} else {
|
||||
p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
|
||||
}
|
||||
} else {
|
||||
if p.IsMap(field) {
|
||||
m := p.GoMapType(nil, field)
|
||||
valuegoTyp, _ := p.GoType(nil, m.ValueField)
|
||||
valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField)
|
||||
nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp)
|
||||
|
||||
mapValue := m.ValueAliasField
|
||||
if mapValue.IsMessage() || p.IsGroup(mapValue) {
|
||||
if nullable && valuegoTyp == valuegoAliasTyp {
|
||||
p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`)
|
||||
} else {
|
||||
// Equal() has a pointer receiver, but map value is a value type
|
||||
a := `this.` + fieldname + `[i]`
|
||||
b := `that1.` + fieldname + `[i]`
|
||||
if valuegoTyp != valuegoAliasTyp {
|
||||
// cast back to the type that has the generated methods on it
|
||||
a = `(` + valuegoTyp + `)(` + a + `)`
|
||||
b = `(` + valuegoTyp + `)(` + b + `)`
|
||||
}
|
||||
p.P(`a := `, a)
|
||||
p.P(`b := `, b)
|
||||
if nullable {
|
||||
p.P(`if !a.Equal(b) {`)
|
||||
} else {
|
||||
p.P(`if !(&a).Equal(&b) {`)
|
||||
}
|
||||
}
|
||||
} else if mapValue.IsBytes() {
|
||||
if ctype {
|
||||
if nullable {
|
||||
p.P(`if !this.`, fieldname, `[i].Equal(*that1.`, fieldname, `[i]) { //nullable`)
|
||||
} else {
|
||||
p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) { //not nullable`)
|
||||
}
|
||||
} else {
|
||||
p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `[i], that1.`, fieldname, `[i]) {`)
|
||||
}
|
||||
} else if mapValue.IsString() {
|
||||
p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
|
||||
} else {
|
||||
p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
|
||||
}
|
||||
} else if field.IsMessage() || p.IsGroup(field) {
|
||||
if nullable {
|
||||
p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`)
|
||||
} else {
|
||||
p.P(`if !this.`, fieldname, `[i].Equal(&that1.`, fieldname, `[i]) {`)
|
||||
}
|
||||
} else if field.IsBytes() {
|
||||
p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `[i], that1.`, fieldname, `[i]) {`)
|
||||
} else if field.IsString() {
|
||||
p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
|
||||
} else {
|
||||
p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
|
||||
}
|
||||
}
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this[%v](%v) Not Equal that[%v](%v)", i, this.`, fieldname, `[i], i, that1.`, fieldname, `[i])`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *plugin) generateMessage(file *generator.FileDescriptor, message *generator.Descriptor, verbose bool) {
|
||||
ccTypeName := generator.CamelCaseSlice(message.TypeName())
|
||||
if verbose {
|
||||
p.P(`func (this *`, ccTypeName, `) VerboseEqual(that interface{}) error {`)
|
||||
} else {
|
||||
p.P(`func (this *`, ccTypeName, `) Equal(that interface{}) bool {`)
|
||||
}
|
||||
p.In()
|
||||
p.generateMsgNullAndTypeCheck(ccTypeName, verbose)
|
||||
oneofs := make(map[string]struct{})
|
||||
|
||||
for _, field := range message.Field {
|
||||
oneof := field.OneofIndex != nil
|
||||
if oneof {
|
||||
fieldname := p.GetFieldName(message, field)
|
||||
if _, ok := oneofs[fieldname]; ok {
|
||||
continue
|
||||
} else {
|
||||
oneofs[fieldname] = struct{}{}
|
||||
}
|
||||
p.P(`if that1.`, fieldname, ` == nil {`)
|
||||
p.In()
|
||||
p.P(`if this.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("this.`, fieldname, ` != nil && that1.`, fieldname, ` == nil")`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`} else if this.`, fieldname, ` == nil {`)
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("this.`, fieldname, ` == nil && that1.`, fieldname, ` != nil")`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
if verbose {
|
||||
p.P(`} else if err := this.`, fieldname, `.VerboseEqual(that1.`, fieldname, `); err != nil {`)
|
||||
} else {
|
||||
p.P(`} else if !this.`, fieldname, `.Equal(that1.`, fieldname, `) {`)
|
||||
}
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return err`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else {
|
||||
p.generateField(file, message, field, verbose)
|
||||
}
|
||||
}
|
||||
if message.DescriptorProto.HasExtension() {
|
||||
if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
fieldname := "XXX_InternalExtensions"
|
||||
p.P(`thismap := `, p.protoPkg.Use(), `.GetUnsafeExtensionsMap(this)`)
|
||||
p.P(`thatmap := `, p.protoPkg.Use(), `.GetUnsafeExtensionsMap(that1)`)
|
||||
p.P(`for k, v := range thismap {`)
|
||||
p.In()
|
||||
p.P(`if v2, ok := thatmap[k]; ok {`)
|
||||
p.In()
|
||||
p.P(`if !v.Equal(&v2) {`)
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this[%v](%v) Not Equal that[%v](%v)", k, thismap[k], k, thatmap[k])`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`} else {`)
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, `[%v] Not In that", k)`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
|
||||
p.P(`for k, _ := range thatmap {`)
|
||||
p.In()
|
||||
p.P(`if _, ok := thismap[k]; !ok {`)
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, `[%v] Not In this", k)`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else {
|
||||
fieldname := "XXX_extensions"
|
||||
p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `, that1.`, fieldname, `) {`)
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
fieldname := "XXX_unrecognized"
|
||||
p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `, that1.`, fieldname, `) {`)
|
||||
p.In()
|
||||
if verbose {
|
||||
p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`)
|
||||
} else {
|
||||
p.P(`return false`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
if verbose {
|
||||
p.P(`return nil`)
|
||||
} else {
|
||||
p.P(`return true`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
|
||||
//Generate Equal methods for oneof fields
|
||||
m := proto.Clone(message.DescriptorProto).(*descriptor.DescriptorProto)
|
||||
for _, field := range m.Field {
|
||||
oneof := field.OneofIndex != nil
|
||||
if !oneof {
|
||||
continue
|
||||
}
|
||||
ccTypeName := p.OneOfTypeName(message, field)
|
||||
if verbose {
|
||||
p.P(`func (this *`, ccTypeName, `) VerboseEqual(that interface{}) error {`)
|
||||
} else {
|
||||
p.P(`func (this *`, ccTypeName, `) Equal(that interface{}) bool {`)
|
||||
}
|
||||
p.In()
|
||||
|
||||
p.generateMsgNullAndTypeCheck(ccTypeName, verbose)
|
||||
vanity.TurnOffNullableForNativeTypes(field)
|
||||
p.generateField(file, message, field, verbose)
|
||||
|
||||
if verbose {
|
||||
p.P(`return nil`)
|
||||
} else {
|
||||
p.P(`return true`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
generator.RegisterPlugin(NewPlugin())
|
||||
}
|
109
vendor/github.com/gogo/protobuf/plugin/equal/equaltest.go
generated
vendored
Normal file
109
vendor/github.com/gogo/protobuf/plugin/equal/equaltest.go
generated
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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")
|
||||
unsafePkg := imports.NewImport("unsafe")
|
||||
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
|
||||
hasUnsafe := gogoproto.IsUnsafeMarshaler(file.FileDescriptorProto, message.DescriptorProto) ||
|
||||
gogoproto.IsUnsafeUnmarshaler(file.FileDescriptorProto, message.DescriptorProto)
|
||||
p.P(`func Test`, ccTypeName, `VerboseEqual(t *`, testingPkg.Use(), `.T) {`)
|
||||
p.In()
|
||||
if hasUnsafe {
|
||||
if hasUnsafe {
|
||||
p.P(`var bigendian uint32 = 0x01020304`)
|
||||
p.P(`if *(*byte)(`, unsafePkg.Use(), `.Pointer(&bigendian)) == 1 {`)
|
||||
p.In()
|
||||
p.P(`t.Skip("unsafe does not work on big endian architectures")`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
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)
|
||||
}
|
233
vendor/github.com/gogo/protobuf/plugin/face/face.go
generated
vendored
Normal file
233
vendor/github.com/gogo/protobuf/plugin/face/face.go
generated
vendored
Normal file
@ -0,0 +1,233 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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 p.IsMap(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())
|
||||
}
|
82
vendor/github.com/gogo/protobuf/plugin/face/facetest.go
generated
vendored
Normal file
82
vendor/github.com/gogo/protobuf/plugin/face/facetest.go
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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)
|
||||
}
|
386
vendor/github.com/gogo/protobuf/plugin/gostring/gostring.go
generated
vendored
Normal file
386
vendor/github.com/gogo/protobuf/plugin/gostring/gostring.go
generated
vendored
Normal file
@ -0,0 +1,386 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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 gostring plugin generates a GoString method for each message.
|
||||
The GoString method is called whenever you use a fmt.Printf as such:
|
||||
|
||||
fmt.Printf("%#v", mymessage)
|
||||
|
||||
or whenever you actually call GoString()
|
||||
The output produced by the GoString method can be copied from the output into code and used to set a variable.
|
||||
It is totally valid Go Code and is populated exactly as the struct that was printed out.
|
||||
|
||||
It is enabled by the following extensions:
|
||||
|
||||
- gostring
|
||||
- gostring_all
|
||||
|
||||
The gostring 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:
|
||||
|
||||
option (gogoproto.gostring_all) = true;
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
given to the gostring plugin, will generate the following code:
|
||||
|
||||
func (this *A) GoString() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings1.Join([]string{`&test.A{` + `Description:` + fmt1.Sprintf("%#v", this.Description), `Number:` + fmt1.Sprintf("%#v", this.Number), `Id:` + fmt1.Sprintf("%#v", this.Id), `XXX_unrecognized:` + fmt1.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
|
||||
return s
|
||||
}
|
||||
|
||||
and the following test code:
|
||||
|
||||
func TestAGoString(t *testing6.T) {
|
||||
popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano()))
|
||||
p := NewPopulatedA(popr, false)
|
||||
s1 := p.GoString()
|
||||
s2 := fmt2.Sprintf("%#v", p)
|
||||
if s1 != s2 {
|
||||
t.Fatalf("GoString want %v got %v", s1, s2)
|
||||
}
|
||||
_, err := go_parser.ParseExpr(s1)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
Typically fmt.Printf("%#v") will stop to print when it reaches a pointer and
|
||||
not print their values, while the generated GoString method will always print all values, recursively.
|
||||
|
||||
*/
|
||||
package gostring
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gogo/protobuf/gogoproto"
|
||||
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
|
||||
)
|
||||
|
||||
type gostring struct {
|
||||
*generator.Generator
|
||||
generator.PluginImports
|
||||
atleastOne bool
|
||||
localName string
|
||||
overwrite bool
|
||||
}
|
||||
|
||||
func NewGoString() *gostring {
|
||||
return &gostring{}
|
||||
}
|
||||
|
||||
func (p *gostring) Name() string {
|
||||
return "gostring"
|
||||
}
|
||||
|
||||
func (p *gostring) Overwrite() {
|
||||
p.overwrite = true
|
||||
}
|
||||
|
||||
func (p *gostring) Init(g *generator.Generator) {
|
||||
p.Generator = g
|
||||
}
|
||||
|
||||
func (p *gostring) Generate(file *generator.FileDescriptor) {
|
||||
proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
|
||||
p.PluginImports = generator.NewPluginImports(p.Generator)
|
||||
p.atleastOne = false
|
||||
|
||||
p.localName = generator.FileName(file)
|
||||
|
||||
fmtPkg := p.NewImport("fmt")
|
||||
stringsPkg := p.NewImport("strings")
|
||||
protoPkg := p.NewImport("github.com/gogo/protobuf/proto")
|
||||
if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
|
||||
protoPkg = p.NewImport("github.com/golang/protobuf/proto")
|
||||
}
|
||||
sortPkg := p.NewImport("sort")
|
||||
strconvPkg := p.NewImport("strconv")
|
||||
reflectPkg := p.NewImport("reflect")
|
||||
sortKeysPkg := p.NewImport("github.com/gogo/protobuf/sortkeys")
|
||||
|
||||
extensionToGoStringUsed := false
|
||||
for _, message := range file.Messages() {
|
||||
if !p.overwrite && !gogoproto.HasGoString(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
continue
|
||||
}
|
||||
if message.DescriptorProto.GetOptions().GetMapEntry() {
|
||||
continue
|
||||
}
|
||||
p.atleastOne = true
|
||||
packageName := file.PackageName()
|
||||
|
||||
ccTypeName := generator.CamelCaseSlice(message.TypeName())
|
||||
p.P(`func (this *`, ccTypeName, `) GoString() string {`)
|
||||
p.In()
|
||||
p.P(`if this == nil {`)
|
||||
p.In()
|
||||
p.P(`return "nil"`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
|
||||
p.P(`s := make([]string, 0, `, strconv.Itoa(len(message.Field)+4), `)`)
|
||||
p.P(`s = append(s, "&`, packageName, ".", ccTypeName, `{")`)
|
||||
|
||||
oneofs := make(map[string]struct{})
|
||||
for _, field := range message.Field {
|
||||
nullable := gogoproto.IsNullable(field)
|
||||
repeated := field.IsRepeated()
|
||||
fieldname := p.GetFieldName(message, field)
|
||||
oneof := field.OneofIndex != nil
|
||||
if oneof {
|
||||
if _, ok := oneofs[fieldname]; ok {
|
||||
continue
|
||||
} else {
|
||||
oneofs[fieldname] = struct{}{}
|
||||
}
|
||||
p.P(`if this.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `) + ",\n")`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if p.IsMap(field) {
|
||||
m := p.GoMapType(nil, field)
|
||||
mapgoTyp, keyField, keyAliasField := m.GoType, m.KeyField, m.KeyAliasField
|
||||
keysName := `keysFor` + fieldname
|
||||
keygoTyp, _ := p.GoType(nil, keyField)
|
||||
keygoTyp = strings.Replace(keygoTyp, "*", "", 1)
|
||||
keygoAliasTyp, _ := p.GoType(nil, keyAliasField)
|
||||
keygoAliasTyp = strings.Replace(keygoAliasTyp, "*", "", 1)
|
||||
keyCapTyp := generator.CamelCase(keygoTyp)
|
||||
p.P(keysName, ` := make([]`, keygoTyp, `, 0, len(this.`, fieldname, `))`)
|
||||
p.P(`for k, _ := range this.`, fieldname, ` {`)
|
||||
p.In()
|
||||
if keygoAliasTyp == keygoTyp {
|
||||
p.P(keysName, ` = append(`, keysName, `, k)`)
|
||||
} else {
|
||||
p.P(keysName, ` = append(`, keysName, `, `, keygoTyp, `(k))`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(sortKeysPkg.Use(), `.`, keyCapTyp, `s(`, keysName, `)`)
|
||||
mapName := `mapStringFor` + fieldname
|
||||
p.P(mapName, ` := "`, mapgoTyp, `{"`)
|
||||
p.P(`for _, k := range `, keysName, ` {`)
|
||||
p.In()
|
||||
if keygoAliasTyp == keygoTyp {
|
||||
p.P(mapName, ` += fmt.Sprintf("%#v: %#v,", k, this.`, fieldname, `[k])`)
|
||||
} else {
|
||||
p.P(mapName, ` += fmt.Sprintf("%#v: %#v,", k, this.`, fieldname, `[`, keygoAliasTyp, `(k)])`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(mapName, ` += "}"`)
|
||||
p.P(`if this.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
p.P(`s = append(s, "`, fieldname, `: " + `, mapName, `+ ",\n")`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if (field.IsMessage() && !gogoproto.IsCustomType(field) && !gogoproto.IsStdTime(field) && !gogoproto.IsStdDuration(field)) || p.IsGroup(field) {
|
||||
if nullable || repeated {
|
||||
p.P(`if this.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
}
|
||||
if nullable {
|
||||
p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `) + ",\n")`)
|
||||
} else if repeated {
|
||||
if nullable {
|
||||
p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `) + ",\n")`)
|
||||
} else {
|
||||
goTyp, _ := p.GoType(message, field)
|
||||
goTyp = strings.Replace(goTyp, "[]", "", 1)
|
||||
p.P("vs := make([]*", goTyp, ", len(this.", fieldname, "))")
|
||||
p.P("for i := range vs {")
|
||||
p.In()
|
||||
p.P("vs[i] = &this.", fieldname, "[i]")
|
||||
p.Out()
|
||||
p.P("}")
|
||||
p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", vs) + ",\n")`)
|
||||
}
|
||||
} else {
|
||||
p.P(`s = append(s, "`, fieldname, `: " + `, stringsPkg.Use(), `.Replace(this.`, fieldname, `.GoString()`, ",`&`,``,1)", ` + ",\n")`)
|
||||
}
|
||||
if nullable || repeated {
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
} else {
|
||||
if !proto3 && (nullable || repeated) {
|
||||
p.P(`if this.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
}
|
||||
if field.IsEnum() {
|
||||
if nullable && !repeated && !proto3 {
|
||||
goTyp, _ := p.GoType(message, field)
|
||||
p.P(`s = append(s, "`, fieldname, `: " + valueToGoString`, p.localName, `(this.`, fieldname, `,"`, generator.GoTypeToName(goTyp), `"`, `) + ",\n")`)
|
||||
} else {
|
||||
p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `) + ",\n")`)
|
||||
}
|
||||
} else {
|
||||
if nullable && !repeated && !proto3 {
|
||||
goTyp, _ := p.GoType(message, field)
|
||||
p.P(`s = append(s, "`, fieldname, `: " + valueToGoString`, p.localName, `(this.`, fieldname, `,"`, generator.GoTypeToName(goTyp), `"`, `) + ",\n")`)
|
||||
} else {
|
||||
p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `) + ",\n")`)
|
||||
}
|
||||
}
|
||||
if !proto3 && (nullable || repeated) {
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
if message.DescriptorProto.HasExtension() {
|
||||
if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
p.P(`s = append(s, "XXX_InternalExtensions: " + extensionToGoString`, p.localName, `(this) + ",\n")`)
|
||||
extensionToGoStringUsed = true
|
||||
} else {
|
||||
p.P(`if this.XXX_extensions != nil {`)
|
||||
p.In()
|
||||
p.P(`s = append(s, "XXX_extensions: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.XXX_extensions) + ",\n")`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
p.P(`if this.XXX_unrecognized != nil {`)
|
||||
p.In()
|
||||
p.P(`s = append(s, "XXX_unrecognized:" + `, fmtPkg.Use(), `.Sprintf("%#v", this.XXX_unrecognized) + ",\n")`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
|
||||
p.P(`s = append(s, "}")`)
|
||||
p.P(`return `, stringsPkg.Use(), `.Join(s, "")`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
|
||||
//Generate GoString methods for oneof fields
|
||||
for _, field := range message.Field {
|
||||
oneof := field.OneofIndex != nil
|
||||
if !oneof {
|
||||
continue
|
||||
}
|
||||
ccTypeName := p.OneOfTypeName(message, field)
|
||||
p.P(`func (this *`, ccTypeName, `) GoString() string {`)
|
||||
p.In()
|
||||
p.P(`if this == nil {`)
|
||||
p.In()
|
||||
p.P(`return "nil"`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
fieldname := p.GetOneOfFieldName(message, field)
|
||||
outStr := strings.Join([]string{
|
||||
"s := ",
|
||||
stringsPkg.Use(), ".Join([]string{`&", packageName, ".", ccTypeName, "{` + \n",
|
||||
"`", fieldname, ":` + ", fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `)`,
|
||||
" + `}`",
|
||||
`}`,
|
||||
`,", "`,
|
||||
`)`}, "")
|
||||
p.P(outStr)
|
||||
p.P(`return s`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
|
||||
if !p.atleastOne {
|
||||
return
|
||||
}
|
||||
|
||||
p.P(`func valueToGoString`, p.localName, `(v interface{}, typ string) string {`)
|
||||
p.In()
|
||||
p.P(`rv := `, reflectPkg.Use(), `.ValueOf(v)`)
|
||||
p.P(`if rv.IsNil() {`)
|
||||
p.In()
|
||||
p.P(`return "nil"`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`pv := `, reflectPkg.Use(), `.Indirect(rv).Interface()`)
|
||||
p.P(`return `, fmtPkg.Use(), `.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
|
||||
if extensionToGoStringUsed {
|
||||
if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
|
||||
fmt.Fprintf(os.Stderr, "The GoString plugin for messages with extensions requires importing gogoprotobuf. Please see file %s", file.GetName())
|
||||
os.Exit(1)
|
||||
}
|
||||
p.P(`func extensionToGoString`, p.localName, `(m `, protoPkg.Use(), `.Message) string {`)
|
||||
p.In()
|
||||
p.P(`e := `, protoPkg.Use(), `.GetUnsafeExtensionsMap(m)`)
|
||||
p.P(`if e == nil { return "nil" }`)
|
||||
p.P(`s := "proto.NewUnsafeXXX_InternalExtensions(map[int32]proto.Extension{"`)
|
||||
p.P(`keys := make([]int, 0, len(e))`)
|
||||
p.P(`for k := range e {`)
|
||||
p.In()
|
||||
p.P(`keys = append(keys, int(k))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(sortPkg.Use(), `.Ints(keys)`)
|
||||
p.P(`ss := []string{}`)
|
||||
p.P(`for _, k := range keys {`)
|
||||
p.In()
|
||||
p.P(`ss = append(ss, `, strconvPkg.Use(), `.Itoa(k) + ": " + e[int32(k)].GoString())`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`s+=`, stringsPkg.Use(), `.Join(ss, ",") + "})"`)
|
||||
p.P(`return s`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
generator.RegisterPlugin(NewGoString())
|
||||
}
|
90
vendor/github.com/gogo/protobuf/plugin/gostring/gostringtest.go
generated
vendored
Normal file
90
vendor/github.com/gogo/protobuf/plugin/gostring/gostringtest.go
generated
vendored
Normal file
@ -0,0 +1,90 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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(`t.Fatal(err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
|
||||
}
|
||||
return used
|
||||
}
|
||||
|
||||
func init() {
|
||||
testgen.RegisterTestPlugin(NewTest)
|
||||
}
|
1205
vendor/github.com/gogo/protobuf/plugin/marshalto/marshalto.go
generated
vendored
Normal file
1205
vendor/github.com/gogo/protobuf/plugin/marshalto/marshalto.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
93
vendor/github.com/gogo/protobuf/plugin/oneofcheck/oneofcheck.go
generated
vendored
Normal file
93
vendor/github.com/gogo/protobuf/plugin/oneofcheck/oneofcheck.go
generated
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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())
|
||||
}
|
795
vendor/github.com/gogo/protobuf/plugin/populate/populate.go
generated
vendored
Normal file
795
vendor/github.com/gogo/protobuf/plugin/populate/populate.go
generated
vendored
Normal file
@ -0,0 +1,795 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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 populate plugin generates a NewPopulated function.
|
||||
This function returns a newly populated structure.
|
||||
|
||||
It is enabled by the following extensions:
|
||||
|
||||
- populate
|
||||
- populate_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:
|
||||
|
||||
option (gogoproto.populate_all) = true;
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
given to the populate plugin, will generate code the following code:
|
||||
|
||||
func NewPopulatedB(r randyExample, easy bool) *B {
|
||||
this := &B{}
|
||||
v2 := NewPopulatedA(r, easy)
|
||||
this.A = *v2
|
||||
if r.Intn(10) != 0 {
|
||||
v3 := r.Intn(10)
|
||||
this.G = make([]github_com_gogo_protobuf_test_custom.Uint128, v3)
|
||||
for i := 0; i < v3; i++ {
|
||||
v4 := github_com_gogo_protobuf_test_custom.NewPopulatedUint128(r)
|
||||
this.G[i] = *v4
|
||||
}
|
||||
}
|
||||
if !easy && r.Intn(10) != 0 {
|
||||
this.XXX_unrecognized = randUnrecognizedExample(r, 3)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
The idea that is useful for testing.
|
||||
Most of the other plugins' generated test code uses it.
|
||||
You will still be able to use the generated test code of other packages
|
||||
if you turn off the popluate plugin and write your own custom NewPopulated function.
|
||||
|
||||
If the easy flag is not set the XXX_unrecognized and XXX_extensions fields are also populated.
|
||||
These have caused problems with JSON marshalling and unmarshalling tests.
|
||||
|
||||
*/
|
||||
package populate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gogo/protobuf/gogoproto"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
|
||||
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
|
||||
"github.com/gogo/protobuf/vanity"
|
||||
)
|
||||
|
||||
type VarGen interface {
|
||||
Next() string
|
||||
Current() string
|
||||
}
|
||||
|
||||
type varGen struct {
|
||||
index int64
|
||||
}
|
||||
|
||||
func NewVarGen() VarGen {
|
||||
return &varGen{0}
|
||||
}
|
||||
|
||||
func (this *varGen) Next() string {
|
||||
this.index++
|
||||
return fmt.Sprintf("v%d", this.index)
|
||||
}
|
||||
|
||||
func (this *varGen) Current() string {
|
||||
return fmt.Sprintf("v%d", this.index)
|
||||
}
|
||||
|
||||
type plugin struct {
|
||||
*generator.Generator
|
||||
generator.PluginImports
|
||||
varGen VarGen
|
||||
atleastOne bool
|
||||
localName string
|
||||
typesPkg generator.Single
|
||||
}
|
||||
|
||||
func NewPlugin() *plugin {
|
||||
return &plugin{}
|
||||
}
|
||||
|
||||
func (p *plugin) Name() string {
|
||||
return "populate"
|
||||
}
|
||||
|
||||
func (p *plugin) Init(g *generator.Generator) {
|
||||
p.Generator = g
|
||||
}
|
||||
|
||||
func value(typeName string, fieldType descriptor.FieldDescriptorProto_Type) string {
|
||||
switch fieldType {
|
||||
case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
|
||||
return typeName + "(r.Float64())"
|
||||
case descriptor.FieldDescriptorProto_TYPE_FLOAT:
|
||||
return typeName + "(r.Float32())"
|
||||
case descriptor.FieldDescriptorProto_TYPE_INT64,
|
||||
descriptor.FieldDescriptorProto_TYPE_SFIXED64,
|
||||
descriptor.FieldDescriptorProto_TYPE_SINT64:
|
||||
return typeName + "(r.Int63())"
|
||||
case descriptor.FieldDescriptorProto_TYPE_UINT64,
|
||||
descriptor.FieldDescriptorProto_TYPE_FIXED64:
|
||||
return typeName + "(uint64(r.Uint32()))"
|
||||
case descriptor.FieldDescriptorProto_TYPE_INT32,
|
||||
descriptor.FieldDescriptorProto_TYPE_SINT32,
|
||||
descriptor.FieldDescriptorProto_TYPE_SFIXED32,
|
||||
descriptor.FieldDescriptorProto_TYPE_ENUM:
|
||||
return typeName + "(r.Int31())"
|
||||
case descriptor.FieldDescriptorProto_TYPE_UINT32,
|
||||
descriptor.FieldDescriptorProto_TYPE_FIXED32:
|
||||
return typeName + "(r.Uint32())"
|
||||
case descriptor.FieldDescriptorProto_TYPE_BOOL:
|
||||
return typeName + `(bool(r.Intn(2) == 0))`
|
||||
case descriptor.FieldDescriptorProto_TYPE_STRING,
|
||||
descriptor.FieldDescriptorProto_TYPE_GROUP,
|
||||
descriptor.FieldDescriptorProto_TYPE_MESSAGE,
|
||||
descriptor.FieldDescriptorProto_TYPE_BYTES:
|
||||
}
|
||||
panic(fmt.Errorf("unexpected type %v", typeName))
|
||||
}
|
||||
|
||||
func negative(fieldType descriptor.FieldDescriptorProto_Type) bool {
|
||||
switch fieldType {
|
||||
case descriptor.FieldDescriptorProto_TYPE_UINT64,
|
||||
descriptor.FieldDescriptorProto_TYPE_FIXED64,
|
||||
descriptor.FieldDescriptorProto_TYPE_UINT32,
|
||||
descriptor.FieldDescriptorProto_TYPE_FIXED32,
|
||||
descriptor.FieldDescriptorProto_TYPE_BOOL:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *plugin) getFuncName(goTypName string) string {
|
||||
funcName := "NewPopulated" + goTypName
|
||||
goTypNames := strings.Split(goTypName, ".")
|
||||
if len(goTypNames) == 2 {
|
||||
funcName = goTypNames[0] + ".NewPopulated" + goTypNames[1]
|
||||
} else if len(goTypNames) != 1 {
|
||||
panic(fmt.Errorf("unreachable: too many dots in %v", goTypName))
|
||||
}
|
||||
switch funcName {
|
||||
case "time.NewPopulatedTime":
|
||||
funcName = p.typesPkg.Use() + ".NewPopulatedStdTime"
|
||||
case "time.NewPopulatedDuration":
|
||||
funcName = p.typesPkg.Use() + ".NewPopulatedStdDuration"
|
||||
}
|
||||
return funcName
|
||||
}
|
||||
|
||||
func (p *plugin) getFuncCall(goTypName string) string {
|
||||
funcName := p.getFuncName(goTypName)
|
||||
funcCall := funcName + "(r, easy)"
|
||||
return funcCall
|
||||
}
|
||||
|
||||
func (p *plugin) getCustomFuncCall(goTypName string) string {
|
||||
funcName := p.getFuncName(goTypName)
|
||||
funcCall := funcName + "(r)"
|
||||
return funcCall
|
||||
}
|
||||
|
||||
func (p *plugin) getEnumVal(field *descriptor.FieldDescriptorProto, goTyp string) string {
|
||||
enum := p.ObjectNamed(field.GetTypeName()).(*generator.EnumDescriptor)
|
||||
l := len(enum.Value)
|
||||
values := make([]string, l)
|
||||
for i := range enum.Value {
|
||||
values[i] = strconv.Itoa(int(*enum.Value[i].Number))
|
||||
}
|
||||
arr := "[]int32{" + strings.Join(values, ",") + "}"
|
||||
val := strings.Join([]string{generator.GoTypeToName(goTyp), `(`, arr, `[r.Intn(`, fmt.Sprintf("%d", l), `)])`}, "")
|
||||
return val
|
||||
}
|
||||
|
||||
func (p *plugin) GenerateField(file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto) {
|
||||
proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
|
||||
goTyp, _ := p.GoType(message, field)
|
||||
fieldname := p.GetOneOfFieldName(message, field)
|
||||
goTypName := generator.GoTypeToName(goTyp)
|
||||
if p.IsMap(field) {
|
||||
m := p.GoMapType(nil, field)
|
||||
keygoTyp, _ := p.GoType(nil, m.KeyField)
|
||||
keygoTyp = strings.Replace(keygoTyp, "*", "", 1)
|
||||
keygoAliasTyp, _ := p.GoType(nil, m.KeyAliasField)
|
||||
keygoAliasTyp = strings.Replace(keygoAliasTyp, "*", "", 1)
|
||||
|
||||
valuegoTyp, _ := p.GoType(nil, m.ValueField)
|
||||
valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField)
|
||||
keytypName := generator.GoTypeToName(keygoTyp)
|
||||
keygoAliasTyp = generator.GoTypeToName(keygoAliasTyp)
|
||||
valuetypAliasName := generator.GoTypeToName(valuegoAliasTyp)
|
||||
|
||||
nullable, valuegoTyp, valuegoAliasTyp := generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp)
|
||||
|
||||
p.P(p.varGen.Next(), ` := r.Intn(10)`)
|
||||
p.P(`this.`, fieldname, ` = make(`, m.GoType, `)`)
|
||||
p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
|
||||
p.In()
|
||||
keyval := ""
|
||||
if m.KeyField.IsString() {
|
||||
keyval = fmt.Sprintf("randString%v(r)", p.localName)
|
||||
} else {
|
||||
keyval = value(keytypName, m.KeyField.GetType())
|
||||
}
|
||||
if keygoAliasTyp != keygoTyp {
|
||||
keyval = keygoAliasTyp + `(` + keyval + `)`
|
||||
}
|
||||
if m.ValueField.IsMessage() || p.IsGroup(field) ||
|
||||
(m.ValueField.IsBytes() && gogoproto.IsCustomType(field)) {
|
||||
s := `this.` + fieldname + `[` + keyval + `] = `
|
||||
if gogoproto.IsStdTime(field) || gogoproto.IsStdDuration(field) {
|
||||
valuegoTyp = valuegoAliasTyp
|
||||
}
|
||||
funcCall := p.getCustomFuncCall(goTypName)
|
||||
if !gogoproto.IsCustomType(field) {
|
||||
goTypName = generator.GoTypeToName(valuegoTyp)
|
||||
funcCall = p.getFuncCall(goTypName)
|
||||
}
|
||||
if !nullable {
|
||||
funcCall = `*` + funcCall
|
||||
}
|
||||
if valuegoTyp != valuegoAliasTyp {
|
||||
funcCall = `(` + valuegoAliasTyp + `)(` + funcCall + `)`
|
||||
}
|
||||
s += funcCall
|
||||
p.P(s)
|
||||
} else if m.ValueField.IsEnum() {
|
||||
s := `this.` + fieldname + `[` + keyval + `]` + ` = ` + p.getEnumVal(m.ValueField, valuegoTyp)
|
||||
p.P(s)
|
||||
} else if m.ValueField.IsBytes() {
|
||||
count := p.varGen.Next()
|
||||
p.P(count, ` := r.Intn(100)`)
|
||||
p.P(p.varGen.Next(), ` := `, keyval)
|
||||
p.P(`this.`, fieldname, `[`, p.varGen.Current(), `] = make(`, valuegoTyp, `, `, count, `)`)
|
||||
p.P(`for i := 0; i < `, count, `; i++ {`)
|
||||
p.In()
|
||||
p.P(`this.`, fieldname, `[`, p.varGen.Current(), `][i] = byte(r.Intn(256))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if m.ValueField.IsString() {
|
||||
s := `this.` + fieldname + `[` + keyval + `]` + ` = ` + fmt.Sprintf("randString%v(r)", p.localName)
|
||||
p.P(s)
|
||||
} else {
|
||||
p.P(p.varGen.Next(), ` := `, keyval)
|
||||
p.P(`this.`, fieldname, `[`, p.varGen.Current(), `] = `, value(valuetypAliasName, m.ValueField.GetType()))
|
||||
if negative(m.ValueField.GetType()) {
|
||||
p.P(`if r.Intn(2) == 0 {`)
|
||||
p.In()
|
||||
p.P(`this.`, fieldname, `[`, p.varGen.Current(), `] *= -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if gogoproto.IsCustomType(field) {
|
||||
funcCall := p.getCustomFuncCall(goTypName)
|
||||
if field.IsRepeated() {
|
||||
p.P(p.varGen.Next(), ` := r.Intn(10)`)
|
||||
p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
|
||||
p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
|
||||
p.In()
|
||||
p.P(p.varGen.Next(), `:= `, funcCall)
|
||||
p.P(`this.`, fieldname, `[i] = *`, p.varGen.Current())
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if gogoproto.IsNullable(field) {
|
||||
p.P(`this.`, fieldname, ` = `, funcCall)
|
||||
} else {
|
||||
p.P(p.varGen.Next(), `:= `, funcCall)
|
||||
p.P(`this.`, fieldname, ` = *`, p.varGen.Current())
|
||||
}
|
||||
} else if field.IsMessage() || p.IsGroup(field) {
|
||||
funcCall := p.getFuncCall(goTypName)
|
||||
if field.IsRepeated() {
|
||||
p.P(p.varGen.Next(), ` := r.Intn(5)`)
|
||||
p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
|
||||
p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
|
||||
p.In()
|
||||
if gogoproto.IsNullable(field) {
|
||||
p.P(`this.`, fieldname, `[i] = `, funcCall)
|
||||
} else {
|
||||
p.P(p.varGen.Next(), `:= `, funcCall)
|
||||
p.P(`this.`, fieldname, `[i] = *`, p.varGen.Current())
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else {
|
||||
if gogoproto.IsNullable(field) {
|
||||
p.P(`this.`, fieldname, ` = `, funcCall)
|
||||
} else {
|
||||
p.P(p.varGen.Next(), `:= `, funcCall)
|
||||
p.P(`this.`, fieldname, ` = *`, p.varGen.Current())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if field.IsEnum() {
|
||||
val := p.getEnumVal(field, goTyp)
|
||||
if field.IsRepeated() {
|
||||
p.P(p.varGen.Next(), ` := r.Intn(10)`)
|
||||
p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
|
||||
p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
|
||||
p.In()
|
||||
p.P(`this.`, fieldname, `[i] = `, val)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if !gogoproto.IsNullable(field) || proto3 {
|
||||
p.P(`this.`, fieldname, ` = `, val)
|
||||
} else {
|
||||
p.P(p.varGen.Next(), ` := `, val)
|
||||
p.P(`this.`, fieldname, ` = &`, p.varGen.Current())
|
||||
}
|
||||
} else if field.IsBytes() {
|
||||
if field.IsRepeated() {
|
||||
p.P(p.varGen.Next(), ` := r.Intn(10)`)
|
||||
p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
|
||||
p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
|
||||
p.In()
|
||||
p.P(p.varGen.Next(), ` := r.Intn(100)`)
|
||||
p.P(`this.`, fieldname, `[i] = make([]byte,`, p.varGen.Current(), `)`)
|
||||
p.P(`for j := 0; j < `, p.varGen.Current(), `; j++ {`)
|
||||
p.In()
|
||||
p.P(`this.`, fieldname, `[i][j] = byte(r.Intn(256))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else {
|
||||
p.P(p.varGen.Next(), ` := r.Intn(100)`)
|
||||
p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
|
||||
p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
|
||||
p.In()
|
||||
p.P(`this.`, fieldname, `[i] = byte(r.Intn(256))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
} else if field.IsString() {
|
||||
typName := generator.GoTypeToName(goTyp)
|
||||
val := fmt.Sprintf("%s(randString%v(r))", typName, p.localName)
|
||||
if field.IsRepeated() {
|
||||
p.P(p.varGen.Next(), ` := r.Intn(10)`)
|
||||
p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
|
||||
p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
|
||||
p.In()
|
||||
p.P(`this.`, fieldname, `[i] = `, val)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if !gogoproto.IsNullable(field) || proto3 {
|
||||
p.P(`this.`, fieldname, ` = `, val)
|
||||
} else {
|
||||
p.P(p.varGen.Next(), `:= `, val)
|
||||
p.P(`this.`, fieldname, ` = &`, p.varGen.Current())
|
||||
}
|
||||
} else {
|
||||
typName := generator.GoTypeToName(goTyp)
|
||||
if field.IsRepeated() {
|
||||
p.P(p.varGen.Next(), ` := r.Intn(10)`)
|
||||
p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
|
||||
p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
|
||||
p.In()
|
||||
p.P(`this.`, fieldname, `[i] = `, value(typName, field.GetType()))
|
||||
if negative(field.GetType()) {
|
||||
p.P(`if r.Intn(2) == 0 {`)
|
||||
p.In()
|
||||
p.P(`this.`, fieldname, `[i] *= -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if !gogoproto.IsNullable(field) || proto3 {
|
||||
p.P(`this.`, fieldname, ` = `, value(typName, field.GetType()))
|
||||
if negative(field.GetType()) {
|
||||
p.P(`if r.Intn(2) == 0 {`)
|
||||
p.In()
|
||||
p.P(`this.`, fieldname, ` *= -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
} else {
|
||||
p.P(p.varGen.Next(), ` := `, value(typName, field.GetType()))
|
||||
if negative(field.GetType()) {
|
||||
p.P(`if r.Intn(2) == 0 {`)
|
||||
p.In()
|
||||
p.P(p.varGen.Current(), ` *= -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
p.P(`this.`, fieldname, ` = &`, p.varGen.Current())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *plugin) hasLoop(field *descriptor.FieldDescriptorProto, visited []*generator.Descriptor, excludes []*generator.Descriptor) *generator.Descriptor {
|
||||
if field.IsMessage() || p.IsGroup(field) || p.IsMap(field) {
|
||||
var fieldMessage *generator.Descriptor
|
||||
if p.IsMap(field) {
|
||||
m := p.GoMapType(nil, field)
|
||||
if !m.ValueField.IsMessage() {
|
||||
return nil
|
||||
}
|
||||
fieldMessage = p.ObjectNamed(m.ValueField.GetTypeName()).(*generator.Descriptor)
|
||||
} else {
|
||||
fieldMessage = p.ObjectNamed(field.GetTypeName()).(*generator.Descriptor)
|
||||
}
|
||||
fieldTypeName := generator.CamelCaseSlice(fieldMessage.TypeName())
|
||||
for _, message := range visited {
|
||||
messageTypeName := generator.CamelCaseSlice(message.TypeName())
|
||||
if fieldTypeName == messageTypeName {
|
||||
for _, e := range excludes {
|
||||
if fieldTypeName == generator.CamelCaseSlice(e.TypeName()) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fieldMessage
|
||||
}
|
||||
}
|
||||
pkg := strings.Split(field.GetTypeName(), ".")[1]
|
||||
for _, f := range fieldMessage.Field {
|
||||
if strings.HasPrefix(f.GetTypeName(), "."+pkg+".") {
|
||||
visited = append(visited, fieldMessage)
|
||||
loopTo := p.hasLoop(f, visited, excludes)
|
||||
if loopTo != nil {
|
||||
return loopTo
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *plugin) loops(field *descriptor.FieldDescriptorProto, message *generator.Descriptor) int {
|
||||
//fmt.Fprintf(os.Stderr, "loops %v %v\n", field.GetTypeName(), generator.CamelCaseSlice(message.TypeName()))
|
||||
excludes := []*generator.Descriptor{}
|
||||
loops := 0
|
||||
for {
|
||||
visited := []*generator.Descriptor{}
|
||||
loopTo := p.hasLoop(field, visited, excludes)
|
||||
if loopTo == nil {
|
||||
break
|
||||
}
|
||||
//fmt.Fprintf(os.Stderr, "loopTo %v\n", generator.CamelCaseSlice(loopTo.TypeName()))
|
||||
excludes = append(excludes, loopTo)
|
||||
loops++
|
||||
}
|
||||
return loops
|
||||
}
|
||||
|
||||
func (p *plugin) Generate(file *generator.FileDescriptor) {
|
||||
p.atleastOne = false
|
||||
p.PluginImports = generator.NewPluginImports(p.Generator)
|
||||
p.varGen = NewVarGen()
|
||||
proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
|
||||
p.typesPkg = p.NewImport("github.com/gogo/protobuf/types")
|
||||
p.localName = generator.FileName(file)
|
||||
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.HasPopulate(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
continue
|
||||
}
|
||||
if message.DescriptorProto.GetOptions().GetMapEntry() {
|
||||
continue
|
||||
}
|
||||
p.atleastOne = true
|
||||
ccTypeName := generator.CamelCaseSlice(message.TypeName())
|
||||
loopLevels := make([]int, len(message.Field))
|
||||
maxLoopLevel := 0
|
||||
for i, field := range message.Field {
|
||||
loopLevels[i] = p.loops(field, message)
|
||||
if loopLevels[i] > maxLoopLevel {
|
||||
maxLoopLevel = loopLevels[i]
|
||||
}
|
||||
}
|
||||
ranTotal := 0
|
||||
for i := range loopLevels {
|
||||
ranTotal += int(math.Pow10(maxLoopLevel - loopLevels[i]))
|
||||
}
|
||||
p.P(`func NewPopulated`, ccTypeName, `(r randy`, p.localName, `, easy bool) *`, ccTypeName, ` {`)
|
||||
p.In()
|
||||
p.P(`this := &`, ccTypeName, `{}`)
|
||||
if gogoproto.IsUnion(message.File(), message.DescriptorProto) && len(message.Field) > 0 {
|
||||
p.P(`fieldNum := r.Intn(`, fmt.Sprintf("%d", ranTotal), `)`)
|
||||
p.P(`switch fieldNum {`)
|
||||
k := 0
|
||||
for i, field := range message.Field {
|
||||
is := []string{}
|
||||
ran := int(math.Pow10(maxLoopLevel - loopLevels[i]))
|
||||
for j := 0; j < ran; j++ {
|
||||
is = append(is, fmt.Sprintf("%d", j+k))
|
||||
}
|
||||
k += ran
|
||||
p.P(`case `, strings.Join(is, ","), `:`)
|
||||
p.In()
|
||||
p.GenerateField(file, message, field)
|
||||
p.Out()
|
||||
}
|
||||
p.P(`}`)
|
||||
} else {
|
||||
var maxFieldNumber int32
|
||||
oneofs := make(map[string]struct{})
|
||||
for fieldIndex, field := range message.Field {
|
||||
if field.GetNumber() > maxFieldNumber {
|
||||
maxFieldNumber = field.GetNumber()
|
||||
}
|
||||
oneof := field.OneofIndex != nil
|
||||
if !oneof {
|
||||
if field.IsRequired() || (!gogoproto.IsNullable(field) && !field.IsRepeated()) || (proto3 && !field.IsMessage()) {
|
||||
p.GenerateField(file, message, field)
|
||||
} else {
|
||||
if loopLevels[fieldIndex] > 0 {
|
||||
p.P(`if r.Intn(10) == 0 {`)
|
||||
} else {
|
||||
p.P(`if r.Intn(10) != 0 {`)
|
||||
}
|
||||
p.In()
|
||||
p.GenerateField(file, message, field)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
} else {
|
||||
fieldname := p.GetFieldName(message, field)
|
||||
if _, ok := oneofs[fieldname]; ok {
|
||||
continue
|
||||
} else {
|
||||
oneofs[fieldname] = struct{}{}
|
||||
}
|
||||
fieldNumbers := []int32{}
|
||||
for _, f := range message.Field {
|
||||
fname := p.GetFieldName(message, f)
|
||||
if fname == fieldname {
|
||||
fieldNumbers = append(fieldNumbers, f.GetNumber())
|
||||
}
|
||||
}
|
||||
|
||||
p.P(`oneofNumber_`, fieldname, ` := `, fmt.Sprintf("%#v", fieldNumbers), `[r.Intn(`, strconv.Itoa(len(fieldNumbers)), `)]`)
|
||||
p.P(`switch oneofNumber_`, fieldname, ` {`)
|
||||
for _, f := range message.Field {
|
||||
fname := p.GetFieldName(message, f)
|
||||
if fname != fieldname {
|
||||
continue
|
||||
}
|
||||
p.P(`case `, strconv.Itoa(int(f.GetNumber())), `:`)
|
||||
p.In()
|
||||
ccTypeName := p.OneOfTypeName(message, f)
|
||||
p.P(`this.`, fname, ` = NewPopulated`, ccTypeName, `(r, easy)`)
|
||||
p.Out()
|
||||
}
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
if message.DescriptorProto.HasExtension() {
|
||||
p.P(`if !easy && r.Intn(10) != 0 {`)
|
||||
p.In()
|
||||
p.P(`l := r.Intn(5)`)
|
||||
p.P(`for i := 0; i < l; i++ {`)
|
||||
p.In()
|
||||
if len(message.DescriptorProto.GetExtensionRange()) > 1 {
|
||||
p.P(`eIndex := r.Intn(`, strconv.Itoa(len(message.DescriptorProto.GetExtensionRange())), `)`)
|
||||
p.P(`fieldNumber := 0`)
|
||||
p.P(`switch eIndex {`)
|
||||
for i, e := range message.DescriptorProto.GetExtensionRange() {
|
||||
p.P(`case `, strconv.Itoa(i), `:`)
|
||||
p.In()
|
||||
p.P(`fieldNumber = r.Intn(`, strconv.Itoa(int(e.GetEnd()-e.GetStart())), `) + `, strconv.Itoa(int(e.GetStart())))
|
||||
p.Out()
|
||||
if e.GetEnd() > maxFieldNumber {
|
||||
maxFieldNumber = e.GetEnd()
|
||||
}
|
||||
}
|
||||
p.P(`}`)
|
||||
} else {
|
||||
e := message.DescriptorProto.GetExtensionRange()[0]
|
||||
p.P(`fieldNumber := r.Intn(`, strconv.Itoa(int(e.GetEnd()-e.GetStart())), `) + `, strconv.Itoa(int(e.GetStart())))
|
||||
if e.GetEnd() > maxFieldNumber {
|
||||
maxFieldNumber = e.GetEnd()
|
||||
}
|
||||
}
|
||||
p.P(`wire := r.Intn(4)`)
|
||||
p.P(`if wire == 3 { wire = 5 }`)
|
||||
p.P(`dAtA := randField`, p.localName, `(nil, r, fieldNumber, wire)`)
|
||||
p.P(protoPkg.Use(), `.SetRawExtension(this, int32(fieldNumber), dAtA)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
|
||||
if maxFieldNumber < (1 << 10) {
|
||||
p.P(`if !easy && r.Intn(10) != 0 {`)
|
||||
p.In()
|
||||
if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
p.P(`this.XXX_unrecognized = randUnrecognized`, p.localName, `(r, `, strconv.Itoa(int(maxFieldNumber+1)), `)`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
p.P(`return this`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(``)
|
||||
|
||||
//Generate NewPopulated functions for oneof fields
|
||||
m := proto.Clone(message.DescriptorProto).(*descriptor.DescriptorProto)
|
||||
for _, f := range m.Field {
|
||||
oneof := f.OneofIndex != nil
|
||||
if !oneof {
|
||||
continue
|
||||
}
|
||||
ccTypeName := p.OneOfTypeName(message, f)
|
||||
p.P(`func NewPopulated`, ccTypeName, `(r randy`, p.localName, `, easy bool) *`, ccTypeName, ` {`)
|
||||
p.In()
|
||||
p.P(`this := &`, ccTypeName, `{}`)
|
||||
vanity.TurnOffNullableForNativeTypes(f)
|
||||
p.GenerateField(file, message, f)
|
||||
p.P(`return this`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
|
||||
if !p.atleastOne {
|
||||
return
|
||||
}
|
||||
|
||||
p.P(`type randy`, p.localName, ` interface {`)
|
||||
p.In()
|
||||
p.P(`Float32() float32`)
|
||||
p.P(`Float64() float64`)
|
||||
p.P(`Int63() int64`)
|
||||
p.P(`Int31() int32`)
|
||||
p.P(`Uint32() uint32`)
|
||||
p.P(`Intn(n int) int`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
|
||||
p.P(`func randUTF8Rune`, p.localName, `(r randy`, p.localName, `) rune {`)
|
||||
p.In()
|
||||
p.P(`ru := r.Intn(62)`)
|
||||
p.P(`if ru < 10 {`)
|
||||
p.In()
|
||||
p.P(`return rune(ru+48)`)
|
||||
p.Out()
|
||||
p.P(`} else if ru < 36 {`)
|
||||
p.In()
|
||||
p.P(`return rune(ru+55)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return rune(ru+61)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
|
||||
p.P(`func randString`, p.localName, `(r randy`, p.localName, `) string {`)
|
||||
p.In()
|
||||
p.P(p.varGen.Next(), ` := r.Intn(100)`)
|
||||
p.P(`tmps := make([]rune, `, p.varGen.Current(), `)`)
|
||||
p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
|
||||
p.In()
|
||||
p.P(`tmps[i] = randUTF8Rune`, p.localName, `(r)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return string(tmps)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
|
||||
p.P(`func randUnrecognized`, p.localName, `(r randy`, p.localName, `, maxFieldNumber int) (dAtA []byte) {`)
|
||||
p.In()
|
||||
p.P(`l := r.Intn(5)`)
|
||||
p.P(`for i := 0; i < l; i++ {`)
|
||||
p.In()
|
||||
p.P(`wire := r.Intn(4)`)
|
||||
p.P(`if wire == 3 { wire = 5 }`)
|
||||
p.P(`fieldNumber := maxFieldNumber + r.Intn(100)`)
|
||||
p.P(`dAtA = randField`, p.localName, `(dAtA, r, fieldNumber, wire)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return dAtA`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
|
||||
p.P(`func randField`, p.localName, `(dAtA []byte, r randy`, p.localName, `, fieldNumber int, wire int) []byte {`)
|
||||
p.In()
|
||||
p.P(`key := uint32(fieldNumber)<<3 | uint32(wire)`)
|
||||
p.P(`switch wire {`)
|
||||
p.P(`case 0:`)
|
||||
p.In()
|
||||
p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(key))`)
|
||||
p.P(p.varGen.Next(), ` := r.Int63()`)
|
||||
p.P(`if r.Intn(2) == 0 {`)
|
||||
p.In()
|
||||
p.P(p.varGen.Current(), ` *= -1`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(`, p.varGen.Current(), `))`)
|
||||
p.Out()
|
||||
p.P(`case 1:`)
|
||||
p.In()
|
||||
p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(key))`)
|
||||
p.P(`dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))`)
|
||||
p.Out()
|
||||
p.P(`case 2:`)
|
||||
p.In()
|
||||
p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(key))`)
|
||||
p.P(`ll := r.Intn(100)`)
|
||||
p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(ll))`)
|
||||
p.P(`for j := 0; j < ll; j++ {`)
|
||||
p.In()
|
||||
p.P(`dAtA = append(dAtA, byte(r.Intn(256)))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`default:`)
|
||||
p.In()
|
||||
p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(key))`)
|
||||
p.P(`dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`return dAtA`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
|
||||
p.P(`func encodeVarintPopulate`, p.localName, `(dAtA []byte, v uint64) []byte {`)
|
||||
p.In()
|
||||
p.P(`for v >= 1<<7 {`)
|
||||
p.In()
|
||||
p.P(`dAtA = append(dAtA, uint8(uint64(v)&0x7f|0x80))`)
|
||||
p.P(`v >>= 7`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`dAtA = append(dAtA, uint8(v))`)
|
||||
p.P(`return dAtA`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
|
||||
}
|
||||
|
||||
func init() {
|
||||
generator.RegisterPlugin(NewPlugin())
|
||||
}
|
674
vendor/github.com/gogo/protobuf/plugin/size/size.go
generated
vendored
Normal file
674
vendor/github.com/gogo/protobuf/plugin/size/size.go
generated
vendored
Normal file
@ -0,0 +1,674 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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 size plugin generates a Size or ProtoSize method for each message.
|
||||
This is useful with the MarshalTo method generated by the marshalto plugin and the
|
||||
gogoproto.marshaler and gogoproto.marshaler_all extensions.
|
||||
|
||||
It is enabled by the following extensions:
|
||||
|
||||
- sizer
|
||||
- sizer_all
|
||||
- protosizer
|
||||
- protosizer_all
|
||||
|
||||
The size plugin also generates a test given it is enabled using one of the following extensions:
|
||||
|
||||
- testgen
|
||||
- testgen_all
|
||||
|
||||
And a benchmark given it is enabled using one of the following extensions:
|
||||
|
||||
- benchgen
|
||||
- benchgen_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:
|
||||
|
||||
option (gogoproto.sizer_all) = true;
|
||||
|
||||
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 size plugin, will generate the following code:
|
||||
|
||||
func (m *B) Size() (n int) {
|
||||
var l int
|
||||
_ = l
|
||||
l = m.A.Size()
|
||||
n += 1 + l + sovExample(uint64(l))
|
||||
if len(m.G) > 0 {
|
||||
for _, e := range m.G {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovExample(uint64(l))
|
||||
}
|
||||
}
|
||||
if m.XXX_unrecognized != nil {
|
||||
n += len(m.XXX_unrecognized)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
and the following test code:
|
||||
|
||||
func TestBSize(t *testing5.T) {
|
||||
popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano()))
|
||||
p := NewPopulatedB(popr, true)
|
||||
dAtA, err := github_com_gogo_protobuf_proto2.Marshal(p)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
size := p.Size()
|
||||
if len(dAtA) != size {
|
||||
t.Fatalf("size %v != marshalled size %v", size, len(dAtA))
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkBSize(b *testing5.B) {
|
||||
popr := math_rand5.New(math_rand5.NewSource(616))
|
||||
total := 0
|
||||
pops := make([]*B, 1000)
|
||||
for i := 0; i < 1000; i++ {
|
||||
pops[i] = NewPopulatedB(popr, false)
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
total += pops[i%1000].Size()
|
||||
}
|
||||
b.SetBytes(int64(total / b.N))
|
||||
}
|
||||
|
||||
The sovExample function is a size of varint function for the example.pb.go file.
|
||||
|
||||
*/
|
||||
package size
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gogo/protobuf/gogoproto"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
|
||||
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
|
||||
"github.com/gogo/protobuf/vanity"
|
||||
)
|
||||
|
||||
type size struct {
|
||||
*generator.Generator
|
||||
generator.PluginImports
|
||||
atleastOne bool
|
||||
localName string
|
||||
typesPkg generator.Single
|
||||
}
|
||||
|
||||
func NewSize() *size {
|
||||
return &size{}
|
||||
}
|
||||
|
||||
func (p *size) Name() string {
|
||||
return "size"
|
||||
}
|
||||
|
||||
func (p *size) Init(g *generator.Generator) {
|
||||
p.Generator = g
|
||||
}
|
||||
|
||||
func wireToType(wire string) int {
|
||||
switch wire {
|
||||
case "fixed64":
|
||||
return proto.WireFixed64
|
||||
case "fixed32":
|
||||
return proto.WireFixed32
|
||||
case "varint":
|
||||
return proto.WireVarint
|
||||
case "bytes":
|
||||
return proto.WireBytes
|
||||
case "group":
|
||||
return proto.WireBytes
|
||||
case "zigzag32":
|
||||
return proto.WireVarint
|
||||
case "zigzag64":
|
||||
return proto.WireVarint
|
||||
}
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func keySize(fieldNumber int32, wireType int) int {
|
||||
x := uint32(fieldNumber)<<3 | uint32(wireType)
|
||||
size := 0
|
||||
for size = 0; x > 127; size++ {
|
||||
x >>= 7
|
||||
}
|
||||
size++
|
||||
return size
|
||||
}
|
||||
|
||||
func (p *size) sizeVarint() {
|
||||
p.P(`
|
||||
func sov`, p.localName, `(x uint64) (n int) {
|
||||
for {
|
||||
n++
|
||||
x >>= 7
|
||||
if x == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return n
|
||||
}`)
|
||||
}
|
||||
|
||||
func (p *size) sizeZigZag() {
|
||||
p.P(`func soz`, p.localName, `(x uint64) (n int) {
|
||||
return sov`, p.localName, `(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||
}`)
|
||||
}
|
||||
|
||||
func (p *size) std(field *descriptor.FieldDescriptorProto, name string) (string, bool) {
|
||||
if gogoproto.IsStdTime(field) {
|
||||
if gogoproto.IsNullable(field) {
|
||||
return p.typesPkg.Use() + `.SizeOfStdTime(*` + name + `)`, true
|
||||
} else {
|
||||
return p.typesPkg.Use() + `.SizeOfStdTime(` + name + `)`, true
|
||||
}
|
||||
} else if gogoproto.IsStdDuration(field) {
|
||||
if gogoproto.IsNullable(field) {
|
||||
return p.typesPkg.Use() + `.SizeOfStdDuration(*` + name + `)`, true
|
||||
} else {
|
||||
return p.typesPkg.Use() + `.SizeOfStdDuration(` + name + `)`, true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (p *size) generateField(proto3 bool, file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto, sizeName string) {
|
||||
fieldname := p.GetOneOfFieldName(message, field)
|
||||
nullable := gogoproto.IsNullable(field)
|
||||
repeated := field.IsRepeated()
|
||||
doNilCheck := gogoproto.NeedsNilCheck(proto3, field)
|
||||
if repeated {
|
||||
p.P(`if len(m.`, fieldname, `) > 0 {`)
|
||||
p.In()
|
||||
} else if doNilCheck {
|
||||
p.P(`if m.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
}
|
||||
packed := field.IsPacked() || (proto3 && field.IsPacked3())
|
||||
_, wire := p.GoType(message, field)
|
||||
wireType := wireToType(wire)
|
||||
fieldNumber := field.GetNumber()
|
||||
if packed {
|
||||
wireType = proto.WireBytes
|
||||
}
|
||||
key := keySize(fieldNumber, wireType)
|
||||
switch *field.Type {
|
||||
case descriptor.FieldDescriptorProto_TYPE_DOUBLE,
|
||||
descriptor.FieldDescriptorProto_TYPE_FIXED64,
|
||||
descriptor.FieldDescriptorProto_TYPE_SFIXED64:
|
||||
if packed {
|
||||
p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(len(m.`, fieldname, `)*8))`, `+len(m.`, fieldname, `)*8`)
|
||||
} else if repeated {
|
||||
p.P(`n+=`, strconv.Itoa(key+8), `*len(m.`, fieldname, `)`)
|
||||
} else if proto3 {
|
||||
p.P(`if m.`, fieldname, ` != 0 {`)
|
||||
p.In()
|
||||
p.P(`n+=`, strconv.Itoa(key+8))
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if nullable {
|
||||
p.P(`n+=`, strconv.Itoa(key+8))
|
||||
} else {
|
||||
p.P(`n+=`, strconv.Itoa(key+8))
|
||||
}
|
||||
case descriptor.FieldDescriptorProto_TYPE_FLOAT,
|
||||
descriptor.FieldDescriptorProto_TYPE_FIXED32,
|
||||
descriptor.FieldDescriptorProto_TYPE_SFIXED32:
|
||||
if packed {
|
||||
p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(len(m.`, fieldname, `)*4))`, `+len(m.`, fieldname, `)*4`)
|
||||
} else if repeated {
|
||||
p.P(`n+=`, strconv.Itoa(key+4), `*len(m.`, fieldname, `)`)
|
||||
} else if proto3 {
|
||||
p.P(`if m.`, fieldname, ` != 0 {`)
|
||||
p.In()
|
||||
p.P(`n+=`, strconv.Itoa(key+4))
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if nullable {
|
||||
p.P(`n+=`, strconv.Itoa(key+4))
|
||||
} else {
|
||||
p.P(`n+=`, strconv.Itoa(key+4))
|
||||
}
|
||||
case descriptor.FieldDescriptorProto_TYPE_INT64,
|
||||
descriptor.FieldDescriptorProto_TYPE_UINT64,
|
||||
descriptor.FieldDescriptorProto_TYPE_UINT32,
|
||||
descriptor.FieldDescriptorProto_TYPE_ENUM,
|
||||
descriptor.FieldDescriptorProto_TYPE_INT32:
|
||||
if packed {
|
||||
p.P(`l = 0`)
|
||||
p.P(`for _, e := range m.`, fieldname, ` {`)
|
||||
p.In()
|
||||
p.P(`l+=sov`, p.localName, `(uint64(e))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(l))+l`)
|
||||
} else if repeated {
|
||||
p.P(`for _, e := range m.`, fieldname, ` {`)
|
||||
p.In()
|
||||
p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(e))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if proto3 {
|
||||
p.P(`if m.`, fieldname, ` != 0 {`)
|
||||
p.In()
|
||||
p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(m.`, fieldname, `))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if nullable {
|
||||
p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(*m.`, fieldname, `))`)
|
||||
} else {
|
||||
p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(m.`, fieldname, `))`)
|
||||
}
|
||||
case descriptor.FieldDescriptorProto_TYPE_BOOL:
|
||||
if packed {
|
||||
p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(len(m.`, fieldname, `)))`, `+len(m.`, fieldname, `)*1`)
|
||||
} else if repeated {
|
||||
p.P(`n+=`, strconv.Itoa(key+1), `*len(m.`, fieldname, `)`)
|
||||
} else if proto3 {
|
||||
p.P(`if m.`, fieldname, ` {`)
|
||||
p.In()
|
||||
p.P(`n+=`, strconv.Itoa(key+1))
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if nullable {
|
||||
p.P(`n+=`, strconv.Itoa(key+1))
|
||||
} else {
|
||||
p.P(`n+=`, strconv.Itoa(key+1))
|
||||
}
|
||||
case descriptor.FieldDescriptorProto_TYPE_STRING:
|
||||
if repeated {
|
||||
p.P(`for _, s := range m.`, fieldname, ` { `)
|
||||
p.In()
|
||||
p.P(`l = len(s)`)
|
||||
p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if proto3 {
|
||||
p.P(`l=len(m.`, fieldname, `)`)
|
||||
p.P(`if l > 0 {`)
|
||||
p.In()
|
||||
p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if nullable {
|
||||
p.P(`l=len(*m.`, fieldname, `)`)
|
||||
p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
|
||||
} else {
|
||||
p.P(`l=len(m.`, fieldname, `)`)
|
||||
p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
|
||||
}
|
||||
case descriptor.FieldDescriptorProto_TYPE_GROUP:
|
||||
panic(fmt.Errorf("size does not support group %v", fieldname))
|
||||
case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
|
||||
if p.IsMap(field) {
|
||||
m := p.GoMapType(nil, field)
|
||||
_, keywire := p.GoType(nil, m.KeyAliasField)
|
||||
valuegoTyp, _ := p.GoType(nil, m.ValueField)
|
||||
valuegoAliasTyp, valuewire := p.GoType(nil, m.ValueAliasField)
|
||||
_, fieldwire := p.GoType(nil, field)
|
||||
|
||||
nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp)
|
||||
|
||||
fieldKeySize := keySize(field.GetNumber(), wireToType(fieldwire))
|
||||
keyKeySize := keySize(1, wireToType(keywire))
|
||||
valueKeySize := keySize(2, wireToType(valuewire))
|
||||
p.P(`for k, v := range m.`, fieldname, ` { `)
|
||||
p.In()
|
||||
p.P(`_ = k`)
|
||||
p.P(`_ = v`)
|
||||
sum := []string{strconv.Itoa(keyKeySize)}
|
||||
switch m.KeyField.GetType() {
|
||||
case descriptor.FieldDescriptorProto_TYPE_DOUBLE,
|
||||
descriptor.FieldDescriptorProto_TYPE_FIXED64,
|
||||
descriptor.FieldDescriptorProto_TYPE_SFIXED64:
|
||||
sum = append(sum, `8`)
|
||||
case descriptor.FieldDescriptorProto_TYPE_FLOAT,
|
||||
descriptor.FieldDescriptorProto_TYPE_FIXED32,
|
||||
descriptor.FieldDescriptorProto_TYPE_SFIXED32:
|
||||
sum = append(sum, `4`)
|
||||
case descriptor.FieldDescriptorProto_TYPE_INT64,
|
||||
descriptor.FieldDescriptorProto_TYPE_UINT64,
|
||||
descriptor.FieldDescriptorProto_TYPE_UINT32,
|
||||
descriptor.FieldDescriptorProto_TYPE_ENUM,
|
||||
descriptor.FieldDescriptorProto_TYPE_INT32:
|
||||
sum = append(sum, `sov`+p.localName+`(uint64(k))`)
|
||||
case descriptor.FieldDescriptorProto_TYPE_BOOL:
|
||||
sum = append(sum, `1`)
|
||||
case descriptor.FieldDescriptorProto_TYPE_STRING,
|
||||
descriptor.FieldDescriptorProto_TYPE_BYTES:
|
||||
sum = append(sum, `len(k)+sov`+p.localName+`(uint64(len(k)))`)
|
||||
case descriptor.FieldDescriptorProto_TYPE_SINT32,
|
||||
descriptor.FieldDescriptorProto_TYPE_SINT64:
|
||||
sum = append(sum, `soz`+p.localName+`(uint64(k))`)
|
||||
}
|
||||
switch m.ValueField.GetType() {
|
||||
case descriptor.FieldDescriptorProto_TYPE_DOUBLE,
|
||||
descriptor.FieldDescriptorProto_TYPE_FIXED64,
|
||||
descriptor.FieldDescriptorProto_TYPE_SFIXED64:
|
||||
sum = append(sum, strconv.Itoa(valueKeySize))
|
||||
sum = append(sum, strconv.Itoa(8))
|
||||
case descriptor.FieldDescriptorProto_TYPE_FLOAT,
|
||||
descriptor.FieldDescriptorProto_TYPE_FIXED32,
|
||||
descriptor.FieldDescriptorProto_TYPE_SFIXED32:
|
||||
sum = append(sum, strconv.Itoa(valueKeySize))
|
||||
sum = append(sum, strconv.Itoa(4))
|
||||
case descriptor.FieldDescriptorProto_TYPE_INT64,
|
||||
descriptor.FieldDescriptorProto_TYPE_UINT64,
|
||||
descriptor.FieldDescriptorProto_TYPE_UINT32,
|
||||
descriptor.FieldDescriptorProto_TYPE_ENUM,
|
||||
descriptor.FieldDescriptorProto_TYPE_INT32:
|
||||
sum = append(sum, strconv.Itoa(valueKeySize))
|
||||
sum = append(sum, `sov`+p.localName+`(uint64(v))`)
|
||||
case descriptor.FieldDescriptorProto_TYPE_BOOL:
|
||||
sum = append(sum, strconv.Itoa(valueKeySize))
|
||||
sum = append(sum, `1`)
|
||||
case descriptor.FieldDescriptorProto_TYPE_STRING:
|
||||
sum = append(sum, strconv.Itoa(valueKeySize))
|
||||
sum = append(sum, `len(v)+sov`+p.localName+`(uint64(len(v)))`)
|
||||
case descriptor.FieldDescriptorProto_TYPE_BYTES:
|
||||
if gogoproto.IsCustomType(field) {
|
||||
p.P(`l = 0`)
|
||||
if nullable {
|
||||
p.P(`if v != nil {`)
|
||||
p.In()
|
||||
}
|
||||
p.P(`l = v.`, sizeName, `()`)
|
||||
p.P(`l += `, strconv.Itoa(valueKeySize), ` + sov`+p.localName+`(uint64(l))`)
|
||||
if nullable {
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
sum = append(sum, `l`)
|
||||
} else {
|
||||
p.P(`l = 0`)
|
||||
if proto3 {
|
||||
p.P(`if len(v) > 0 {`)
|
||||
} else {
|
||||
p.P(`if v != nil {`)
|
||||
}
|
||||
p.In()
|
||||
p.P(`l = `, strconv.Itoa(valueKeySize), ` + len(v)+sov`+p.localName+`(uint64(len(v)))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
sum = append(sum, `l`)
|
||||
}
|
||||
case descriptor.FieldDescriptorProto_TYPE_SINT32,
|
||||
descriptor.FieldDescriptorProto_TYPE_SINT64:
|
||||
sum = append(sum, strconv.Itoa(valueKeySize))
|
||||
sum = append(sum, `soz`+p.localName+`(uint64(v))`)
|
||||
case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
|
||||
stdSizeCall, stdOk := p.std(field, "v")
|
||||
if nullable {
|
||||
p.P(`l = 0`)
|
||||
p.P(`if v != nil {`)
|
||||
p.In()
|
||||
if stdOk {
|
||||
p.P(`l = `, stdSizeCall)
|
||||
} else if valuegoTyp != valuegoAliasTyp {
|
||||
p.P(`l = ((`, valuegoTyp, `)(v)).`, sizeName, `()`)
|
||||
} else {
|
||||
p.P(`l = v.`, sizeName, `()`)
|
||||
}
|
||||
p.P(`l += `, strconv.Itoa(valueKeySize), ` + sov`+p.localName+`(uint64(l))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
sum = append(sum, `l`)
|
||||
} else {
|
||||
if stdOk {
|
||||
p.P(`l = `, stdSizeCall)
|
||||
} else if valuegoTyp != valuegoAliasTyp {
|
||||
p.P(`l = ((*`, valuegoTyp, `)(&v)).`, sizeName, `()`)
|
||||
} else {
|
||||
p.P(`l = v.`, sizeName, `()`)
|
||||
}
|
||||
sum = append(sum, strconv.Itoa(valueKeySize))
|
||||
sum = append(sum, `l+sov`+p.localName+`(uint64(l))`)
|
||||
}
|
||||
}
|
||||
p.P(`mapEntrySize := `, strings.Join(sum, "+"))
|
||||
p.P(`n+=mapEntrySize+`, fieldKeySize, `+sov`, p.localName, `(uint64(mapEntrySize))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if repeated {
|
||||
p.P(`for _, e := range m.`, fieldname, ` { `)
|
||||
p.In()
|
||||
stdSizeCall, stdOk := p.std(field, "e")
|
||||
if stdOk {
|
||||
p.P(`l=`, stdSizeCall)
|
||||
} else {
|
||||
p.P(`l=e.`, sizeName, `()`)
|
||||
}
|
||||
p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else {
|
||||
stdSizeCall, stdOk := p.std(field, "m."+fieldname)
|
||||
if stdOk {
|
||||
p.P(`l=`, stdSizeCall)
|
||||
} else {
|
||||
p.P(`l=m.`, fieldname, `.`, sizeName, `()`)
|
||||
}
|
||||
p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
|
||||
}
|
||||
case descriptor.FieldDescriptorProto_TYPE_BYTES:
|
||||
if !gogoproto.IsCustomType(field) {
|
||||
if repeated {
|
||||
p.P(`for _, b := range m.`, fieldname, ` { `)
|
||||
p.In()
|
||||
p.P(`l = len(b)`)
|
||||
p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if proto3 {
|
||||
p.P(`l=len(m.`, fieldname, `)`)
|
||||
p.P(`if l > 0 {`)
|
||||
p.In()
|
||||
p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else {
|
||||
p.P(`l=len(m.`, fieldname, `)`)
|
||||
p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
|
||||
}
|
||||
} else {
|
||||
if repeated {
|
||||
p.P(`for _, e := range m.`, fieldname, ` { `)
|
||||
p.In()
|
||||
p.P(`l=e.`, sizeName, `()`)
|
||||
p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else {
|
||||
p.P(`l=m.`, fieldname, `.`, sizeName, `()`)
|
||||
p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
|
||||
}
|
||||
}
|
||||
case descriptor.FieldDescriptorProto_TYPE_SINT32,
|
||||
descriptor.FieldDescriptorProto_TYPE_SINT64:
|
||||
if packed {
|
||||
p.P(`l = 0`)
|
||||
p.P(`for _, e := range m.`, fieldname, ` {`)
|
||||
p.In()
|
||||
p.P(`l+=soz`, p.localName, `(uint64(e))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(l))+l`)
|
||||
} else if repeated {
|
||||
p.P(`for _, e := range m.`, fieldname, ` {`)
|
||||
p.In()
|
||||
p.P(`n+=`, strconv.Itoa(key), `+soz`, p.localName, `(uint64(e))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if proto3 {
|
||||
p.P(`if m.`, fieldname, ` != 0 {`)
|
||||
p.In()
|
||||
p.P(`n+=`, strconv.Itoa(key), `+soz`, p.localName, `(uint64(m.`, fieldname, `))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
} else if nullable {
|
||||
p.P(`n+=`, strconv.Itoa(key), `+soz`, p.localName, `(uint64(*m.`, fieldname, `))`)
|
||||
} else {
|
||||
p.P(`n+=`, strconv.Itoa(key), `+soz`, p.localName, `(uint64(m.`, fieldname, `))`)
|
||||
}
|
||||
default:
|
||||
panic("not implemented")
|
||||
}
|
||||
if repeated || doNilCheck {
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *size) Generate(file *generator.FileDescriptor) {
|
||||
p.PluginImports = generator.NewPluginImports(p.Generator)
|
||||
p.atleastOne = false
|
||||
p.localName = generator.FileName(file)
|
||||
p.typesPkg = p.NewImport("github.com/gogo/protobuf/types")
|
||||
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() {
|
||||
sizeName := ""
|
||||
if gogoproto.IsSizer(file.FileDescriptorProto, message.DescriptorProto) && gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
fmt.Fprintf(os.Stderr, "ERROR: message %v cannot support both sizer and protosizer plugins\n", generator.CamelCase(*message.Name))
|
||||
os.Exit(1)
|
||||
}
|
||||
if gogoproto.IsSizer(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
sizeName = "Size"
|
||||
} else if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
sizeName = "ProtoSize"
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
if message.DescriptorProto.GetOptions().GetMapEntry() {
|
||||
continue
|
||||
}
|
||||
p.atleastOne = true
|
||||
ccTypeName := generator.CamelCaseSlice(message.TypeName())
|
||||
p.P(`func (m *`, ccTypeName, `) `, sizeName, `() (n int) {`)
|
||||
p.In()
|
||||
p.P(`var l int`)
|
||||
p.P(`_ = l`)
|
||||
oneofs := make(map[string]struct{})
|
||||
for _, field := range message.Field {
|
||||
oneof := field.OneofIndex != nil
|
||||
if !oneof {
|
||||
proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
|
||||
p.generateField(proto3, file, message, field, sizeName)
|
||||
} else {
|
||||
fieldname := p.GetFieldName(message, field)
|
||||
if _, ok := oneofs[fieldname]; ok {
|
||||
continue
|
||||
} else {
|
||||
oneofs[fieldname] = struct{}{}
|
||||
}
|
||||
p.P(`if m.`, fieldname, ` != nil {`)
|
||||
p.In()
|
||||
p.P(`n+=m.`, fieldname, `.`, sizeName, `()`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
if message.DescriptorProto.HasExtension() {
|
||||
if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
p.P(`n += `, protoPkg.Use(), `.SizeOfInternalExtension(m)`)
|
||||
} else {
|
||||
p.P(`if m.XXX_extensions != nil {`)
|
||||
p.In()
|
||||
p.P(`n+=len(m.XXX_extensions)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
p.P(`if m.XXX_unrecognized != nil {`)
|
||||
p.In()
|
||||
p.P(`n+=len(m.XXX_unrecognized)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
p.P(`return n`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P()
|
||||
|
||||
//Generate Size methods for oneof fields
|
||||
m := proto.Clone(message.DescriptorProto).(*descriptor.DescriptorProto)
|
||||
for _, f := range m.Field {
|
||||
oneof := f.OneofIndex != nil
|
||||
if !oneof {
|
||||
continue
|
||||
}
|
||||
ccTypeName := p.OneOfTypeName(message, f)
|
||||
p.P(`func (m *`, ccTypeName, `) `, sizeName, `() (n int) {`)
|
||||
p.In()
|
||||
p.P(`var l int`)
|
||||
p.P(`_ = l`)
|
||||
vanity.TurnOffNullableForNativeTypes(f)
|
||||
p.generateField(false, file, message, f, sizeName)
|
||||
p.P(`return n`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
|
||||
if !p.atleastOne {
|
||||
return
|
||||
}
|
||||
|
||||
p.sizeVarint()
|
||||
p.sizeZigZag()
|
||||
|
||||
}
|
||||
|
||||
func init() {
|
||||
generator.RegisterPlugin(NewSize())
|
||||
}
|
134
vendor/github.com/gogo/protobuf/plugin/size/sizetest.go
generated
vendored
Normal file
134
vendor/github.com/gogo/protobuf/plugin/size/sizetest.go
generated
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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())
|
||||
sizeName := ""
|
||||
if gogoproto.IsSizer(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
sizeName = "Size"
|
||||
} else if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
sizeName = "ProtoSize"
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
if message.DescriptorProto.GetOptions().GetMapEntry() {
|
||||
continue
|
||||
}
|
||||
|
||||
if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
used = true
|
||||
p.P(`func Test`, ccTypeName, sizeName, `(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.`, sizeName, `()`)
|
||||
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, sizeName, `(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].`, sizeName, `()`)
|
||||
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)
|
||||
}
|
296
vendor/github.com/gogo/protobuf/plugin/stringer/stringer.go
generated
vendored
Normal file
296
vendor/github.com/gogo/protobuf/plugin/stringer/stringer.go
generated
vendored
Normal file
@ -0,0 +1,296 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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 stringer plugin generates a String method for each message.
|
||||
|
||||
It is enabled by the following extensions:
|
||||
|
||||
- stringer
|
||||
- stringer_all
|
||||
|
||||
The stringer 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:
|
||||
|
||||
option (gogoproto.goproto_stringer_all) = false;
|
||||
option (gogoproto.stringer_all) = true;
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
given to the stringer stringer, will generate the following code:
|
||||
|
||||
func (this *A) String() string {
|
||||
if this == nil {
|
||||
return "nil"
|
||||
}
|
||||
s := strings.Join([]string{`&A{`,
|
||||
`Description:` + fmt.Sprintf("%v", this.Description) + `,`,
|
||||
`Number:` + fmt.Sprintf("%v", this.Number) + `,`,
|
||||
`Id:` + fmt.Sprintf("%v", this.Id) + `,`,
|
||||
`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`,
|
||||
`}`,
|
||||
}, "")
|
||||
return s
|
||||
}
|
||||
|
||||
and the following test code:
|
||||
|
||||
func TestAStringer(t *testing4.T) {
|
||||
popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano()))
|
||||
p := NewPopulatedA(popr, false)
|
||||
s1 := p.String()
|
||||
s2 := fmt1.Sprintf("%v", p)
|
||||
if s1 != s2 {
|
||||
t.Fatalf("String want %v got %v", s1, s2)
|
||||
}
|
||||
}
|
||||
|
||||
Typically fmt.Printf("%v") will stop to print when it reaches a pointer and
|
||||
not print their values, while the generated String method will always print all values, recursively.
|
||||
|
||||
*/
|
||||
package stringer
|
||||
|
||||
import (
|
||||
"github.com/gogo/protobuf/gogoproto"
|
||||
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type stringer struct {
|
||||
*generator.Generator
|
||||
generator.PluginImports
|
||||
atleastOne bool
|
||||
localName string
|
||||
}
|
||||
|
||||
func NewStringer() *stringer {
|
||||
return &stringer{}
|
||||
}
|
||||
|
||||
func (p *stringer) Name() string {
|
||||
return "stringer"
|
||||
}
|
||||
|
||||
func (p *stringer) Init(g *generator.Generator) {
|
||||
p.Generator = g
|
||||
}
|
||||
|
||||
func (p *stringer) Generate(file *generator.FileDescriptor) {
|
||||
proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
|
||||
p.PluginImports = generator.NewPluginImports(p.Generator)
|
||||
p.atleastOne = false
|
||||
|
||||
p.localName = generator.FileName(file)
|
||||
|
||||
fmtPkg := p.NewImport("fmt")
|
||||
stringsPkg := p.NewImport("strings")
|
||||
reflectPkg := p.NewImport("reflect")
|
||||
sortKeysPkg := p.NewImport("github.com/gogo/protobuf/sortkeys")
|
||||
protoPkg := p.NewImport("github.com/gogo/protobuf/proto")
|
||||
for _, message := range file.Messages() {
|
||||
if !gogoproto.IsStringer(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
continue
|
||||
}
|
||||
if gogoproto.EnabledGoStringer(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
panic("old string method needs to be disabled, please use gogoproto.goproto_stringer or gogoproto.goproto_stringer_all and set it to false")
|
||||
}
|
||||
if message.DescriptorProto.GetOptions().GetMapEntry() {
|
||||
continue
|
||||
}
|
||||
p.atleastOne = true
|
||||
ccTypeName := generator.CamelCaseSlice(message.TypeName())
|
||||
p.P(`func (this *`, ccTypeName, `) String() string {`)
|
||||
p.In()
|
||||
p.P(`if this == nil {`)
|
||||
p.In()
|
||||
p.P(`return "nil"`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
for _, field := range message.Field {
|
||||
if !p.IsMap(field) {
|
||||
continue
|
||||
}
|
||||
fieldname := p.GetFieldName(message, field)
|
||||
|
||||
m := p.GoMapType(nil, field)
|
||||
mapgoTyp, keyField, keyAliasField := m.GoType, m.KeyField, m.KeyAliasField
|
||||
keysName := `keysFor` + fieldname
|
||||
keygoTyp, _ := p.GoType(nil, keyField)
|
||||
keygoTyp = strings.Replace(keygoTyp, "*", "", 1)
|
||||
keygoAliasTyp, _ := p.GoType(nil, keyAliasField)
|
||||
keygoAliasTyp = strings.Replace(keygoAliasTyp, "*", "", 1)
|
||||
keyCapTyp := generator.CamelCase(keygoTyp)
|
||||
p.P(keysName, ` := make([]`, keygoTyp, `, 0, len(this.`, fieldname, `))`)
|
||||
p.P(`for k, _ := range this.`, fieldname, ` {`)
|
||||
p.In()
|
||||
if keygoAliasTyp == keygoTyp {
|
||||
p.P(keysName, ` = append(`, keysName, `, k)`)
|
||||
} else {
|
||||
p.P(keysName, ` = append(`, keysName, `, `, keygoTyp, `(k))`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(sortKeysPkg.Use(), `.`, keyCapTyp, `s(`, keysName, `)`)
|
||||
mapName := `mapStringFor` + fieldname
|
||||
p.P(mapName, ` := "`, mapgoTyp, `{"`)
|
||||
p.P(`for _, k := range `, keysName, ` {`)
|
||||
p.In()
|
||||
if keygoAliasTyp == keygoTyp {
|
||||
p.P(mapName, ` += fmt.Sprintf("%v: %v,", k, this.`, fieldname, `[k])`)
|
||||
} else {
|
||||
p.P(mapName, ` += fmt.Sprintf("%v: %v,", k, this.`, fieldname, `[`, keygoAliasTyp, `(k)])`)
|
||||
}
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(mapName, ` += "}"`)
|
||||
}
|
||||
p.P("s := ", stringsPkg.Use(), ".Join([]string{`&", ccTypeName, "{`,")
|
||||
oneofs := make(map[string]struct{})
|
||||
for _, field := range message.Field {
|
||||
nullable := gogoproto.IsNullable(field)
|
||||
repeated := field.IsRepeated()
|
||||
fieldname := p.GetFieldName(message, field)
|
||||
oneof := field.OneofIndex != nil
|
||||
if oneof {
|
||||
if _, ok := oneofs[fieldname]; ok {
|
||||
continue
|
||||
} else {
|
||||
oneofs[fieldname] = struct{}{}
|
||||
}
|
||||
p.P("`", fieldname, ":`", ` + `, fmtPkg.Use(), `.Sprintf("%v", this.`, fieldname, ") + `,", "`,")
|
||||
} else if p.IsMap(field) {
|
||||
mapName := `mapStringFor` + fieldname
|
||||
p.P("`", fieldname, ":`", ` + `, mapName, " + `,", "`,")
|
||||
} else if (field.IsMessage() && !gogoproto.IsCustomType(field)) || p.IsGroup(field) {
|
||||
desc := p.ObjectNamed(field.GetTypeName())
|
||||
msgname := p.TypeName(desc)
|
||||
msgnames := strings.Split(msgname, ".")
|
||||
typeName := msgnames[len(msgnames)-1]
|
||||
if nullable {
|
||||
p.P("`", fieldname, ":`", ` + `, stringsPkg.Use(), `.Replace(`, fmtPkg.Use(), `.Sprintf("%v", this.`, fieldname, `), "`, typeName, `","`, msgname, `"`, ", 1) + `,", "`,")
|
||||
} else if repeated {
|
||||
p.P("`", fieldname, ":`", ` + `, stringsPkg.Use(), `.Replace(`, stringsPkg.Use(), `.Replace(`, fmtPkg.Use(), `.Sprintf("%v", this.`, fieldname, `), "`, typeName, `","`, msgname, `"`, ", 1),`&`,``,1) + `,", "`,")
|
||||
} else {
|
||||
p.P("`", fieldname, ":`", ` + `, stringsPkg.Use(), `.Replace(`, stringsPkg.Use(), `.Replace(this.`, fieldname, `.String(), "`, typeName, `","`, msgname, `"`, ", 1),`&`,``,1) + `,", "`,")
|
||||
}
|
||||
} else {
|
||||
if nullable && !repeated && !proto3 {
|
||||
p.P("`", fieldname, ":`", ` + valueToString`, p.localName, `(this.`, fieldname, ") + `,", "`,")
|
||||
} else {
|
||||
p.P("`", fieldname, ":`", ` + `, fmtPkg.Use(), `.Sprintf("%v", this.`, fieldname, ") + `,", "`,")
|
||||
}
|
||||
}
|
||||
}
|
||||
if message.DescriptorProto.HasExtension() {
|
||||
if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
p.P("`XXX_InternalExtensions:` + ", protoPkg.Use(), ".StringFromInternalExtension(this) + `,`,")
|
||||
} else {
|
||||
p.P("`XXX_extensions:` + ", protoPkg.Use(), ".StringFromExtensionsBytes(this.XXX_extensions) + `,`,")
|
||||
}
|
||||
}
|
||||
if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
p.P("`XXX_unrecognized:` + ", fmtPkg.Use(), `.Sprintf("%v", this.XXX_unrecognized) + `, "`,`,")
|
||||
}
|
||||
p.P("`}`,")
|
||||
p.P(`}`, `,""`, ")")
|
||||
p.P(`return s`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
|
||||
//Generate String methods for oneof fields
|
||||
for _, field := range message.Field {
|
||||
oneof := field.OneofIndex != nil
|
||||
if !oneof {
|
||||
continue
|
||||
}
|
||||
ccTypeName := p.OneOfTypeName(message, field)
|
||||
p.P(`func (this *`, ccTypeName, `) String() string {`)
|
||||
p.In()
|
||||
p.P(`if this == nil {`)
|
||||
p.In()
|
||||
p.P(`return "nil"`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P("s := ", stringsPkg.Use(), ".Join([]string{`&", ccTypeName, "{`,")
|
||||
fieldname := p.GetOneOfFieldName(message, field)
|
||||
if field.IsMessage() || p.IsGroup(field) {
|
||||
desc := p.ObjectNamed(field.GetTypeName())
|
||||
msgname := p.TypeName(desc)
|
||||
msgnames := strings.Split(msgname, ".")
|
||||
typeName := msgnames[len(msgnames)-1]
|
||||
p.P("`", fieldname, ":`", ` + `, stringsPkg.Use(), `.Replace(`, fmtPkg.Use(), `.Sprintf("%v", this.`, fieldname, `), "`, typeName, `","`, msgname, `"`, ", 1) + `,", "`,")
|
||||
} else {
|
||||
p.P("`", fieldname, ":`", ` + `, fmtPkg.Use(), `.Sprintf("%v", this.`, fieldname, ") + `,", "`,")
|
||||
}
|
||||
p.P("`}`,")
|
||||
p.P(`}`, `,""`, ")")
|
||||
p.P(`return s`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
|
||||
if !p.atleastOne {
|
||||
return
|
||||
}
|
||||
|
||||
p.P(`func valueToString`, p.localName, `(v interface{}) string {`)
|
||||
p.In()
|
||||
p.P(`rv := `, reflectPkg.Use(), `.ValueOf(v)`)
|
||||
p.P(`if rv.IsNil() {`)
|
||||
p.In()
|
||||
p.P(`return "nil"`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`pv := `, reflectPkg.Use(), `.Indirect(rv).Interface()`)
|
||||
p.P(`return `, fmtPkg.Use(), `.Sprintf("*%v", pv)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
|
||||
}
|
||||
|
||||
func init() {
|
||||
generator.RegisterPlugin(NewStringer())
|
||||
}
|
83
vendor/github.com/gogo/protobuf/plugin/stringer/stringertest.go
generated
vendored
Normal file
83
vendor/github.com/gogo/protobuf/plugin/stringer/stringertest.go
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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)
|
||||
}
|
608
vendor/github.com/gogo/protobuf/plugin/testgen/testgen.go
generated
vendored
Normal file
608
vendor/github.com/gogo/protobuf/plugin/testgen/testgen.go
generated
vendored
Normal file
@ -0,0 +1,608 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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 testgen plugin generates Test and Benchmark functions for each message.
|
||||
|
||||
Tests are enabled using the following extensions:
|
||||
|
||||
- testgen
|
||||
- testgen_all
|
||||
|
||||
Benchmarks are enabled using the following extensions:
|
||||
|
||||
- benchgen
|
||||
- benchgen_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:
|
||||
|
||||
option (gogoproto.testgen_all) = true;
|
||||
option (gogoproto.benchgen_all) = true;
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
given to the testgen plugin, will generate the following test code:
|
||||
|
||||
func TestAProto(t *testing.T) {
|
||||
popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano()))
|
||||
p := NewPopulatedA(popr, false)
|
||||
dAtA, err := github_com_gogo_protobuf_proto.Marshal(p)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
msg := &A{}
|
||||
if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for i := range dAtA {
|
||||
dAtA[i] = byte(popr.Intn(256))
|
||||
}
|
||||
if err := p.VerboseEqual(msg); err != nil {
|
||||
t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err)
|
||||
}
|
||||
if !p.Equal(msg) {
|
||||
t.Fatalf("%#v !Proto %#v", msg, p)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAProtoMarshal(b *testing.B) {
|
||||
popr := math_rand.New(math_rand.NewSource(616))
|
||||
total := 0
|
||||
pops := make([]*A, 10000)
|
||||
for i := 0; i < 10000; i++ {
|
||||
pops[i] = NewPopulatedA(popr, false)
|
||||
}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
dAtA, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
total += len(dAtA)
|
||||
}
|
||||
b.SetBytes(int64(total / b.N))
|
||||
}
|
||||
|
||||
func BenchmarkAProtoUnmarshal(b *testing.B) {
|
||||
popr := math_rand.New(math_rand.NewSource(616))
|
||||
total := 0
|
||||
datas := make([][]byte, 10000)
|
||||
for i := 0; i < 10000; i++ {
|
||||
dAtA, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedA(popr, false))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
datas[i] = dAtA
|
||||
}
|
||||
msg := &A{}
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
total += len(datas[i%10000])
|
||||
if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
b.SetBytes(int64(total / b.N))
|
||||
}
|
||||
|
||||
|
||||
func TestAJSON(t *testing1.T) {
|
||||
popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano()))
|
||||
p := NewPopulatedA(popr, true)
|
||||
jsondata, err := encoding_json.Marshal(p)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
msg := &A{}
|
||||
err = encoding_json.Unmarshal(jsondata, msg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := p.VerboseEqual(msg); err != nil {
|
||||
t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err)
|
||||
}
|
||||
if !p.Equal(msg) {
|
||||
t.Fatalf("%#v !Json Equal %#v", msg, p)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAProtoText(t *testing2.T) {
|
||||
popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano()))
|
||||
p := NewPopulatedA(popr, true)
|
||||
dAtA := github_com_gogo_protobuf_proto1.MarshalTextString(p)
|
||||
msg := &A{}
|
||||
if err := github_com_gogo_protobuf_proto1.UnmarshalText(dAtA, msg); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := p.VerboseEqual(msg); err != nil {
|
||||
t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err)
|
||||
}
|
||||
if !p.Equal(msg) {
|
||||
t.Fatalf("%#v !Proto %#v", msg, p)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAProtoCompactText(t *testing2.T) {
|
||||
popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano()))
|
||||
p := NewPopulatedA(popr, true)
|
||||
dAtA := github_com_gogo_protobuf_proto1.CompactTextString(p)
|
||||
msg := &A{}
|
||||
if err := github_com_gogo_protobuf_proto1.UnmarshalText(dAtA, msg); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := p.VerboseEqual(msg); err != nil {
|
||||
t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err)
|
||||
}
|
||||
if !p.Equal(msg) {
|
||||
t.Fatalf("%#v !Proto %#v", msg, p)
|
||||
}
|
||||
}
|
||||
|
||||
Other registered tests are also generated.
|
||||
Tests are registered to this test plugin by calling the following function.
|
||||
|
||||
func RegisterTestPlugin(newFunc NewTestPlugin)
|
||||
|
||||
where NewTestPlugin is:
|
||||
|
||||
type NewTestPlugin func(g *generator.Generator) TestPlugin
|
||||
|
||||
and TestPlugin is an interface:
|
||||
|
||||
type TestPlugin interface {
|
||||
Generate(imports generator.PluginImports, file *generator.FileDescriptor) (used bool)
|
||||
}
|
||||
|
||||
Plugins that use this interface include:
|
||||
|
||||
- populate
|
||||
- gostring
|
||||
- equal
|
||||
- union
|
||||
- and more
|
||||
|
||||
Please look at these plugins as examples of how to create your own.
|
||||
A good idea is to let each plugin generate its own tests.
|
||||
|
||||
*/
|
||||
package testgen
|
||||
|
||||
import (
|
||||
"github.com/gogo/protobuf/gogoproto"
|
||||
"github.com/gogo/protobuf/protoc-gen-gogo/generator"
|
||||
)
|
||||
|
||||
type TestPlugin interface {
|
||||
Generate(imports generator.PluginImports, file *generator.FileDescriptor) (used bool)
|
||||
}
|
||||
|
||||
type NewTestPlugin func(g *generator.Generator) TestPlugin
|
||||
|
||||
var testplugins = make([]NewTestPlugin, 0)
|
||||
|
||||
func RegisterTestPlugin(newFunc NewTestPlugin) {
|
||||
testplugins = append(testplugins, newFunc)
|
||||
}
|
||||
|
||||
type plugin struct {
|
||||
*generator.Generator
|
||||
generator.PluginImports
|
||||
tests []TestPlugin
|
||||
}
|
||||
|
||||
func NewPlugin() *plugin {
|
||||
return &plugin{}
|
||||
}
|
||||
|
||||
func (p *plugin) Name() string {
|
||||
return "testgen"
|
||||
}
|
||||
|
||||
func (p *plugin) Init(g *generator.Generator) {
|
||||
p.Generator = g
|
||||
p.tests = make([]TestPlugin, 0, len(testplugins))
|
||||
for i := range testplugins {
|
||||
p.tests = append(p.tests, testplugins[i](g))
|
||||
}
|
||||
}
|
||||
|
||||
func (p *plugin) Generate(file *generator.FileDescriptor) {
|
||||
p.PluginImports = generator.NewPluginImports(p.Generator)
|
||||
atLeastOne := false
|
||||
for i := range p.tests {
|
||||
used := p.tests[i].Generate(p.PluginImports, file)
|
||||
if used {
|
||||
atLeastOne = true
|
||||
}
|
||||
}
|
||||
if atLeastOne {
|
||||
p.P(`//These tests are generated by github.com/gogo/protobuf/plugin/testgen`)
|
||||
}
|
||||
}
|
||||
|
||||
type testProto struct {
|
||||
*generator.Generator
|
||||
}
|
||||
|
||||
func newProto(g *generator.Generator) TestPlugin {
|
||||
return &testProto{g}
|
||||
}
|
||||
|
||||
func (p *testProto) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
|
||||
used := false
|
||||
testingPkg := imports.NewImport("testing")
|
||||
randPkg := imports.NewImport("math/rand")
|
||||
timePkg := imports.NewImport("time")
|
||||
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 message.DescriptorProto.GetOptions().GetMapEntry() {
|
||||
continue
|
||||
}
|
||||
if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
used = true
|
||||
|
||||
p.P(`func Test`, ccTypeName, `Proto(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, false)`)
|
||||
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(`msg := &`, ccTypeName, `{}`)
|
||||
p.P(`if err := `, protoPkg.Use(), `.Unmarshal(dAtA, msg); err != nil {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`littlefuzz := make([]byte, len(dAtA))`)
|
||||
p.P(`copy(littlefuzz, dAtA)`)
|
||||
p.P(`for i := range dAtA {`)
|
||||
p.In()
|
||||
p.P(`dAtA[i] = byte(popr.Intn(256))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
if gogoproto.HasVerboseEqual(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
p.P(`if err := p.VerboseEqual(msg); err != nil {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
p.P(`if !p.Equal(msg) {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`if len(littlefuzz) > 0 {`)
|
||||
p.In()
|
||||
p.P(`fuzzamount := 100`)
|
||||
p.P(`for i := 0; i < fuzzamount; i++ {`)
|
||||
p.In()
|
||||
p.P(`littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256))`)
|
||||
p.P(`littlefuzz = append(littlefuzz, byte(popr.Intn(256)))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`// shouldn't panic`)
|
||||
p.P(`_ = `, protoPkg.Use(), `.Unmarshal(littlefuzz, msg)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P()
|
||||
}
|
||||
|
||||
if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
if gogoproto.IsMarshaler(file.FileDescriptorProto, message.DescriptorProto) || gogoproto.IsUnsafeMarshaler(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
p.P(`func Test`, ccTypeName, `MarshalTo(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, false)`)
|
||||
if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
p.P(`size := p.ProtoSize()`)
|
||||
} else {
|
||||
p.P(`size := p.Size()`)
|
||||
}
|
||||
p.P(`dAtA := make([]byte, size)`)
|
||||
p.P(`for i := range dAtA {`)
|
||||
p.In()
|
||||
p.P(`dAtA[i] = byte(popr.Intn(256))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`_, err := p.MarshalTo(dAtA)`)
|
||||
p.P(`if err != nil {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`msg := &`, ccTypeName, `{}`)
|
||||
p.P(`if err := `, protoPkg.Use(), `.Unmarshal(dAtA, msg); err != nil {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`for i := range dAtA {`)
|
||||
p.In()
|
||||
p.P(`dAtA[i] = byte(popr.Intn(256))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
if gogoproto.HasVerboseEqual(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
p.P(`if err := p.VerboseEqual(msg); err != nil {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
p.P(`if !p.Equal(msg) {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P()
|
||||
}
|
||||
}
|
||||
|
||||
if gogoproto.HasBenchGen(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
used = true
|
||||
p.P(`func Benchmark`, ccTypeName, `ProtoMarshal(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, `, 10000)`)
|
||||
p.P(`for i := 0; i < 10000; 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(`dAtA, err := `, protoPkg.Use(), `.Marshal(pops[i%10000])`)
|
||||
p.P(`if err != nil {`)
|
||||
p.In()
|
||||
p.P(`panic(err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`total += len(dAtA)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`b.SetBytes(int64(total / b.N))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P()
|
||||
|
||||
p.P(`func Benchmark`, ccTypeName, `ProtoUnmarshal(b *`, testingPkg.Use(), `.B) {`)
|
||||
p.In()
|
||||
p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(616))`)
|
||||
p.P(`total := 0`)
|
||||
p.P(`datas := make([][]byte, 10000)`)
|
||||
p.P(`for i := 0; i < 10000; i++ {`)
|
||||
p.In()
|
||||
p.P(`dAtA, err := `, protoPkg.Use(), `.Marshal(NewPopulated`, ccTypeName, `(popr, false))`)
|
||||
p.P(`if err != nil {`)
|
||||
p.In()
|
||||
p.P(`panic(err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`datas[i] = dAtA`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`msg := &`, ccTypeName, `{}`)
|
||||
p.P(`b.ResetTimer()`)
|
||||
p.P(`for i := 0; i < b.N; i++ {`)
|
||||
p.In()
|
||||
p.P(`total += len(datas[i%10000])`)
|
||||
p.P(`if err := `, protoPkg.Use(), `.Unmarshal(datas[i%10000], msg); err != nil {`)
|
||||
p.In()
|
||||
p.P(`panic(err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`b.SetBytes(int64(total / b.N))`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P()
|
||||
}
|
||||
}
|
||||
return used
|
||||
}
|
||||
|
||||
type testJson struct {
|
||||
*generator.Generator
|
||||
}
|
||||
|
||||
func newJson(g *generator.Generator) TestPlugin {
|
||||
return &testJson{g}
|
||||
}
|
||||
|
||||
func (p *testJson) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
|
||||
used := false
|
||||
testingPkg := imports.NewImport("testing")
|
||||
randPkg := imports.NewImport("math/rand")
|
||||
timePkg := imports.NewImport("time")
|
||||
jsonPkg := imports.NewImport("github.com/gogo/protobuf/jsonpb")
|
||||
for _, message := range file.Messages() {
|
||||
ccTypeName := generator.CamelCaseSlice(message.TypeName())
|
||||
if message.DescriptorProto.GetOptions().GetMapEntry() {
|
||||
continue
|
||||
}
|
||||
if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
used = true
|
||||
p.P(`func Test`, ccTypeName, `JSON(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(`marshaler := `, jsonPkg.Use(), `.Marshaler{}`)
|
||||
p.P(`jsondata, err := marshaler.MarshalToString(p)`)
|
||||
p.P(`if err != nil {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P(`msg := &`, ccTypeName, `{}`)
|
||||
p.P(`err = `, jsonPkg.Use(), `.UnmarshalString(jsondata, msg)`)
|
||||
p.P(`if err != nil {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
if gogoproto.HasVerboseEqual(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
p.P(`if err := p.VerboseEqual(msg); err != nil {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
p.P(`if !p.Equal(msg) {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
}
|
||||
return used
|
||||
}
|
||||
|
||||
type testText struct {
|
||||
*generator.Generator
|
||||
}
|
||||
|
||||
func newText(g *generator.Generator) TestPlugin {
|
||||
return &testText{g}
|
||||
}
|
||||
|
||||
func (p *testText) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
|
||||
used := false
|
||||
testingPkg := imports.NewImport("testing")
|
||||
randPkg := imports.NewImport("math/rand")
|
||||
timePkg := imports.NewImport("time")
|
||||
protoPkg := imports.NewImport("github.com/gogo/protobuf/proto")
|
||||
if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
|
||||
protoPkg = imports.NewImport("github.com/golang/protobuf/proto")
|
||||
}
|
||||
//fmtPkg := imports.NewImport("fmt")
|
||||
for _, message := range file.Messages() {
|
||||
ccTypeName := generator.CamelCaseSlice(message.TypeName())
|
||||
if message.DescriptorProto.GetOptions().GetMapEntry() {
|
||||
continue
|
||||
}
|
||||
if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
used = true
|
||||
|
||||
p.P(`func Test`, ccTypeName, `ProtoText(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(`dAtA := `, protoPkg.Use(), `.MarshalTextString(p)`)
|
||||
p.P(`msg := &`, ccTypeName, `{}`)
|
||||
p.P(`if err := `, protoPkg.Use(), `.UnmarshalText(dAtA, msg); err != nil {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
if gogoproto.HasVerboseEqual(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
p.P(`if err := p.VerboseEqual(msg); err != nil {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
p.P(`if !p.Equal(msg) {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P()
|
||||
|
||||
p.P(`func Test`, ccTypeName, `ProtoCompactText(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(`dAtA := `, protoPkg.Use(), `.CompactTextString(p)`)
|
||||
p.P(`msg := &`, ccTypeName, `{}`)
|
||||
p.P(`if err := `, protoPkg.Use(), `.UnmarshalText(dAtA, msg); err != nil {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
if gogoproto.HasVerboseEqual(file.FileDescriptorProto, message.DescriptorProto) {
|
||||
p.P(`if err := p.VerboseEqual(msg); err != nil {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
}
|
||||
p.P(`if !p.Equal(msg) {`)
|
||||
p.In()
|
||||
p.P(`t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.Out()
|
||||
p.P(`}`)
|
||||
p.P()
|
||||
|
||||
}
|
||||
}
|
||||
return used
|
||||
}
|
||||
|
||||
func init() {
|
||||
RegisterTestPlugin(newProto)
|
||||
RegisterTestPlugin(newJson)
|
||||
RegisterTestPlugin(newText)
|
||||
}
|
209
vendor/github.com/gogo/protobuf/plugin/union/union.go
generated
vendored
Normal file
209
vendor/github.com/gogo/protobuf/plugin/union/union.go
generated
vendored
Normal file
@ -0,0 +1,209 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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())
|
||||
}
|
86
vendor/github.com/gogo/protobuf/plugin/union/uniontest.go
generated
vendored
Normal file
86
vendor/github.com/gogo/protobuf/plugin/union/uniontest.go
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, The GoGo Authors. 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)
|
||||
}
|
1349
vendor/github.com/gogo/protobuf/plugin/unmarshal/unmarshal.go
generated
vendored
Normal file
1349
vendor/github.com/gogo/protobuf/plugin/unmarshal/unmarshal.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user