vendor: Update github.com/gogo/protobuf
Also tweaks the proto definitions: - [packed=false] on the block_indexes field to retain compat with v0.14.16 and earlier. - Uses the vendored protobuf package in include paths. And, "build.go setup" will install the vendored protoc-gen-gogofast. This should ensure that a proto rebuild isn't so dependent on whatever version of the compiler and package the developer has installed... GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3864
This commit is contained in:
committed by
Audrius Butkevicius
parent
4fb9c143ac
commit
987718baf8
+287
-98
@@ -1,7 +1,7 @@
|
||||
// Extensions for Protocol Buffers to create more go like structures.
|
||||
// Protocol Buffers for Go with Gadgets
|
||||
//
|
||||
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
||||
// http://github.com/gogo/protobuf/gogoproto
|
||||
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
|
||||
// http://github.com/gogo/protobuf
|
||||
//
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
@@ -68,7 +68,7 @@ import (
|
||||
// It is incremented whenever an incompatibility between the generated code and
|
||||
// proto package is introduced; the generated code references
|
||||
// a constant, proto.ProtoPackageIsVersionN (where N is generatedCodeVersion).
|
||||
const generatedCodeVersion = 1
|
||||
const generatedCodeVersion = 2
|
||||
|
||||
// A Plugin provides functionality to add to the output during Go code generation,
|
||||
// such as to produce RPC stubs.
|
||||
@@ -300,6 +300,36 @@ type FileDescriptor struct {
|
||||
// PackageName is the package name we'll use in the generated code to refer to this file.
|
||||
func (d *FileDescriptor) PackageName() string { return uniquePackageOf(d.FileDescriptorProto) }
|
||||
|
||||
// VarName is the variable name we'll use in the generated code to refer
|
||||
// to the compressed bytes of this descriptor. It is not exported, so
|
||||
// it is only valid inside the generated package.
|
||||
func (d *FileDescriptor) VarName() string { return fmt.Sprintf("fileDescriptor%v", FileName(d)) }
|
||||
|
||||
// goPackageOption interprets the file's go_package option.
|
||||
// If there is no go_package, it returns ("", "", false).
|
||||
// If there's a simple name, it returns ("", pkg, true).
|
||||
// If the option implies an import path, it returns (impPath, pkg, true).
|
||||
func (d *FileDescriptor) goPackageOption() (impPath, pkg string, ok bool) {
|
||||
pkg = d.GetOptions().GetGoPackage()
|
||||
if pkg == "" {
|
||||
return
|
||||
}
|
||||
ok = true
|
||||
// The presence of a slash implies there's an import path.
|
||||
slash := strings.LastIndex(pkg, "/")
|
||||
if slash < 0 {
|
||||
return
|
||||
}
|
||||
impPath, pkg = pkg, pkg[slash+1:]
|
||||
// A semicolon-delimited suffix overrides the package name.
|
||||
sc := strings.IndexByte(impPath, ';')
|
||||
if sc < 0 {
|
||||
return
|
||||
}
|
||||
impPath, pkg = impPath[:sc], impPath[sc+1:]
|
||||
return
|
||||
}
|
||||
|
||||
// goPackageName returns the Go package name to use in the
|
||||
// generated Go file. The result explicit reports whether the name
|
||||
// came from an option go_package statement. If explicit is false,
|
||||
@@ -307,10 +337,8 @@ func (d *FileDescriptor) PackageName() string { return uniquePackageOf(d.FileDes
|
||||
// or the input file name.
|
||||
func (d *FileDescriptor) goPackageName() (name string, explicit bool) {
|
||||
// Does the file have a "go_package" option?
|
||||
if opts := d.Options; opts != nil {
|
||||
if pkg := opts.GetGoPackage(); pkg != "" {
|
||||
return pkg, true
|
||||
}
|
||||
if _, pkg, ok := d.goPackageOption(); ok {
|
||||
return pkg, true
|
||||
}
|
||||
|
||||
// Does the file have a package clause?
|
||||
@@ -321,6 +349,26 @@ func (d *FileDescriptor) goPackageName() (name string, explicit bool) {
|
||||
return baseName(d.GetName()), false
|
||||
}
|
||||
|
||||
// goFileName returns the output name for the generated Go file.
|
||||
func (d *FileDescriptor) goFileName() string {
|
||||
name := *d.Name
|
||||
if ext := path.Ext(name); ext == ".proto" || ext == ".protodevel" {
|
||||
name = name[:len(name)-len(ext)]
|
||||
}
|
||||
name += ".pb.go"
|
||||
|
||||
// Does the file have a "go_package" option?
|
||||
// If it does, it may override the filename.
|
||||
if impPath, _, ok := d.goPackageOption(); ok && impPath != "" {
|
||||
// Replace the existing dirname with the declared import path.
|
||||
_, name = path.Split(name)
|
||||
name = path.Join(impPath, name)
|
||||
return name
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
func (d *FileDescriptor) addExport(obj Object, sym symbol) {
|
||||
d.exported[obj] = append(d.exported[obj], sym)
|
||||
}
|
||||
@@ -356,8 +404,6 @@ func (ms *messageSymbol) GenerateAlias(g *Generator, pkg string) {
|
||||
if ms.hasExtensions {
|
||||
g.P("func (*", ms.sym, ") ExtensionRangeArray() []", g.Pkg["proto"], ".ExtensionRange ",
|
||||
"{ return (*", remoteSym, ")(nil).ExtensionRangeArray() }")
|
||||
g.P("func (m *", ms.sym, ") ExtensionMap() map[int32]", g.Pkg["proto"], ".Extension ",
|
||||
"{ return (*", remoteSym, ")(m).ExtensionMap() }")
|
||||
if ms.isMessageSet {
|
||||
g.P("func (m *", ms.sym, ") Marshal() ([]byte, error) ",
|
||||
"{ return (*", remoteSym, ")(m).Marshal() }")
|
||||
@@ -548,7 +594,7 @@ type Generator struct {
|
||||
Param map[string]string // Command-line parameters.
|
||||
PackageImportPath string // Go import path of the package we're generating code for
|
||||
ImportPrefix string // String to prefix to imported package file names.
|
||||
ImportMap map[string]string // Mapping from import name to generated name
|
||||
ImportMap map[string]string // Mapping from .proto file name to import path
|
||||
|
||||
Pkg map[string]string // The names under which we import support packages
|
||||
|
||||
@@ -622,7 +668,6 @@ func (g *Generator) CommandLineParameters(parameter string) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if pluginList == "" {
|
||||
return
|
||||
}
|
||||
@@ -823,9 +868,9 @@ AllFiles:
|
||||
// and FileDescriptorProtos into file-referenced objects within the Generator.
|
||||
// It also creates the list of files to generate and so should be called before GenerateAllFiles.
|
||||
func (g *Generator) WrapTypes() {
|
||||
g.allFiles = make([]*FileDescriptor, len(g.Request.ProtoFile))
|
||||
g.allFiles = make([]*FileDescriptor, 0, len(g.Request.ProtoFile))
|
||||
g.allFilesByName = make(map[string]*FileDescriptor, len(g.allFiles))
|
||||
for i, f := range g.Request.ProtoFile {
|
||||
for _, f := range g.Request.ProtoFile {
|
||||
// We must wrap the descriptors before we wrap the enums
|
||||
descs := wrapDescriptors(f)
|
||||
g.buildNestedDescriptors(descs)
|
||||
@@ -841,22 +886,22 @@ func (g *Generator) WrapTypes() {
|
||||
proto3: fileIsProto3(f),
|
||||
}
|
||||
extractComments(fd)
|
||||
g.allFiles[i] = fd
|
||||
g.allFiles = append(g.allFiles, fd)
|
||||
g.allFilesByName[f.GetName()] = fd
|
||||
}
|
||||
for _, fd := range g.allFiles {
|
||||
fd.imp = wrapImported(fd.FileDescriptorProto, g)
|
||||
}
|
||||
|
||||
g.genFiles = make([]*FileDescriptor, len(g.Request.FileToGenerate))
|
||||
for i, fileName := range g.Request.FileToGenerate {
|
||||
g.genFiles[i] = g.allFilesByName[fileName]
|
||||
if g.genFiles[i] == nil {
|
||||
g.genFiles = make([]*FileDescriptor, 0, len(g.Request.FileToGenerate))
|
||||
for _, fileName := range g.Request.FileToGenerate {
|
||||
fd := g.allFilesByName[fileName]
|
||||
if fd == nil {
|
||||
g.Fail("could not find file named", fileName)
|
||||
}
|
||||
g.genFiles[i].index = i
|
||||
fd.index = len(g.genFiles)
|
||||
g.genFiles = append(g.genFiles, fd)
|
||||
}
|
||||
g.Response.File = make([]*plugin.CodeGeneratorResponse_File, len(g.genFiles))
|
||||
}
|
||||
|
||||
// Scan the descriptors in this file. For each one, build the slice of nested descriptors
|
||||
@@ -920,9 +965,8 @@ func newDescriptor(desc *descriptor.DescriptorProto, parent *Descriptor, file *d
|
||||
}
|
||||
}
|
||||
|
||||
d.ext = make([]*ExtensionDescriptor, len(desc.Extension))
|
||||
for i, field := range desc.Extension {
|
||||
d.ext[i] = &ExtensionDescriptor{common{file}, field, d}
|
||||
for _, field := range desc.Extension {
|
||||
d.ext = append(d.ext, &ExtensionDescriptor{common{file}, field, d})
|
||||
}
|
||||
|
||||
return d
|
||||
@@ -981,9 +1025,9 @@ func wrapEnumDescriptors(file *descriptor.FileDescriptorProto, descs []*Descript
|
||||
|
||||
// Return a slice of all the top-level ExtensionDescriptors defined within this file.
|
||||
func wrapExtensions(file *descriptor.FileDescriptorProto) []*ExtensionDescriptor {
|
||||
sl := make([]*ExtensionDescriptor, len(file.Extension))
|
||||
for i, field := range file.Extension {
|
||||
sl[i] = &ExtensionDescriptor{common{file}, field, nil}
|
||||
var sl []*ExtensionDescriptor
|
||||
for _, field := range file.Extension {
|
||||
sl = append(sl, &ExtensionDescriptor{common{file}, field, nil})
|
||||
}
|
||||
return sl
|
||||
}
|
||||
@@ -1161,7 +1205,6 @@ func (g *Generator) GenerateAllFiles() {
|
||||
for _, file := range g.genFiles {
|
||||
genFileMap[file] = true
|
||||
}
|
||||
i := 0
|
||||
for _, file := range g.allFiles {
|
||||
g.Reset()
|
||||
g.writeOutput = genFileMap[file]
|
||||
@@ -1169,10 +1212,10 @@ func (g *Generator) GenerateAllFiles() {
|
||||
if !g.writeOutput {
|
||||
continue
|
||||
}
|
||||
g.Response.File[i] = new(plugin.CodeGeneratorResponse_File)
|
||||
g.Response.File[i].Name = proto.String(goFileName(*file.Name))
|
||||
g.Response.File[i].Content = proto.String(g.String())
|
||||
i++
|
||||
g.Response.File = append(g.Response.File, &plugin.CodeGeneratorResponse_File{
|
||||
Name: proto.String(file.goFileName()),
|
||||
Content: proto.String(g.String()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1205,17 +1248,17 @@ func (g *Generator) generate(file *FileDescriptor) {
|
||||
// For one file in the package, assert version compatibility.
|
||||
g.P("// This is a compile-time assertion to ensure that this generated file")
|
||||
g.P("// is compatible with the proto package it is being compiled against.")
|
||||
g.P("// A compilation error at this line likely means your copy of the")
|
||||
g.P("// proto package needs to be updated.")
|
||||
if gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
|
||||
g.P("const _ = ", g.Pkg["proto"], ".GoGoProtoPackageIsVersion", generatedCodeVersion)
|
||||
g.P("const _ = ", g.Pkg["proto"], ".GoGoProtoPackageIsVersion", generatedCodeVersion, " // please upgrade the proto package")
|
||||
} else {
|
||||
g.P("const _ = ", g.Pkg["proto"], ".ProtoPackageIsVersion", generatedCodeVersion)
|
||||
g.P("const _ = ", g.Pkg["proto"], ".ProtoPackageIsVersion", generatedCodeVersion, " // please upgrade the proto package")
|
||||
}
|
||||
g.P()
|
||||
}
|
||||
|
||||
// Reset on each file
|
||||
g.writtenImports = make(map[string]bool)
|
||||
|
||||
for _, td := range g.file.imp {
|
||||
g.generateImported(td)
|
||||
}
|
||||
@@ -1386,7 +1429,7 @@ func (g *Generator) generateImports() {
|
||||
if fd.PackageName() == g.packageName {
|
||||
continue
|
||||
}
|
||||
filename := goFileName(s)
|
||||
filename := fd.goFileName()
|
||||
// By default, import path is the dirname of the Go filename.
|
||||
importPath := path.Dir(filename)
|
||||
if substitution, ok := g.ImportMap[s]; ok {
|
||||
@@ -1547,8 +1590,10 @@ func (g *Generator) generateEnum(enum *EnumDescriptor) {
|
||||
indexes = append([]string{strconv.Itoa(m.index)}, indexes...)
|
||||
}
|
||||
indexes = append(indexes, strconv.Itoa(enum.index))
|
||||
g.P("func (", ccTypeName, ") EnumDescriptor() ([]byte, []int) { return fileDescriptor", FileName(g.file), ", []int{", strings.Join(indexes, ", "), "} }")
|
||||
|
||||
g.P("func (", ccTypeName, ") EnumDescriptor() ([]byte, []int) { return ", g.file.VarName(), ", []int{", strings.Join(indexes, ", "), "} }")
|
||||
if enum.file.GetPackage() == "google.protobuf" && enum.GetName() == "NullValue" {
|
||||
g.P("func (", ccTypeName, `) XXX_WellKnownType() string { return "`, enum.GetName(), `" }`)
|
||||
}
|
||||
g.P()
|
||||
}
|
||||
|
||||
@@ -1624,7 +1669,11 @@ func (g *Generator) goTag(message *Descriptor, field *descriptor.FieldDescriptor
|
||||
enum += CamelCaseSlice(obj.TypeName())
|
||||
}
|
||||
packed := ""
|
||||
if field.Options != nil && field.Options.GetPacked() {
|
||||
if (field.Options != nil && field.Options.GetPacked()) ||
|
||||
// Per https://developers.google.com/protocol-buffers/docs/proto3#simple:
|
||||
// "In proto3, repeated fields of scalar numeric types use packed encoding by default."
|
||||
(message.proto3() && (field.Options == nil || field.Options.Packed == nil) &&
|
||||
isRepeated(field) && IsScalar(field)) {
|
||||
packed = ",packed"
|
||||
}
|
||||
fieldName := field.GetName()
|
||||
@@ -1692,7 +1741,15 @@ func (g *Generator) goTag(message *Descriptor, field *descriptor.FieldDescriptor
|
||||
if field.OneofIndex != nil {
|
||||
oneof = ",oneof"
|
||||
}
|
||||
return strconv.Quote(fmt.Sprintf("%s,%d,%s%s%s%s%s%s%s%s%s%s%s",
|
||||
stdtime := ""
|
||||
if gogoproto.IsStdTime(field) {
|
||||
stdtime = ",stdtime"
|
||||
}
|
||||
stdduration := ""
|
||||
if gogoproto.IsStdDuration(field) {
|
||||
stdduration = ",stdduration"
|
||||
}
|
||||
return strconv.Quote(fmt.Sprintf("%s,%d,%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||
wiretype,
|
||||
field.GetNumber(),
|
||||
optrepreq,
|
||||
@@ -1705,7 +1762,9 @@ func (g *Generator) goTag(message *Descriptor, field *descriptor.FieldDescriptor
|
||||
ctype,
|
||||
casttype,
|
||||
castkey,
|
||||
castvalue))
|
||||
castvalue,
|
||||
stdtime,
|
||||
stdduration))
|
||||
}
|
||||
|
||||
func needsStar(field *descriptor.FieldDescriptorProto, proto3 bool, allowOneOf bool) bool {
|
||||
@@ -1818,8 +1877,14 @@ func (g *Generator) GoType(message *Descriptor, field *descriptor.FieldDescripto
|
||||
if len(packageName) > 0 {
|
||||
g.customImports = append(g.customImports, packageName)
|
||||
}
|
||||
case gogoproto.IsStdTime(field):
|
||||
g.customImports = append(g.customImports, "time")
|
||||
typ = "time.Time"
|
||||
case gogoproto.IsStdDuration(field):
|
||||
g.customImports = append(g.customImports, "time")
|
||||
typ = "time.Duration"
|
||||
}
|
||||
if needsStar(field, g.file.proto3, message != nil && message.allowOneof()) {
|
||||
if needsStar(field, g.file.proto3 && field.Extendee == nil, message != nil && message.allowOneof()) {
|
||||
typ = "*" + typ
|
||||
}
|
||||
if isRepeated(field) {
|
||||
@@ -1890,9 +1955,18 @@ func (g *Generator) GoMapType(d *Descriptor, field *descriptor.FieldDescriptorPr
|
||||
if !gogoproto.IsNullable(m.ValueAliasField) {
|
||||
valType = strings.TrimPrefix(valType, "*")
|
||||
}
|
||||
g.RecordTypeUse(m.ValueAliasField.GetTypeName())
|
||||
if !gogoproto.IsStdTime(field) && !gogoproto.IsStdDuration(field) {
|
||||
g.RecordTypeUse(m.ValueAliasField.GetTypeName())
|
||||
}
|
||||
default:
|
||||
valType = strings.TrimPrefix(valType, "*")
|
||||
if gogoproto.IsCustomType(m.ValueAliasField) {
|
||||
if !gogoproto.IsNullable(m.ValueAliasField) {
|
||||
valType = strings.TrimPrefix(valType, "*")
|
||||
}
|
||||
g.RecordTypeUse(m.ValueAliasField.GetTypeName())
|
||||
} else {
|
||||
valType = strings.TrimPrefix(valType, "*")
|
||||
}
|
||||
}
|
||||
|
||||
m.GoType = fmt.Sprintf("map[%s]%s", keyType, valType)
|
||||
@@ -1908,7 +1982,8 @@ func (g *Generator) RecordTypeUse(t string) {
|
||||
}
|
||||
|
||||
// Method names that may be generated. Fields with these names get an
|
||||
// underscore appended.
|
||||
// underscore appended. Any change to this set is a potential incompatible
|
||||
// API change because it changes generated field names.
|
||||
var methodNames = [...]string{
|
||||
"Reset",
|
||||
"String",
|
||||
@@ -1925,6 +2000,28 @@ var methodNames = [...]string{
|
||||
"ProtoSize",
|
||||
}
|
||||
|
||||
// Names of messages in the `google.protobuf` package for which
|
||||
// we will generate XXX_WellKnownType methods.
|
||||
var wellKnownTypes = map[string]bool{
|
||||
"Any": true,
|
||||
"Duration": true,
|
||||
"Empty": true,
|
||||
"Struct": true,
|
||||
"Timestamp": true,
|
||||
|
||||
"Value": true,
|
||||
"ListValue": true,
|
||||
"DoubleValue": true,
|
||||
"FloatValue": true,
|
||||
"Int64Value": true,
|
||||
"UInt64Value": true,
|
||||
"Int32Value": true,
|
||||
"UInt32Value": true,
|
||||
"BoolValue": true,
|
||||
"StringValue": true,
|
||||
"BytesValue": true,
|
||||
}
|
||||
|
||||
// Generate the type and default constant definitions for this Descriptor.
|
||||
func (g *Generator) generateMessage(message *Descriptor) {
|
||||
// The full type name
|
||||
@@ -2076,11 +2173,13 @@ func (g *Generator) generateMessage(message *Descriptor) {
|
||||
|
||||
g.PrintComments(fmt.Sprintf("%s,%d,%d", message.path, messageFieldPath, i))
|
||||
g.P(fieldName, "\t", typename, "\t`", tag, "`")
|
||||
g.RecordTypeUse(field.GetTypeName())
|
||||
if !gogoproto.IsStdTime(field) && !gogoproto.IsStdDuration(field) {
|
||||
g.RecordTypeUse(field.GetTypeName())
|
||||
}
|
||||
}
|
||||
if len(message.ExtensionRange) > 0 {
|
||||
if gogoproto.HasExtensionsMap(g.file.FileDescriptorProto, message.DescriptorProto) {
|
||||
g.P("XXX_extensions\t\tmap[int32]", g.Pkg["proto"], ".Extension `json:\"-\"`")
|
||||
g.P(g.Pkg["proto"], ".XXX_InternalExtensions `json:\"-\"`")
|
||||
} else {
|
||||
g.P("XXX_extensions\t\t[]byte `protobuf:\"bytes,0,opt\" json:\"-\"`")
|
||||
}
|
||||
@@ -2114,15 +2213,16 @@ func (g *Generator) generateMessage(message *Descriptor) {
|
||||
g.P("func (m *", ccTypeName, ") String() string { return ", g.Pkg["proto"], ".CompactTextString(m) }")
|
||||
}
|
||||
g.P("func (*", ccTypeName, ") ProtoMessage() {}")
|
||||
if !message.group {
|
||||
var indexes []string
|
||||
for m := message; m != nil; m = m.parent {
|
||||
// XXX: skip groups?
|
||||
indexes = append([]string{strconv.Itoa(m.index)}, indexes...)
|
||||
}
|
||||
g.P("func (*", ccTypeName, ") Descriptor() ([]byte, []int) { return fileDescriptor", FileName(g.file), ", []int{", strings.Join(indexes, ", "), "} }")
|
||||
var indexes []string
|
||||
for m := message; m != nil; m = m.parent {
|
||||
indexes = append([]string{strconv.Itoa(m.index)}, indexes...)
|
||||
}
|
||||
g.P("func (*", ccTypeName, ") Descriptor() ([]byte, []int) { return ", g.file.VarName(), ", []int{", strings.Join(indexes, ", "), "} }")
|
||||
// TODO: Revisit the decision to use a XXX_WellKnownType method
|
||||
// if we change proto.MessageName to work with multiple equivalents.
|
||||
if message.file.GetPackage() == "google.protobuf" && wellKnownTypes[message.GetName()] {
|
||||
g.P("func (*", ccTypeName, `) XXX_WellKnownType() string { return "`, message.GetName(), `" }`)
|
||||
}
|
||||
|
||||
// Extension support methods
|
||||
var hasExtensions, isMessageSet bool
|
||||
if len(message.ExtensionRange) > 0 {
|
||||
@@ -2133,22 +2233,22 @@ func (g *Generator) generateMessage(message *Descriptor) {
|
||||
g.P()
|
||||
g.P("func (m *", ccTypeName, ") Marshal() ([]byte, error) {")
|
||||
g.In()
|
||||
g.P("return ", g.Pkg["proto"], ".MarshalMessageSet(m.ExtensionMap())")
|
||||
g.P("return ", g.Pkg["proto"], ".MarshalMessageSet(&m.XXX_InternalExtensions)")
|
||||
g.Out()
|
||||
g.P("}")
|
||||
g.P("func (m *", ccTypeName, ") Unmarshal(buf []byte) error {")
|
||||
g.In()
|
||||
g.P("return ", g.Pkg["proto"], ".UnmarshalMessageSet(buf, m.ExtensionMap())")
|
||||
g.P("return ", g.Pkg["proto"], ".UnmarshalMessageSet(buf, &m.XXX_InternalExtensions)")
|
||||
g.Out()
|
||||
g.P("}")
|
||||
g.P("func (m *", ccTypeName, ") MarshalJSON() ([]byte, error) {")
|
||||
g.In()
|
||||
g.P("return ", g.Pkg["proto"], ".MarshalMessageSetJSON(m.XXX_extensions)")
|
||||
g.P("return ", g.Pkg["proto"], ".MarshalMessageSetJSON(&m.XXX_InternalExtensions)")
|
||||
g.Out()
|
||||
g.P("}")
|
||||
g.P("func (m *", ccTypeName, ") UnmarshalJSON(buf []byte) error {")
|
||||
g.In()
|
||||
g.P("return ", g.Pkg["proto"], ".UnmarshalMessageSetJSON(buf, m.XXX_extensions)")
|
||||
g.P("return ", g.Pkg["proto"], ".UnmarshalMessageSetJSON(buf, &m.XXX_InternalExtensions)")
|
||||
g.Out()
|
||||
g.P("}")
|
||||
g.P("// ensure ", ccTypeName, " satisfies proto.Marshaler and proto.Unmarshaler")
|
||||
@@ -2161,7 +2261,7 @@ func (g *Generator) generateMessage(message *Descriptor) {
|
||||
g.In()
|
||||
for _, r := range message.ExtensionRange {
|
||||
end := fmt.Sprint(*r.End - 1) // make range inclusive on both ends
|
||||
g.P("{", r.Start, ", ", end, "},")
|
||||
g.P("{Start: ", r.Start, ", End: ", end, "},")
|
||||
}
|
||||
g.Out()
|
||||
g.P("}")
|
||||
@@ -2170,18 +2270,7 @@ func (g *Generator) generateMessage(message *Descriptor) {
|
||||
g.P("return extRange_", ccTypeName)
|
||||
g.Out()
|
||||
g.P("}")
|
||||
if gogoproto.HasExtensionsMap(g.file.FileDescriptorProto, message.DescriptorProto) {
|
||||
g.P("func (m *", ccTypeName, ") ExtensionMap() map[int32]", g.Pkg["proto"], ".Extension {")
|
||||
g.In()
|
||||
g.P("if m.XXX_extensions == nil {")
|
||||
g.In()
|
||||
g.P("m.XXX_extensions = make(map[int32]", g.Pkg["proto"], ".Extension)")
|
||||
g.Out()
|
||||
g.P("}")
|
||||
g.P("return m.XXX_extensions")
|
||||
g.Out()
|
||||
g.P("}")
|
||||
} else {
|
||||
if !gogoproto.HasExtensionsMap(g.file.FileDescriptorProto, message.DescriptorProto) {
|
||||
g.P("func (m *", ccTypeName, ") GetExtensions() *[]byte {")
|
||||
g.In()
|
||||
g.P("if m.XXX_extensions == nil {")
|
||||
@@ -2315,7 +2404,9 @@ func (g *Generator) generateMessage(message *Descriptor) {
|
||||
_, wiretype := g.GoType(message, field)
|
||||
tag := "protobuf:" + g.goTag(message, field, wiretype)
|
||||
g.P("type ", oneofTypeName[field], " struct{ ", fieldNames[field], " ", fieldTypes[field], " `", tag, "` }")
|
||||
g.RecordTypeUse(field.GetTypeName())
|
||||
if !gogoproto.IsStdTime(field) && !gogoproto.IsStdDuration(field) {
|
||||
g.RecordTypeUse(field.GetTypeName())
|
||||
}
|
||||
}
|
||||
g.P()
|
||||
for _, field := range message.Field {
|
||||
@@ -2359,11 +2450,6 @@ func (g *Generator) generateMessage(message *Descriptor) {
|
||||
star = "*"
|
||||
}
|
||||
|
||||
// In proto3, only generate getters for message fields and oneof fields.
|
||||
if message.proto3() && *field.Type != descriptor.FieldDescriptorProto_TYPE_MESSAGE && !oneof {
|
||||
continue
|
||||
}
|
||||
|
||||
// Only export getter symbols for basic types,
|
||||
// and for messages and enums in the same package.
|
||||
// Groups are not exported.
|
||||
@@ -2428,7 +2514,11 @@ func (g *Generator) generateMessage(message *Descriptor) {
|
||||
g.Out()
|
||||
g.P("}")
|
||||
} else if !oneof {
|
||||
g.P("if m != nil && m." + fname + " != nil {")
|
||||
if message.proto3() {
|
||||
g.P("if m != nil {")
|
||||
} else {
|
||||
g.P("if m != nil && m." + fname + " != nil {")
|
||||
}
|
||||
g.In()
|
||||
g.P("return " + star + "m." + fname)
|
||||
g.Out()
|
||||
@@ -2457,7 +2547,11 @@ func (g *Generator) generateMessage(message *Descriptor) {
|
||||
} else {
|
||||
goTyp, _ := g.GoType(message, field)
|
||||
goTypName := GoTypeToName(goTyp)
|
||||
g.P("return ", goTypName, "{}")
|
||||
if !gogoproto.IsNullable(field) && gogoproto.IsStdDuration(field) {
|
||||
g.P("return 0")
|
||||
} else {
|
||||
g.P("return ", goTypName, "{}")
|
||||
}
|
||||
}
|
||||
case descriptor.FieldDescriptorProto_TYPE_BOOL:
|
||||
g.P("return false")
|
||||
@@ -2614,13 +2708,41 @@ func (g *Generator) generateMessage(message *Descriptor) {
|
||||
fieldWire[field] = wire
|
||||
g.P("_ = b.EncodeVarint(", field.Number, "<<3|", g.Pkg["proto"], ".", wire, ")")
|
||||
if *field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES && gogoproto.IsCustomType(field) {
|
||||
g.P(`data, err := `, val, `.Marshal()`)
|
||||
g.P(`dAtA, err := `, val, `.Marshal()`)
|
||||
g.P(`if err != nil {`)
|
||||
g.In()
|
||||
g.P(`return err`)
|
||||
g.Out()
|
||||
g.P(`}`)
|
||||
val = "data"
|
||||
val = "dAtA"
|
||||
} else if gogoproto.IsStdTime(field) {
|
||||
pkg := g.useTypes()
|
||||
if gogoproto.IsNullable(field) {
|
||||
g.P(`dAtA, err := `, pkg, `.StdTimeMarshal(*`, val, `)`)
|
||||
} else {
|
||||
g.P(`dAtA, err := `, pkg, `.StdTimeMarshal(`, val, `)`)
|
||||
}
|
||||
g.P(`if err != nil {`)
|
||||
g.In()
|
||||
g.P(`return err`)
|
||||
g.Out()
|
||||
g.P(`}`)
|
||||
val = "dAtA"
|
||||
pre, post = "b.EncodeRawBytes(", ")"
|
||||
} else if gogoproto.IsStdDuration(field) {
|
||||
pkg := g.useTypes()
|
||||
if gogoproto.IsNullable(field) {
|
||||
g.P(`dAtA, err := `, pkg, `.StdDurationMarshal(*`, val, `)`)
|
||||
} else {
|
||||
g.P(`dAtA, err := `, pkg, `.StdDurationMarshal(`, val, `)`)
|
||||
}
|
||||
g.P(`if err != nil {`)
|
||||
g.In()
|
||||
g.P(`return err`)
|
||||
g.Out()
|
||||
g.P(`}`)
|
||||
val = "dAtA"
|
||||
pre, post = "b.EncodeRawBytes(", ")"
|
||||
}
|
||||
if !canFail {
|
||||
g.P("_ = ", pre, val, post)
|
||||
@@ -2684,9 +2806,13 @@ func (g *Generator) generateMessage(message *Descriptor) {
|
||||
dec = "b.DecodeGroup(msg)"
|
||||
// handled specially below
|
||||
case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
|
||||
g.P("msg := new(", fieldTypes[field][1:], ")") // drop star
|
||||
lhs = "err"
|
||||
dec = "b.DecodeMessage(msg)"
|
||||
if gogoproto.IsStdTime(field) || gogoproto.IsStdDuration(field) {
|
||||
dec = "b.DecodeRawBytes(true)"
|
||||
} else {
|
||||
g.P("msg := new(", fieldTypes[field][1:], ")") // drop star
|
||||
lhs = "err"
|
||||
dec = "b.DecodeMessage(msg)"
|
||||
}
|
||||
// handled specially below
|
||||
case descriptor.FieldDescriptorProto_TYPE_BYTES:
|
||||
dec = "b.DecodeRawBytes(true)"
|
||||
@@ -2721,6 +2847,34 @@ func (g *Generator) generateMessage(message *Descriptor) {
|
||||
g.P(`c := &cc`)
|
||||
g.P(`err = c.Unmarshal(`, val, `)`)
|
||||
val = "*c"
|
||||
} else if gogoproto.IsStdTime(field) {
|
||||
pkg := g.useTypes()
|
||||
g.P(`if err != nil {`)
|
||||
g.In()
|
||||
g.P(`return true, err`)
|
||||
g.Out()
|
||||
g.P(`}`)
|
||||
g.P(`c := new(time.Time)`)
|
||||
g.P(`if err2 := `, pkg, `.StdTimeUnmarshal(c, `, val, `); err2 != nil {`)
|
||||
g.In()
|
||||
g.P(`return true, err`)
|
||||
g.Out()
|
||||
g.P(`}`)
|
||||
val = "c"
|
||||
} else if gogoproto.IsStdDuration(field) {
|
||||
pkg := g.useTypes()
|
||||
g.P(`if err != nil {`)
|
||||
g.In()
|
||||
g.P(`return true, err`)
|
||||
g.Out()
|
||||
g.P(`}`)
|
||||
g.P(`c := new(time.Duration)`)
|
||||
g.P(`if err2 := `, pkg, `.StdDurationUnmarshal(c, `, val, `); err2 != nil {`)
|
||||
g.In()
|
||||
g.P(`return true, err`)
|
||||
g.Out()
|
||||
g.P(`}`)
|
||||
val = "c"
|
||||
}
|
||||
if cast != "" {
|
||||
val = cast + "(" + val + ")"
|
||||
@@ -2733,7 +2887,9 @@ func (g *Generator) generateMessage(message *Descriptor) {
|
||||
val += " != 0"
|
||||
case descriptor.FieldDescriptorProto_TYPE_GROUP,
|
||||
descriptor.FieldDescriptorProto_TYPE_MESSAGE:
|
||||
val = "msg"
|
||||
if !gogoproto.IsStdTime(field) && !gogoproto.IsStdDuration(field) {
|
||||
val = "msg"
|
||||
}
|
||||
}
|
||||
if gogoproto.IsCastType(field) {
|
||||
_, typ, err := getCastType(field)
|
||||
@@ -2798,7 +2954,21 @@ func (g *Generator) generateMessage(message *Descriptor) {
|
||||
fixed = g.Pkg["proto"] + ".Size(" + val + ")"
|
||||
case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
|
||||
wire = "WireBytes"
|
||||
g.P("s := ", g.Pkg["proto"], ".Size(", val, ")")
|
||||
if gogoproto.IsStdTime(field) {
|
||||
if gogoproto.IsNullable(field) {
|
||||
val = "*" + val
|
||||
}
|
||||
pkg := g.useTypes()
|
||||
g.P("s := ", pkg, ".SizeOfStdTime(", val, ")")
|
||||
} else if gogoproto.IsStdDuration(field) {
|
||||
if gogoproto.IsNullable(field) {
|
||||
val = "*" + val
|
||||
}
|
||||
pkg := g.useTypes()
|
||||
g.P("s := ", pkg, ".SizeOfStdDuration(", val, ")")
|
||||
} else {
|
||||
g.P("s := ", g.Pkg["proto"], ".Size(", val, ")")
|
||||
}
|
||||
fixed = "s"
|
||||
varint = fixed
|
||||
case descriptor.FieldDescriptorProto_TYPE_BYTES:
|
||||
@@ -2898,6 +3068,7 @@ func (g *Generator) generateExtension(ext *ExtensionDescriptor) {
|
||||
g.P("Field: ", field.Number, ",")
|
||||
g.P(`Name: "`, extName, `",`)
|
||||
g.P("Tag: ", tag, ",")
|
||||
g.P(`Filename: "`, g.file.GetName(), `",`)
|
||||
|
||||
g.Out()
|
||||
g.P("}")
|
||||
@@ -2953,8 +3124,9 @@ func (g *Generator) generateFileDescriptor(file *FileDescriptor) {
|
||||
w.Close()
|
||||
b = buf.Bytes()
|
||||
|
||||
v := fmt.Sprintf("fileDescriptor%v", FileName(file))
|
||||
v := file.VarName()
|
||||
g.P()
|
||||
g.P("func init() { ", g.Pkg["proto"], ".RegisterFile(", strconv.Quote(*file.Name), ", ", v, ") }")
|
||||
g.P("var ", v, " = []byte{")
|
||||
g.In()
|
||||
g.P("// ", len(b), " bytes of a gzipped FileDescriptorProto")
|
||||
@@ -3059,15 +3231,6 @@ func CamelCaseSlice(elem []string) string { return CamelCase(strings.Join(elem,
|
||||
// dottedSlice turns a sliced name into a dotted name.
|
||||
func dottedSlice(elem []string) string { return strings.Join(elem, ".") }
|
||||
|
||||
// Given a .proto file name, return the output name for the generated Go program.
|
||||
func goFileName(name string) string {
|
||||
ext := path.Ext(name)
|
||||
if ext == ".proto" || ext == ".protodevel" {
|
||||
name = name[0 : len(name)-len(ext)]
|
||||
}
|
||||
return name + ".pb.go"
|
||||
}
|
||||
|
||||
// Is this field optional?
|
||||
func isOptional(field *descriptor.FieldDescriptorProto) bool {
|
||||
return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_OPTIONAL
|
||||
@@ -3083,6 +3246,32 @@ func isRepeated(field *descriptor.FieldDescriptorProto) bool {
|
||||
return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED
|
||||
}
|
||||
|
||||
// Is this field a scalar numeric type?
|
||||
func IsScalar(field *descriptor.FieldDescriptorProto) bool {
|
||||
if field.Type == nil {
|
||||
return false
|
||||
}
|
||||
switch *field.Type {
|
||||
case descriptor.FieldDescriptorProto_TYPE_DOUBLE,
|
||||
descriptor.FieldDescriptorProto_TYPE_FLOAT,
|
||||
descriptor.FieldDescriptorProto_TYPE_INT64,
|
||||
descriptor.FieldDescriptorProto_TYPE_UINT64,
|
||||
descriptor.FieldDescriptorProto_TYPE_INT32,
|
||||
descriptor.FieldDescriptorProto_TYPE_FIXED64,
|
||||
descriptor.FieldDescriptorProto_TYPE_FIXED32,
|
||||
descriptor.FieldDescriptorProto_TYPE_BOOL,
|
||||
descriptor.FieldDescriptorProto_TYPE_UINT32,
|
||||
descriptor.FieldDescriptorProto_TYPE_ENUM,
|
||||
descriptor.FieldDescriptorProto_TYPE_SFIXED32,
|
||||
descriptor.FieldDescriptorProto_TYPE_SFIXED64,
|
||||
descriptor.FieldDescriptorProto_TYPE_SINT32,
|
||||
descriptor.FieldDescriptorProto_TYPE_SINT64:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// badToUnderscore is the mapping function used to generate Go names from package names,
|
||||
// which can be dotted in the input .proto file. It replaces non-identifier characters such as
|
||||
// dot or dash with underscore.
|
||||
|
||||
+38
-36
@@ -1,5 +1,7 @@
|
||||
// Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
|
||||
// http://github.com/gogo/protobuf/gogoproto
|
||||
// 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
|
||||
@@ -238,18 +240,38 @@ func (g *Generator) GetMapKeyField(field, keyField *descriptor.FieldDescriptorPr
|
||||
}
|
||||
|
||||
func (g *Generator) GetMapValueField(field, valField *descriptor.FieldDescriptorProto) *descriptor.FieldDescriptorProto {
|
||||
if !gogoproto.IsCastValue(field) && gogoproto.IsNullable(field) {
|
||||
return valField
|
||||
if gogoproto.IsCustomType(field) && gogoproto.IsCastValue(field) {
|
||||
g.Fail("cannot have a customtype and casttype: ", field.String())
|
||||
}
|
||||
valField = proto.Clone(valField).(*descriptor.FieldDescriptorProto)
|
||||
if valField.Options == nil {
|
||||
valField.Options = &descriptor.FieldOptions{}
|
||||
}
|
||||
|
||||
stdtime := gogoproto.IsStdTime(field)
|
||||
if stdtime {
|
||||
if err := proto.SetExtension(valField.Options, gogoproto.E_Stdtime, &stdtime); err != nil {
|
||||
g.Fail(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
stddur := gogoproto.IsStdDuration(field)
|
||||
if stddur {
|
||||
if err := proto.SetExtension(valField.Options, gogoproto.E_Stdduration, &stddur); err != nil {
|
||||
g.Fail(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if valType := gogoproto.GetCastValue(field); len(valType) > 0 {
|
||||
if err := proto.SetExtension(valField.Options, gogoproto.E_Casttype, &valType); err != nil {
|
||||
g.Fail(err.Error())
|
||||
}
|
||||
}
|
||||
if valType := gogoproto.GetCustomType(field); len(valType) > 0 {
|
||||
if err := proto.SetExtension(valField.Options, gogoproto.E_Customtype, &valType); err != nil {
|
||||
g.Fail(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
nullable := gogoproto.IsNullable(field)
|
||||
if err := proto.SetExtension(valField.Options, gogoproto.E_Nullable, &nullable); err != nil {
|
||||
@@ -261,7 +283,7 @@ func (g *Generator) GetMapValueField(field, valField *descriptor.FieldDescriptor
|
||||
// GoMapValueTypes returns the map value Go type and the alias map value Go type (for casting), taking into
|
||||
// account whether the map is nullable or the value is a message.
|
||||
func GoMapValueTypes(mapField, valueField *descriptor.FieldDescriptorProto, goValueType, goValueAliasType string) (nullable bool, outGoType string, outGoAliasType string) {
|
||||
nullable = gogoproto.IsNullable(mapField) && valueField.IsMessage()
|
||||
nullable = gogoproto.IsNullable(mapField) && (valueField.IsMessage() || gogoproto.IsCustomType(mapField))
|
||||
if nullable {
|
||||
// ensure the non-aliased Go value type is a pointer for consistency
|
||||
if strings.HasPrefix(goValueType, "*") {
|
||||
@@ -294,6 +316,7 @@ func EmbedFieldName(goTyp string) string {
|
||||
}
|
||||
|
||||
func (g *Generator) GeneratePlugin(p Plugin) {
|
||||
plugins = []Plugin{p}
|
||||
p.Init(g)
|
||||
// Generate the output. The generator runs for every file, even the files
|
||||
// that we don't generate output for, so that we can collate the full list
|
||||
@@ -302,7 +325,6 @@ func (g *Generator) GeneratePlugin(p Plugin) {
|
||||
for _, file := range g.genFiles {
|
||||
genFileMap[file] = true
|
||||
}
|
||||
i := 0
|
||||
for _, file := range g.allFiles {
|
||||
g.Reset()
|
||||
g.writeOutput = genFileMap[file]
|
||||
@@ -310,10 +332,10 @@ func (g *Generator) GeneratePlugin(p Plugin) {
|
||||
if !g.writeOutput {
|
||||
continue
|
||||
}
|
||||
g.Response.File[i] = new(plugin.CodeGeneratorResponse_File)
|
||||
g.Response.File[i].Name = proto.String(goFileName(*file.Name))
|
||||
g.Response.File[i].Content = proto.String(g.String())
|
||||
i++
|
||||
g.Response.File = append(g.Response.File, &plugin.CodeGeneratorResponse_File{
|
||||
Name: proto.String(file.goFileName()),
|
||||
Content: proto.String(g.String()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,32 +419,6 @@ func getCastType(field *descriptor.FieldDescriptorProto) (packageName string, ty
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
func getCastKey(field *descriptor.FieldDescriptorProto) (packageName string, typ string, err error) {
|
||||
if field.Options != nil {
|
||||
var v interface{}
|
||||
v, err = proto.GetExtension(field.Options, gogoproto.E_Castkey)
|
||||
if err == nil && v.(*string) != nil {
|
||||
ctype := *(v.(*string))
|
||||
packageName, typ = splitCPackageType(ctype)
|
||||
return packageName, typ, nil
|
||||
}
|
||||
}
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
func getCastValue(field *descriptor.FieldDescriptorProto) (packageName string, typ string, err error) {
|
||||
if field.Options != nil {
|
||||
var v interface{}
|
||||
v, err = proto.GetExtension(field.Options, gogoproto.E_Castvalue)
|
||||
if err == nil && v.(*string) != nil {
|
||||
ctype := *(v.(*string))
|
||||
packageName, typ = splitCPackageType(ctype)
|
||||
return packageName, typ, nil
|
||||
}
|
||||
}
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
func FileName(file *FileDescriptor) string {
|
||||
fname := path.Base(file.FileDescriptorProto.GetName())
|
||||
fname = strings.Replace(fname, ".proto", "", -1)
|
||||
@@ -443,3 +439,9 @@ func (g *Generator) AllFiles() *descriptor.FileDescriptorSet {
|
||||
func (d *Descriptor) Path() string {
|
||||
return d.path
|
||||
}
|
||||
|
||||
func (g *Generator) useTypes() string {
|
||||
pkg := strings.Map(badToUnderscore, "github.com/gogo/protobuf/types")
|
||||
g.customImports = append(g.customImports, "github.com/gogo/protobuf/types")
|
||||
return pkg
|
||||
}
|
||||
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
// Go support for Protocol Buffers - Google's data interchange format
|
||||
//
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// https://github.com/golang/protobuf
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package generator
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
|
||||
)
|
||||
|
||||
func TestCamelCase(t *testing.T) {
|
||||
tests := []struct {
|
||||
in, want string
|
||||
}{
|
||||
{"one", "One"},
|
||||
{"one_two", "OneTwo"},
|
||||
{"_my_field_name_2", "XMyFieldName_2"},
|
||||
{"Something_Capped", "Something_Capped"},
|
||||
{"my_Name", "My_Name"},
|
||||
{"OneTwo", "OneTwo"},
|
||||
{"_", "X"},
|
||||
{"_a_", "XA_"},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
if got := CamelCase(tc.in); got != tc.want {
|
||||
t.Errorf("CamelCase(%q) = %q, want %q", tc.in, got, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGoPackageOption(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
impPath, pkg string
|
||||
ok bool
|
||||
}{
|
||||
{"", "", "", false},
|
||||
{"foo", "", "foo", true},
|
||||
{"github.com/golang/bar", "github.com/golang/bar", "bar", true},
|
||||
{"github.com/golang/bar;baz", "github.com/golang/bar", "baz", true},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
d := &FileDescriptor{
|
||||
FileDescriptorProto: &descriptor.FileDescriptorProto{
|
||||
Options: &descriptor.FileOptions{
|
||||
GoPackage: &tc.in,
|
||||
},
|
||||
},
|
||||
}
|
||||
impPath, pkg, ok := d.goPackageOption()
|
||||
if impPath != tc.impPath || pkg != tc.pkg || ok != tc.ok {
|
||||
t.Errorf("go_package = %q => (%q, %q, %t), want (%q, %q, %t)", tc.in,
|
||||
impPath, pkg, ok, tc.impPath, tc.pkg, tc.ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user