mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-22 10:58:57 +00:00
209e68c1ba
Also adds idle time and keepalive parameters because how this is configured has changed in the new package version. The values are those that seems like might already be default, if keep-alives were enabled, which is not obvious from the doc comments. Also, Go 1.19 gofmt reformatting of comments.
314 lines
9.1 KiB
Go
314 lines
9.1 KiB
Go
// Copyright (C) 2020 The Syncthing Authors.
|
|
//
|
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
|
|
//go:build ignore
|
|
// +build ignore
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"strings"
|
|
"unicode"
|
|
|
|
"github.com/syncthing/syncthing/proto/ext"
|
|
|
|
"github.com/gogo/protobuf/gogoproto"
|
|
"github.com/gogo/protobuf/proto"
|
|
"github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
|
|
"github.com/gogo/protobuf/vanity"
|
|
"github.com/gogo/protobuf/vanity/command"
|
|
)
|
|
|
|
func main() {
|
|
req := command.Read()
|
|
files := req.GetProtoFile()
|
|
files = vanity.FilterFiles(files, vanity.NotGoogleProtobufDescriptorProto)
|
|
|
|
vanity.ForEachFile(files, vanity.TurnOffGoGettersAll)
|
|
vanity.ForEachFile(files, TurnOnProtoSizerAll)
|
|
vanity.ForEachFile(files, vanity.TurnOffGoEnumPrefixAll)
|
|
vanity.ForEachFile(files, vanity.TurnOffGoUnrecognizedAll)
|
|
vanity.ForEachFile(files, vanity.TurnOffGoUnkeyedAll)
|
|
vanity.ForEachFile(files, vanity.TurnOffGoSizecacheAll)
|
|
vanity.ForEachFile(files, vanity.TurnOnMarshalerAll)
|
|
vanity.ForEachFile(files, vanity.TurnOnUnmarshalerAll)
|
|
vanity.ForEachEnumInFiles(files, HandleCustomEnumExtensions)
|
|
vanity.ForEachFile(files, SetPackagePrefix("github.com/syncthing/syncthing"))
|
|
vanity.ForEachFile(files, HandleFile)
|
|
vanity.ForEachFieldInFilesExcludingExtensions(files, TurnOffNullableForMessages)
|
|
|
|
resp := command.Generate(req)
|
|
command.Write(resp)
|
|
}
|
|
|
|
func TurnOnProtoSizerAll(file *descriptor.FileDescriptorProto) {
|
|
vanity.SetBoolFileOption(gogoproto.E_ProtosizerAll, true)(file)
|
|
}
|
|
|
|
func TurnOffNullableForMessages(field *descriptor.FieldDescriptorProto) {
|
|
if !vanity.FieldHasBoolExtension(field, gogoproto.E_Nullable) {
|
|
_, hasCustomType := GetFieldStringExtension(field, gogoproto.E_Customtype)
|
|
if field.IsMessage() || hasCustomType {
|
|
vanity.SetBoolFieldOption(gogoproto.E_Nullable, false)(field)
|
|
}
|
|
}
|
|
}
|
|
|
|
func HandleCustomEnumExtensions(enum *descriptor.EnumDescriptorProto) {
|
|
for _, field := range enum.Value {
|
|
if field == nil {
|
|
continue
|
|
}
|
|
if field.Options == nil {
|
|
field.Options = &descriptor.EnumValueOptions{}
|
|
}
|
|
customName := gogoproto.GetEnumValueCustomName(field)
|
|
if customName != "" {
|
|
continue
|
|
}
|
|
if v, ok := GetEnumValueStringExtension(field, ext.E_Enumgoname); ok {
|
|
SetEnumValueStringFieldOption(field, gogoproto.E_EnumvalueCustomname, v)
|
|
} else {
|
|
SetEnumValueStringFieldOption(field, gogoproto.E_EnumvalueCustomname, toCamelCase(*field.Name, true))
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
func SetPackagePrefix(prefix string) func(file *descriptor.FileDescriptorProto) {
|
|
return func(file *descriptor.FileDescriptorProto) {
|
|
if file.Options.GoPackage == nil {
|
|
pkg, _ := filepath.Split(file.GetName())
|
|
fullPkg := prefix + "/" + strings.TrimSuffix(pkg, "/")
|
|
file.Options.GoPackage = &fullPkg
|
|
}
|
|
}
|
|
}
|
|
|
|
func toCamelCase(input string, firstUpper bool) string {
|
|
runes := []rune(strings.ToLower(input))
|
|
outputRunes := make([]rune, 0, len(runes))
|
|
|
|
nextUpper := false
|
|
for i, rune := range runes {
|
|
if rune == '_' {
|
|
nextUpper = true
|
|
continue
|
|
}
|
|
if (firstUpper && i == 0) || nextUpper {
|
|
rune = unicode.ToUpper(rune)
|
|
nextUpper = false
|
|
}
|
|
outputRunes = append(outputRunes, rune)
|
|
}
|
|
return string(outputRunes)
|
|
}
|
|
|
|
func SetStringFieldOption(field *descriptor.FieldDescriptorProto, extension *proto.ExtensionDesc, value string) {
|
|
if _, ok := GetFieldStringExtension(field, extension); ok {
|
|
return
|
|
}
|
|
if field.Options == nil {
|
|
field.Options = &descriptor.FieldOptions{}
|
|
}
|
|
if err := proto.SetExtension(field.Options, extension, &value); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func SetEnumValueStringFieldOption(field *descriptor.EnumValueDescriptorProto, extension *proto.ExtensionDesc, value string) {
|
|
if _, ok := GetEnumValueStringExtension(field, extension); ok {
|
|
return
|
|
}
|
|
if field.Options == nil {
|
|
field.Options = &descriptor.EnumValueOptions{}
|
|
}
|
|
if err := proto.SetExtension(field.Options, extension, &value); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func GetEnumValueStringExtension(enumValue *descriptor.EnumValueDescriptorProto, extension *proto.ExtensionDesc) (string, bool) {
|
|
if enumValue.Options == nil {
|
|
return "", false
|
|
}
|
|
value, err := proto.GetExtension(enumValue.Options, extension)
|
|
if err != nil {
|
|
return "", false
|
|
}
|
|
if value == nil {
|
|
return "", false
|
|
}
|
|
if v, ok := value.(*string); !ok || v == nil {
|
|
return "", false
|
|
} else {
|
|
return *v, true
|
|
}
|
|
}
|
|
|
|
func GetFieldStringExtension(field *descriptor.FieldDescriptorProto, extension *proto.ExtensionDesc) (string, bool) {
|
|
if field.Options == nil {
|
|
return "", false
|
|
}
|
|
value, err := proto.GetExtension(field.Options, extension)
|
|
if err != nil {
|
|
return "", false
|
|
}
|
|
if value == nil {
|
|
return "", false
|
|
}
|
|
if v, ok := value.(*string); !ok || v == nil {
|
|
return "", false
|
|
} else {
|
|
return *v, true
|
|
}
|
|
}
|
|
|
|
func GetFieldBooleanExtension(field *descriptor.FieldDescriptorProto, extension *proto.ExtensionDesc) (bool, bool) {
|
|
if field.Options == nil {
|
|
return false, false
|
|
}
|
|
value, err := proto.GetExtension(field.Options, extension)
|
|
if err != nil {
|
|
return false, false
|
|
}
|
|
if value == nil {
|
|
return false, false
|
|
}
|
|
if v, ok := value.(*bool); !ok || v == nil {
|
|
return false, false
|
|
} else {
|
|
return *v, true
|
|
}
|
|
}
|
|
|
|
func GetMessageBoolExtension(msg *descriptor.DescriptorProto, extension *proto.ExtensionDesc) (bool, bool) {
|
|
if msg.Options == nil {
|
|
return false, false
|
|
}
|
|
value, err := proto.GetExtension(msg.Options, extension)
|
|
if err != nil {
|
|
return false, false
|
|
}
|
|
if value == nil {
|
|
return false, false
|
|
}
|
|
val, ok := value.(*bool)
|
|
if !ok || val == nil {
|
|
return false, false
|
|
}
|
|
return *val, true
|
|
}
|
|
|
|
func HandleFile(file *descriptor.FileDescriptorProto) {
|
|
vanity.ForEachMessageInFiles([]*descriptor.FileDescriptorProto{file}, HandleCustomExtensions(file))
|
|
}
|
|
|
|
func HandleCustomExtensions(file *descriptor.FileDescriptorProto) func(msg *descriptor.DescriptorProto) {
|
|
return func(msg *descriptor.DescriptorProto) {
|
|
generateXmlTags := true
|
|
if generate, ok := GetMessageBoolExtension(msg, ext.E_XmlTags); ok {
|
|
generateXmlTags = generate
|
|
}
|
|
|
|
vanity.ForEachField([]*descriptor.DescriptorProto{msg}, func(field *descriptor.FieldDescriptorProto) {
|
|
if field.Options == nil {
|
|
field.Options = &descriptor.FieldOptions{}
|
|
}
|
|
deprecated := field.Options.Deprecated != nil && *field.Options.Deprecated == true
|
|
|
|
if field.Type != nil && *field.Type == descriptor.FieldDescriptorProto_TYPE_INT32 {
|
|
SetStringFieldOption(field, gogoproto.E_Casttype, "int")
|
|
}
|
|
|
|
if field.TypeName != nil && *field.TypeName == ".google.protobuf.Timestamp" {
|
|
vanity.SetBoolFieldOption(gogoproto.E_Stdtime, true)(field)
|
|
}
|
|
|
|
if goName, ok := GetFieldStringExtension(field, ext.E_Goname); ok {
|
|
SetStringFieldOption(field, gogoproto.E_Customname, goName)
|
|
} else if deprecated {
|
|
SetStringFieldOption(field, gogoproto.E_Customname, "Deprecated"+toCamelCase(*field.Name, true))
|
|
}
|
|
|
|
if goType, ok := GetFieldStringExtension(field, ext.E_Gotype); ok {
|
|
SetStringFieldOption(field, gogoproto.E_Customtype, goType)
|
|
}
|
|
|
|
if val, ok := GetFieldBooleanExtension(field, ext.E_DeviceId); ok && val {
|
|
if *file.Options.GoPackage != "github.com/syncthing/syncthing/lib/protocol" {
|
|
SetStringFieldOption(field, gogoproto.E_Customtype, "github.com/syncthing/syncthing/lib/protocol.DeviceID")
|
|
} else {
|
|
SetStringFieldOption(field, gogoproto.E_Customtype, "DeviceID")
|
|
}
|
|
}
|
|
|
|
if jsonValue, ok := GetFieldStringExtension(field, ext.E_Json); ok {
|
|
SetStringFieldOption(field, gogoproto.E_Jsontag, jsonValue)
|
|
} else if deprecated {
|
|
SetStringFieldOption(field, gogoproto.E_Jsontag, "-")
|
|
} else {
|
|
SetStringFieldOption(field, gogoproto.E_Jsontag, toCamelCase(*field.Name, false))
|
|
}
|
|
|
|
current := ""
|
|
if v, ok := GetFieldStringExtension(field, gogoproto.E_Moretags); ok {
|
|
current = v
|
|
}
|
|
|
|
if generateXmlTags {
|
|
if len(current) > 0 {
|
|
current += " "
|
|
}
|
|
if xmlValue, ok := GetFieldStringExtension(field, ext.E_Xml); ok {
|
|
current += fmt.Sprintf(`xml:"%s"`, xmlValue)
|
|
} else {
|
|
xmlValue = toCamelCase(*field.Name, false)
|
|
// XML dictates element name within the collection, not collection name, so trim plural suffix.
|
|
if field.IsRepeated() {
|
|
if strings.HasSuffix(xmlValue, "ses") {
|
|
// addresses -> address
|
|
xmlValue = strings.TrimSuffix(xmlValue, "es")
|
|
} else {
|
|
// devices -> device
|
|
xmlValue = strings.TrimSuffix(xmlValue, "s")
|
|
}
|
|
}
|
|
if deprecated {
|
|
xmlValue += ",omitempty"
|
|
}
|
|
current += fmt.Sprintf(`xml:"%s"`, xmlValue)
|
|
}
|
|
}
|
|
|
|
if defaultValue, ok := GetFieldStringExtension(field, ext.E_Default); ok {
|
|
if len(current) > 0 {
|
|
current += " "
|
|
}
|
|
current += fmt.Sprintf(`default:"%s"`, defaultValue)
|
|
}
|
|
|
|
if nodefaultValue, ok := GetFieldBooleanExtension(field, ext.E_Nodefault); ok {
|
|
if len(current) > 0 {
|
|
current += " "
|
|
}
|
|
current += fmt.Sprintf(`nodefault:"%t"`, nodefaultValue)
|
|
}
|
|
|
|
if restartValue, ok := GetFieldBooleanExtension(field, ext.E_Restart); ok {
|
|
if len(current) > 0 {
|
|
current += " "
|
|
}
|
|
current += fmt.Sprintf(`restart:"%t"`, restartValue)
|
|
}
|
|
|
|
SetStringFieldOption(field, gogoproto.E_Moretags, current)
|
|
})
|
|
}
|
|
}
|