Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
f93f144288 | |||
56b9570287 | |||
ba9e54d1fb | |||
ce58df8a6d | |||
c5c87da714 | |||
05a0af6b74 | |||
4c3954ec76 | |||
67d1a1d8e5 |
@ -21,8 +21,6 @@ func main() {
|
|||||||
var modelPath string
|
var modelPath string
|
||||||
var edgeVerbosity int
|
var edgeVerbosity int
|
||||||
var imgWidth, imgHeight, horizon int
|
var imgWidth, imgHeight, horizon int
|
||||||
var debug bool
|
|
||||||
|
|
||||||
|
|
||||||
mqttQos := cli.InitIntFlag("MQTT_QOS", 0)
|
mqttQos := cli.InitIntFlag("MQTT_QOS", 0)
|
||||||
_, mqttRetain := os.LookupEnv("MQTT_RETAIN")
|
_, mqttRetain := os.LookupEnv("MQTT_RETAIN")
|
||||||
@ -36,20 +34,16 @@ func main() {
|
|||||||
flag.IntVar(&imgWidth, "img-width", 0, "image width expected by model (mandatory)")
|
flag.IntVar(&imgWidth, "img-width", 0, "image width expected by model (mandatory)")
|
||||||
flag.IntVar(&imgHeight, "img-height", 0, "image height expected by model (mandatory)")
|
flag.IntVar(&imgHeight, "img-height", 0, "image height expected by model (mandatory)")
|
||||||
flag.IntVar(&horizon, "horizon", 0, "upper zone to crop from image. Models expect size 'imgHeight - horizon'")
|
flag.IntVar(&horizon, "horizon", 0, "upper zone to crop from image. Models expect size 'imgHeight - horizon'")
|
||||||
flag.BoolVar(&debug, "debug", false, "Display debug logs")
|
logLevel := zap.LevelFlag("log", zap.InfoLevel, "log level")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if len(os.Args) <= 1 {
|
if len(os.Args) <= 1 {
|
||||||
flag.PrintDefaults()
|
flag.PrintDefaults()
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
config := zap.NewDevelopmentConfig()
|
config := zap.NewDevelopmentConfig()
|
||||||
if debug {
|
config.Level = zap.NewAtomicLevelAt(*logLevel)
|
||||||
config.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
|
|
||||||
} else {
|
|
||||||
config.Level = zap.NewAtomicLevelAt(zap.InfoLevel)
|
|
||||||
}
|
|
||||||
lgr, err := config.Build()
|
lgr, err := config.Build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("unable to init logger: %v", err)
|
log.Fatalf("unable to init logger: %v", err)
|
||||||
|
26
go.mod
26
go.mod
@ -3,30 +3,32 @@ module github.com/cyrilix/robocar-steering-tflite-edgetpu
|
|||||||
go 1.17
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cyrilix/robocar-base v0.1.5
|
github.com/cyrilix/robocar-base v0.1.6
|
||||||
github.com/cyrilix/robocar-protobuf/go v1.0.3
|
github.com/cyrilix/robocar-protobuf/go v1.0.4
|
||||||
github.com/disintegration/imaging v1.6.2
|
github.com/disintegration/imaging v1.6.2
|
||||||
github.com/eclipse/paho.mqtt.golang v1.3.5
|
github.com/eclipse/paho.mqtt.golang v1.3.5
|
||||||
github.com/golang/protobuf v1.5.2
|
|
||||||
github.com/mattn/go-tflite v1.0.2-0.20210524070808-ba19dc99415b
|
github.com/mattn/go-tflite v1.0.2-0.20210524070808-ba19dc99415b
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.25.0
|
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.26.0
|
||||||
go.opentelemetry.io/otel/metric v0.25.0
|
go.opentelemetry.io/otel/metric v0.26.0
|
||||||
go.opentelemetry.io/otel/sdk/export/metric v0.25.0
|
go.opentelemetry.io/otel/sdk/metric v0.26.0
|
||||||
go.opentelemetry.io/otel/sdk/metric v0.25.0
|
|
||||||
go.uber.org/zap v1.19.1
|
go.uber.org/zap v1.19.1
|
||||||
|
google.golang.org/protobuf v1.27.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/go-logr/logr v1.2.1 // indirect
|
||||||
|
github.com/go-logr/stdr v1.2.0 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
github.com/gorilla/websocket v1.4.2 // indirect
|
github.com/gorilla/websocket v1.4.2 // indirect
|
||||||
github.com/mattn/go-pointer v0.0.1 // indirect
|
github.com/mattn/go-pointer v0.0.1 // indirect
|
||||||
go.opentelemetry.io/otel v1.2.0 // indirect
|
go.opentelemetry.io/otel v1.3.0 // indirect
|
||||||
go.opentelemetry.io/otel/internal/metric v0.25.0 // indirect
|
go.opentelemetry.io/otel/internal/metric v0.26.0 // indirect
|
||||||
go.opentelemetry.io/otel/sdk v1.2.0 // indirect
|
go.opentelemetry.io/otel/sdk v1.3.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.2.0 // indirect
|
go.opentelemetry.io/otel/sdk/export/metric v0.26.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/trace v1.3.0 // indirect
|
||||||
go.uber.org/atomic v1.7.0 // indirect
|
go.uber.org/atomic v1.7.0 // indirect
|
||||||
go.uber.org/multierr v1.6.0 // indirect
|
go.uber.org/multierr v1.6.0 // indirect
|
||||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 // indirect
|
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 // indirect
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect
|
||||||
google.golang.org/protobuf v1.26.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
52
go.sum
52
go.sum
@ -4,17 +4,17 @@ github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcy
|
|||||||
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
||||||
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
|
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
|
||||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
github.com/benbjohnson/clock v1.2.0 h1:9Re3G2TWxkE06LdMWMpcY6KV81GLXMGiYpPYUPkFAws=
|
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||||
github.com/benbjohnson/clock v1.2.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
github.com/cyrilix/robocar-base v0.1.5 h1:EfbYHB69hgyQCVuzZ9/ifdSrQfXS7+04M8O9BDu1/5w=
|
github.com/cyrilix/robocar-base v0.1.6 h1:VVcSZD8DPsha3XDLxRBMvtcd6uC8CcIjqbxG482dxvo=
|
||||||
github.com/cyrilix/robocar-base v0.1.5/go.mod h1:tb7R5OFoBn9EWNLX3Kzx6R/3cQ9/7r8XsHvlLSESOAM=
|
github.com/cyrilix/robocar-base v0.1.6/go.mod h1:m5ov/7hpRHi0yMp2prKafL6UEsM2O71Uea85WR0/jjI=
|
||||||
github.com/cyrilix/robocar-protobuf/go v1.0.3 h1:iPHw2+7FVXG2C4+Th1m11hQ+2RpAQzlxKhc5M7XOa6Q=
|
github.com/cyrilix/robocar-protobuf/go v1.0.4 h1:XTolFYbiKw4gQ2l+z/LMZkLrmAUMzlHcQBzp/czlANo=
|
||||||
github.com/cyrilix/robocar-protobuf/go v1.0.3/go.mod h1:xb95cK07lYXnKcHZKnGafmAgYRrqZWZgV9LMiJAp+gE=
|
github.com/cyrilix/robocar-protobuf/go v1.0.4/go.mod h1:1fyGMVm4ZodfYRrbWCEQgtvKyvrhyTBe5zA7/Qeh/H0=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@ -38,6 +38,11 @@ github.com/go-gl/gl v0.0.0-20190320180904-bf2b1f2f34d7/go.mod h1:482civXOzJJCPzJ
|
|||||||
github.com/go-gl/glfw v0.0.0-20180426074136-46a8d530c326/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20180426074136-46a8d530c326/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-gl/mathgl v0.0.0-20190416160123-c4601bc793c7/go.mod h1:yhpkQzEiH9yPyxDUGzkmgScbaBVlhC06qodikEM0ZwQ=
|
github.com/go-gl/mathgl v0.0.0-20190416160123-c4601bc793c7/go.mod h1:yhpkQzEiH9yPyxDUGzkmgScbaBVlhC06qodikEM0ZwQ=
|
||||||
|
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
|
github.com/go-logr/logr v1.2.1 h1:DX7uPQ4WgAWfoh+NGGlbJQswnYIVvz0SRlLS3rPZQDA=
|
||||||
|
github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
|
github.com/go-logr/stdr v1.2.0 h1:j4LrlVXgrbIWO83mmQUnK0Hi+YnbD+vzrE1z/EphbFE=
|
||||||
|
github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI=
|
||||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||||
@ -114,22 +119,22 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM
|
|||||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||||
github.com/vincent-petithory/dataurl v0.0.0-20191104211930-d1553a71de50/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U=
|
github.com/vincent-petithory/dataurl v0.0.0-20191104211930-d1553a71de50/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
go.opentelemetry.io/otel v1.2.0 h1:YOQDvxO1FayUcT9MIhJhgMyNO1WqoduiyvQHzGN0kUQ=
|
go.opentelemetry.io/otel v1.3.0 h1:APxLf0eiBwLl+SOXiJJCVYzA1OOJNyAoV8C5RNRyy7Y=
|
||||||
go.opentelemetry.io/otel v1.2.0/go.mod h1:aT17Fk0Z1Nor9e0uisf98LrntPGMnk4frBO9+dkf69I=
|
go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs=
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.25.0 h1:XyBEWc22bxYllvyeG3bmW0G4esJ8Wi6P2m0e/tIuMsE=
|
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.26.0 h1:w7fF+cx3zdxURlLuVhzuYt6BT9COyecNfYYhtHXZoDc=
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.25.0/go.mod h1:Mn5lMLB4mIMKZ1IR4qCoYspC4lEbfK6pD7bI3SSAMKk=
|
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.26.0/go.mod h1:Q4v85sm7QpfKDGBdHSMn1pKqvwtQ4I7JgtuRIjRi17U=
|
||||||
go.opentelemetry.io/otel/internal/metric v0.25.0 h1:w/7RXe16WdPylaIXDgcYM6t/q0K5lXgSdZOEbIEyliE=
|
go.opentelemetry.io/otel/internal/metric v0.26.0 h1:dlrvawyd/A+X8Jp0EBT4wWEe4k5avYaXsXrBr4dbfnY=
|
||||||
go.opentelemetry.io/otel/internal/metric v0.25.0/go.mod h1:Nhuw26QSX7d6n4duoqAFi5KOQR4AuzyMcl5eXOgwxtc=
|
go.opentelemetry.io/otel/internal/metric v0.26.0/go.mod h1:CbBP6AxKynRs3QCbhklyLUtpfzbqCLiafV9oY2Zj1Jk=
|
||||||
go.opentelemetry.io/otel/metric v0.25.0 h1:7cXOnCADUsR3+EOqxPaSKwhEuNu0gz/56dRN1hpIdKw=
|
go.opentelemetry.io/otel/metric v0.26.0 h1:VaPYBTvA13h/FsiWfxa3yZnZEm15BhStD8JZQSA773M=
|
||||||
go.opentelemetry.io/otel/metric v0.25.0/go.mod h1:E884FSpQfnJOMMUaq+05IWlJ4rjZpk2s/F1Ju+TEEm8=
|
go.opentelemetry.io/otel/metric v0.26.0/go.mod h1:c6YL0fhRo4YVoNs6GoByzUgBp36hBL523rECoZA5UWg=
|
||||||
go.opentelemetry.io/otel/sdk v1.2.0 h1:wKN260u4DesJYhyjxDa7LRFkuhH7ncEVKU37LWcyNIo=
|
go.opentelemetry.io/otel/sdk v1.3.0 h1:3278edCoH89MEJ0Ky8WQXVmDQv3FX4ZJ3Pp+9fJreAI=
|
||||||
go.opentelemetry.io/otel/sdk v1.2.0/go.mod h1:jNN8QtpvbsKhgaC6V5lHiejMoKD+V8uadoSafgHPx1U=
|
go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs=
|
||||||
go.opentelemetry.io/otel/sdk/export/metric v0.25.0 h1:6UjAFmVB5Fza3K5qUJpYWGrk8QMPIqlSnya5FI46VBY=
|
go.opentelemetry.io/otel/sdk/export/metric v0.26.0 h1:eNseg5yyZqaAAY+Att3owR3Bl0Is5rCZywqO1OrGx18=
|
||||||
go.opentelemetry.io/otel/sdk/export/metric v0.25.0/go.mod h1:Ej7NOa+WpN49EIcr1HMUYRvxXXCCnQCg2+ovdt2z8Pk=
|
go.opentelemetry.io/otel/sdk/export/metric v0.26.0/go.mod h1:UpqzSnUOjFeSIVQLPp3pYIXfB/MiMFyXXzYT/bercxQ=
|
||||||
go.opentelemetry.io/otel/sdk/metric v0.25.0 h1:J+Ta+4IAA5W9AdWhGQLfciEpavBqqSkBzTDeYvJLFNU=
|
go.opentelemetry.io/otel/sdk/metric v0.26.0 h1:7IKp3gc/ObieCtshBeYYVFp3ZP7xIH1OzODi1Wao90Y=
|
||||||
go.opentelemetry.io/otel/sdk/metric v0.25.0/go.mod h1:G4xzj4LvC6xDDSsVXpvRVclQCbofGGg4ZU2VKKtDRfg=
|
go.opentelemetry.io/otel/sdk/metric v0.26.0/go.mod h1:2VIeK0kS1YvRLFg3J58ptZTXYpiWlkq2n5RQt6w7He8=
|
||||||
go.opentelemetry.io/otel/trace v1.2.0 h1:Ys3iqbqZhcf28hHzrm5WAquMkDHNZTUkw7KHbuNjej0=
|
go.opentelemetry.io/otel/trace v1.3.0 h1:doy8Hzb1RJ+I3yFhtDmwNc7tIyw1tNMOIsyPzp1NOGY=
|
||||||
go.opentelemetry.io/otel/trace v1.2.0/go.mod h1:N5FLswTubnxKxOJHM7XZC074qpeEdLy3CgAVsdMucK0=
|
go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk=
|
||||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4=
|
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4=
|
||||||
@ -201,8 +206,9 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
|
|||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
|
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||||
|
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
|
@ -7,15 +7,15 @@ import (
|
|||||||
"github.com/cyrilix/robocar-base/service"
|
"github.com/cyrilix/robocar-base/service"
|
||||||
"github.com/cyrilix/robocar-protobuf/go/events"
|
"github.com/cyrilix/robocar-protobuf/go/events"
|
||||||
"github.com/cyrilix/robocar-steering-tflite-edgetpu/pkg/metrics"
|
"github.com/cyrilix/robocar-steering-tflite-edgetpu/pkg/metrics"
|
||||||
|
"github.com/cyrilix/robocar-steering-tflite-edgetpu/pkg/tools"
|
||||||
"github.com/disintegration/imaging"
|
"github.com/disintegration/imaging"
|
||||||
mqtt "github.com/eclipse/paho.mqtt.golang"
|
mqtt "github.com/eclipse/paho.mqtt.golang"
|
||||||
"github.com/golang/protobuf/proto"
|
|
||||||
"github.com/mattn/go-tflite"
|
"github.com/mattn/go-tflite"
|
||||||
"github.com/mattn/go-tflite/delegates/edgetpu"
|
"github.com/mattn/go-tflite/delegates/edgetpu"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
"image"
|
"image"
|
||||||
_ "image/jpeg"
|
_ "image/jpeg"
|
||||||
"sort"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -137,7 +137,6 @@ func (p *Part) onFrame(_ mqtt.Client, message mqtt.Message) {
|
|||||||
frameAge := now - msg.Id.CreatedAt.AsTime().UnixMilli()
|
frameAge := now - msg.Id.CreatedAt.AsTime().UnixMilli()
|
||||||
go metrics.FrameAge.Record(context.Background(), frameAge)
|
go metrics.FrameAge.Record(context.Background(), frameAge)
|
||||||
|
|
||||||
|
|
||||||
img, _, err := image.Decode(bytes.NewReader(msg.GetFrame()))
|
img, _, err := image.Decode(bytes.NewReader(msg.GetFrame()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zap.L().Error("unable to decode frame, skip frame", zap.Error(err))
|
zap.L().Error("unable to decode frame, skip frame", zap.Error(err))
|
||||||
@ -193,13 +192,13 @@ func (p *Part) Value(img image.Image) (float32, float32, error) {
|
|||||||
dx = img.Bounds().Dx()
|
dx = img.Bounds().Dx()
|
||||||
dy = img.Bounds().Dy()
|
dy = img.Bounds().Dy()
|
||||||
|
|
||||||
bb := make([]byte, dx*dy*3)
|
bb := make([]uint8, dx*dy*3)
|
||||||
for y := 0; y < dy; y++ {
|
for y := 0; y < dy; y++ {
|
||||||
for x := 0; x < dx; x++ {
|
for x := 0; x < dx; x++ {
|
||||||
r, g, b, _ := img.At(x, y).RGBA()
|
r, g, b, _ := img.At(x, y).RGBA()
|
||||||
bb[(y*dx+x)*3+0] = byte(float64(r) / 255.0)
|
bb[(y*dx+x)*3+0] = uint8(float64(r) / 257.0)
|
||||||
bb[(y*dx+x)*3+1] = byte(float64(g) / 255.0)
|
bb[(y*dx+x)*3+1] = uint8(float64(g) / 257.0)
|
||||||
bb[(y*dx+x)*3+2] = byte(float64(b) / 255.0)
|
bb[(y*dx+x)*3+2] = uint8(float64(b) / 257.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
status = input.CopyFromBuffer(bb)
|
status = input.CopyFromBuffer(bb)
|
||||||
@ -212,42 +211,15 @@ func (p *Part) Value(img image.Image) (float32, float32, error) {
|
|||||||
return 0., 0., fmt.Errorf("invoke failed: %v", status)
|
return 0., 0., fmt.Errorf("invoke failed: %v", status)
|
||||||
}
|
}
|
||||||
|
|
||||||
output := p.interpreter.GetOutputTensor(0)
|
output := p.interpreter.GetOutputTensor(0).UInt8s()
|
||||||
outputSize := output.Dim(output.NumDims() - 1)
|
zap.L().Debug("raw steering", zap.Uint8s("result", output))
|
||||||
b := make([]byte, outputSize)
|
|
||||||
type result struct {
|
|
||||||
score float64
|
|
||||||
index int
|
|
||||||
}
|
|
||||||
status = output.CopyToBuffer(&b[0])
|
|
||||||
if status != tflite.OK {
|
|
||||||
return 0., 0., fmt.Errorf("output failed: %v", status)
|
|
||||||
}
|
|
||||||
|
|
||||||
var results []result
|
steering, score := tools.LinearBin(output, 15, -1, 2.0)
|
||||||
minScore := 0.2
|
|
||||||
for i := 0; i < outputSize; i++ {
|
|
||||||
score := float64(b[i]) / 255.0
|
|
||||||
if score < minScore {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
results = append(results, result{score: score, index: i})
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(results) == 0 {
|
|
||||||
zap.L().Warn(fmt.Sprintf("none steering with score > %0.2f found", minScore))
|
|
||||||
return 0., 0., nil
|
|
||||||
}
|
|
||||||
sort.Slice(results, func(i, j int) bool {
|
|
||||||
return results[i].score > results[j].score
|
|
||||||
})
|
|
||||||
|
|
||||||
steering := float64(results[0].index)*(2./float64(outputSize)) - 1
|
|
||||||
zap.L().Debug("found steering",
|
zap.L().Debug("found steering",
|
||||||
zap.Float64("steering", steering),
|
zap.Float64("steering", steering),
|
||||||
zap.Float64("score", results[0].score),
|
zap.Float64("score", score),
|
||||||
)
|
)
|
||||||
return float32(steering), float32(results[0].score), nil
|
return float32(steering), float32(score), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var registerCallbacks = func(p *Part) error {
|
var registerCallbacks = func(p *Part) error {
|
||||||
|
40
pkg/tools/tools.go
Normal file
40
pkg/tools/tools.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package tools
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LinearBin perform inverse linear_bin, taking
|
||||||
|
func LinearBin(arr []uint8, n int, offset int, r float64) (float64, float64) {
|
||||||
|
outputSize := len(arr)
|
||||||
|
type result struct {
|
||||||
|
score float64
|
||||||
|
index int
|
||||||
|
}
|
||||||
|
|
||||||
|
var results []result
|
||||||
|
minScore := 0.2
|
||||||
|
for i := 0; i < outputSize; i++ {
|
||||||
|
score := float64(int(arr[i])) / 255.0
|
||||||
|
if score < minScore {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
results = append(results, result{score: score, index: i})
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(results) == 0 {
|
||||||
|
zap.L().Warn(fmt.Sprintf("none steering with score > %0.2f found", minScore))
|
||||||
|
return 0., 0.
|
||||||
|
}
|
||||||
|
zap.S().Debugf("raw result: %v", results)
|
||||||
|
|
||||||
|
sort.Slice(results, func(i, j int) bool {
|
||||||
|
return results[i].score > results[j].score
|
||||||
|
})
|
||||||
|
|
||||||
|
b := results[0].index
|
||||||
|
a := float64(b)*(r/(float64(n)+float64(offset))) + float64(offset)
|
||||||
|
return a, results[0].score
|
||||||
|
}
|
77
pkg/tools/tools_test.go
Normal file
77
pkg/tools/tools_test.go
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package tools
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_LinearBin(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
arr []byte
|
||||||
|
n int
|
||||||
|
offset int
|
||||||
|
r float64
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want float64
|
||||||
|
want1 float64
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "default",
|
||||||
|
args: args{
|
||||||
|
arr: []byte{0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
n: 15,
|
||||||
|
offset: -1,
|
||||||
|
r: 2.0,
|
||||||
|
},
|
||||||
|
want: 0.,
|
||||||
|
want1: 1.0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "left",
|
||||||
|
args: args{
|
||||||
|
arr: []byte{255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
n: 15,
|
||||||
|
offset: -1,
|
||||||
|
r: 2.0,
|
||||||
|
},
|
||||||
|
want: -1.,
|
||||||
|
want1: 1.0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "right",
|
||||||
|
args: args{
|
||||||
|
arr: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255},
|
||||||
|
n: 15,
|
||||||
|
offset: -1,
|
||||||
|
r: 2.0,
|
||||||
|
},
|
||||||
|
want: 1.,
|
||||||
|
want1: 1.0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "right",
|
||||||
|
args: args{
|
||||||
|
arr: []byte{0, 0, 0, 0, 0, 0, 0, 5, 10, 15, 20, 40, 100, 60, 5},
|
||||||
|
n: 15,
|
||||||
|
offset: -1,
|
||||||
|
r: 2.0,
|
||||||
|
},
|
||||||
|
want: 0.7142857142857142,
|
||||||
|
want1: 0.39215686274509803,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, got1 := LinearBin(tt.args.arr, tt.args.n, tt.args.offset, tt.args.r)
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("linearBin() got = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
if got1 != tt.want1 {
|
||||||
|
t.Errorf("linearBin() got1 = %v, want %v", got1, tt.want1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
2
vendor/github.com/cyrilix/robocar-protobuf/go/events/events.pb.go
generated
vendored
2
vendor/github.com/cyrilix/robocar-protobuf/go/events/events.pb.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.26.0
|
// protoc-gen-go v1.27.1
|
||||||
// protoc v3.12.4
|
// protoc v3.12.4
|
||||||
// source: events/events.proto
|
// source: events/events.proto
|
||||||
|
|
||||||
|
29
vendor/github.com/go-logr/logr/.golangci.yaml
generated
vendored
Normal file
29
vendor/github.com/go-logr/logr/.golangci.yaml
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
run:
|
||||||
|
timeout: 1m
|
||||||
|
tests: true
|
||||||
|
|
||||||
|
linters:
|
||||||
|
disable-all: true
|
||||||
|
enable:
|
||||||
|
- asciicheck
|
||||||
|
- deadcode
|
||||||
|
- errcheck
|
||||||
|
- forcetypeassert
|
||||||
|
- gocritic
|
||||||
|
- gofmt
|
||||||
|
- goimports
|
||||||
|
- gosimple
|
||||||
|
- govet
|
||||||
|
- ineffassign
|
||||||
|
- misspell
|
||||||
|
- revive
|
||||||
|
- staticcheck
|
||||||
|
- structcheck
|
||||||
|
- typecheck
|
||||||
|
- unused
|
||||||
|
- varcheck
|
||||||
|
|
||||||
|
issues:
|
||||||
|
exclude-use-default: false
|
||||||
|
max-issues-per-linter: 0
|
||||||
|
max-same-issues: 10
|
6
vendor/github.com/go-logr/logr/CHANGELOG.md
generated
vendored
Normal file
6
vendor/github.com/go-logr/logr/CHANGELOG.md
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# CHANGELOG
|
||||||
|
|
||||||
|
## v1.0.0-rc1
|
||||||
|
|
||||||
|
This is the first logged release. Major changes (including breaking changes)
|
||||||
|
have occurred since earlier tags.
|
17
vendor/github.com/go-logr/logr/CONTRIBUTING.md
generated
vendored
Normal file
17
vendor/github.com/go-logr/logr/CONTRIBUTING.md
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Contributing
|
||||||
|
|
||||||
|
Logr is open to pull-requests, provided they fit within the intended scope of
|
||||||
|
the project. Specifically, this library aims to be VERY small and minimalist,
|
||||||
|
with no external dependencies.
|
||||||
|
|
||||||
|
## Compatibility
|
||||||
|
|
||||||
|
This project intends to follow [semantic versioning](http://semver.org) and
|
||||||
|
is very strict about compatibility. Any proposed changes MUST follow those
|
||||||
|
rules.
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
As a logging library, logr must be as light-weight as possible. Any proposed
|
||||||
|
code change must include results of running the [benchmark](./benchmark)
|
||||||
|
before and after the change.
|
201
vendor/github.com/go-logr/logr/LICENSE
generated
vendored
Normal file
201
vendor/github.com/go-logr/logr/LICENSE
generated
vendored
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
278
vendor/github.com/go-logr/logr/README.md
generated
vendored
Normal file
278
vendor/github.com/go-logr/logr/README.md
generated
vendored
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
# A minimal logging API for Go
|
||||||
|
|
||||||
|
[](https://pkg.go.dev/github.com/go-logr/logr)
|
||||||
|
|
||||||
|
logr offers an(other) opinion on how Go programs and libraries can do logging
|
||||||
|
without becoming coupled to a particular logging implementation. This is not
|
||||||
|
an implementation of logging - it is an API. In fact it is two APIs with two
|
||||||
|
different sets of users.
|
||||||
|
|
||||||
|
The `Logger` type is intended for application and library authors. It provides
|
||||||
|
a relatively small API which can be used everywhere you want to emit logs. It
|
||||||
|
defers the actual act of writing logs (to files, to stdout, or whatever) to the
|
||||||
|
`LogSink` interface.
|
||||||
|
|
||||||
|
The `LogSink` interface is intended for logging library implementers. It is a
|
||||||
|
pure interface which can be implemented by logging frameworks to provide the actual logging
|
||||||
|
functionality.
|
||||||
|
|
||||||
|
This decoupling allows application and library developers to write code in
|
||||||
|
terms of `logr.Logger` (which has very low dependency fan-out) while the
|
||||||
|
implementation of logging is managed "up stack" (e.g. in or near `main()`.)
|
||||||
|
Application developers can then switch out implementations as necessary.
|
||||||
|
|
||||||
|
Many people assert that libraries should not be logging, and as such efforts
|
||||||
|
like this are pointless. Those people are welcome to convince the authors of
|
||||||
|
the tens-of-thousands of libraries that *DO* write logs that they are all
|
||||||
|
wrong. In the meantime, logr takes a more practical approach.
|
||||||
|
|
||||||
|
## Typical usage
|
||||||
|
|
||||||
|
Somewhere, early in an application's life, it will make a decision about which
|
||||||
|
logging library (implementation) it actually wants to use. Something like:
|
||||||
|
|
||||||
|
```
|
||||||
|
func main() {
|
||||||
|
// ... other setup code ...
|
||||||
|
|
||||||
|
// Create the "root" logger. We have chosen the "logimpl" implementation,
|
||||||
|
// which takes some initial parameters and returns a logr.Logger.
|
||||||
|
logger := logimpl.New(param1, param2)
|
||||||
|
|
||||||
|
// ... other setup code ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Most apps will call into other libraries, create structures to govern the flow,
|
||||||
|
etc. The `logr.Logger` object can be passed to these other libraries, stored
|
||||||
|
in structs, or even used as a package-global variable, if needed. For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
app := createTheAppObject(logger)
|
||||||
|
app.Run()
|
||||||
|
```
|
||||||
|
|
||||||
|
Outside of this early setup, no other packages need to know about the choice of
|
||||||
|
implementation. They write logs in terms of the `logr.Logger` that they
|
||||||
|
received:
|
||||||
|
|
||||||
|
```
|
||||||
|
type appObject struct {
|
||||||
|
// ... other fields ...
|
||||||
|
logger logr.Logger
|
||||||
|
// ... other fields ...
|
||||||
|
}
|
||||||
|
|
||||||
|
func (app *appObject) Run() {
|
||||||
|
app.logger.Info("starting up", "timestamp", time.Now())
|
||||||
|
|
||||||
|
// ... app code ...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
If the Go standard library had defined an interface for logging, this project
|
||||||
|
probably would not be needed. Alas, here we are.
|
||||||
|
|
||||||
|
### Inspiration
|
||||||
|
|
||||||
|
Before you consider this package, please read [this blog post by the
|
||||||
|
inimitable Dave Cheney][warning-makes-no-sense]. We really appreciate what
|
||||||
|
he has to say, and it largely aligns with our own experiences.
|
||||||
|
|
||||||
|
### Differences from Dave's ideas
|
||||||
|
|
||||||
|
The main differences are:
|
||||||
|
|
||||||
|
1. Dave basically proposes doing away with the notion of a logging API in favor
|
||||||
|
of `fmt.Printf()`. We disagree, especially when you consider things like output
|
||||||
|
locations, timestamps, file and line decorations, and structured logging. This
|
||||||
|
package restricts the logging API to just 2 types of logs: info and error.
|
||||||
|
|
||||||
|
Info logs are things you want to tell the user which are not errors. Error
|
||||||
|
logs are, well, errors. If your code receives an `error` from a subordinate
|
||||||
|
function call and is logging that `error` *and not returning it*, use error
|
||||||
|
logs.
|
||||||
|
|
||||||
|
2. Verbosity-levels on info logs. This gives developers a chance to indicate
|
||||||
|
arbitrary grades of importance for info logs, without assigning names with
|
||||||
|
semantic meaning such as "warning", "trace", and "debug." Superficially this
|
||||||
|
may feel very similar, but the primary difference is the lack of semantics.
|
||||||
|
Because verbosity is a numerical value, it's safe to assume that an app running
|
||||||
|
with higher verbosity means more (and less important) logs will be generated.
|
||||||
|
|
||||||
|
## Implementations (non-exhaustive)
|
||||||
|
|
||||||
|
There are implementations for the following logging libraries:
|
||||||
|
|
||||||
|
- **a function** (can bridge to non-structured libraries): [funcr](https://github.com/go-logr/logr/tree/master/funcr)
|
||||||
|
- **github.com/google/glog**: [glogr](https://github.com/go-logr/glogr)
|
||||||
|
- **k8s.io/klog** (for Kubernetes): [klogr](https://git.k8s.io/klog/klogr)
|
||||||
|
- **go.uber.org/zap**: [zapr](https://github.com/go-logr/zapr)
|
||||||
|
- **log** (the Go standard library logger): [stdr](https://github.com/go-logr/stdr)
|
||||||
|
- **github.com/sirupsen/logrus**: [logrusr](https://github.com/bombsimon/logrusr)
|
||||||
|
- **github.com/wojas/genericr**: [genericr](https://github.com/wojas/genericr) (makes it easy to implement your own backend)
|
||||||
|
- **logfmt** (Heroku style [logging](https://www.brandur.org/logfmt)): [logfmtr](https://github.com/iand/logfmtr)
|
||||||
|
- **github.com/rs/zerolog**: [zerologr](https://github.com/go-logr/zerologr)
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
### Conceptual
|
||||||
|
|
||||||
|
#### Why structured logging?
|
||||||
|
|
||||||
|
- **Structured logs are more easily queryable**: Since you've got
|
||||||
|
key-value pairs, it's much easier to query your structured logs for
|
||||||
|
particular values by filtering on the contents of a particular key --
|
||||||
|
think searching request logs for error codes, Kubernetes reconcilers for
|
||||||
|
the name and namespace of the reconciled object, etc.
|
||||||
|
|
||||||
|
- **Structured logging makes it easier to have cross-referenceable logs**:
|
||||||
|
Similarly to searchability, if you maintain conventions around your
|
||||||
|
keys, it becomes easy to gather all log lines related to a particular
|
||||||
|
concept.
|
||||||
|
|
||||||
|
- **Structured logs allow better dimensions of filtering**: if you have
|
||||||
|
structure to your logs, you've got more precise control over how much
|
||||||
|
information is logged -- you might choose in a particular configuration
|
||||||
|
to log certain keys but not others, only log lines where a certain key
|
||||||
|
matches a certain value, etc., instead of just having v-levels and names
|
||||||
|
to key off of.
|
||||||
|
|
||||||
|
- **Structured logs better represent structured data**: sometimes, the
|
||||||
|
data that you want to log is inherently structured (think tuple-link
|
||||||
|
objects.) Structured logs allow you to preserve that structure when
|
||||||
|
outputting.
|
||||||
|
|
||||||
|
#### Why V-levels?
|
||||||
|
|
||||||
|
**V-levels give operators an easy way to control the chattiness of log
|
||||||
|
operations**. V-levels provide a way for a given package to distinguish
|
||||||
|
the relative importance or verbosity of a given log message. Then, if
|
||||||
|
a particular logger or package is logging too many messages, the user
|
||||||
|
of the package can simply change the v-levels for that library.
|
||||||
|
|
||||||
|
#### Why not named levels, like Info/Warning/Error?
|
||||||
|
|
||||||
|
Read [Dave Cheney's post][warning-makes-no-sense]. Then read [Differences
|
||||||
|
from Dave's ideas](#differences-from-daves-ideas).
|
||||||
|
|
||||||
|
#### Why not allow format strings, too?
|
||||||
|
|
||||||
|
**Format strings negate many of the benefits of structured logs**:
|
||||||
|
|
||||||
|
- They're not easily searchable without resorting to fuzzy searching,
|
||||||
|
regular expressions, etc.
|
||||||
|
|
||||||
|
- They don't store structured data well, since contents are flattened into
|
||||||
|
a string.
|
||||||
|
|
||||||
|
- They're not cross-referenceable.
|
||||||
|
|
||||||
|
- They don't compress easily, since the message is not constant.
|
||||||
|
|
||||||
|
(Unless you turn positional parameters into key-value pairs with numerical
|
||||||
|
keys, at which point you've gotten key-value logging with meaningless
|
||||||
|
keys.)
|
||||||
|
|
||||||
|
### Practical
|
||||||
|
|
||||||
|
#### Why key-value pairs, and not a map?
|
||||||
|
|
||||||
|
Key-value pairs are *much* easier to optimize, especially around
|
||||||
|
allocations. Zap (a structured logger that inspired logr's interface) has
|
||||||
|
[performance measurements](https://github.com/uber-go/zap#performance)
|
||||||
|
that show this quite nicely.
|
||||||
|
|
||||||
|
While the interface ends up being a little less obvious, you get
|
||||||
|
potentially better performance, plus avoid making users type
|
||||||
|
`map[string]string{}` every time they want to log.
|
||||||
|
|
||||||
|
#### What if my V-levels differ between libraries?
|
||||||
|
|
||||||
|
That's fine. Control your V-levels on a per-logger basis, and use the
|
||||||
|
`WithName` method to pass different loggers to different libraries.
|
||||||
|
|
||||||
|
Generally, you should take care to ensure that you have relatively
|
||||||
|
consistent V-levels within a given logger, however, as this makes deciding
|
||||||
|
on what verbosity of logs to request easier.
|
||||||
|
|
||||||
|
#### But I really want to use a format string!
|
||||||
|
|
||||||
|
That's not actually a question. Assuming your question is "how do
|
||||||
|
I convert my mental model of logging with format strings to logging with
|
||||||
|
constant messages":
|
||||||
|
|
||||||
|
1. Figure out what the error actually is, as you'd write in a TL;DR style,
|
||||||
|
and use that as a message.
|
||||||
|
|
||||||
|
2. For every place you'd write a format specifier, look to the word before
|
||||||
|
it, and add that as a key value pair.
|
||||||
|
|
||||||
|
For instance, consider the following examples (all taken from spots in the
|
||||||
|
Kubernetes codebase):
|
||||||
|
|
||||||
|
- `klog.V(4).Infof("Client is returning errors: code %v, error %v",
|
||||||
|
responseCode, err)` becomes `logger.Error(err, "client returned an
|
||||||
|
error", "code", responseCode)`
|
||||||
|
|
||||||
|
- `klog.V(4).Infof("Got a Retry-After %ds response for attempt %d to %v",
|
||||||
|
seconds, retries, url)` becomes `logger.V(4).Info("got a retry-after
|
||||||
|
response when requesting url", "attempt", retries, "after
|
||||||
|
seconds", seconds, "url", url)`
|
||||||
|
|
||||||
|
If you *really* must use a format string, use it in a key's value, and
|
||||||
|
call `fmt.Sprintf` yourself. For instance: `log.Printf("unable to
|
||||||
|
reflect over type %T")` becomes `logger.Info("unable to reflect over
|
||||||
|
type", "type", fmt.Sprintf("%T"))`. In general though, the cases where
|
||||||
|
this is necessary should be few and far between.
|
||||||
|
|
||||||
|
#### How do I choose my V-levels?
|
||||||
|
|
||||||
|
This is basically the only hard constraint: increase V-levels to denote
|
||||||
|
more verbose or more debug-y logs.
|
||||||
|
|
||||||
|
Otherwise, you can start out with `0` as "you always want to see this",
|
||||||
|
`1` as "common logging that you might *possibly* want to turn off", and
|
||||||
|
`10` as "I would like to performance-test your log collection stack."
|
||||||
|
|
||||||
|
Then gradually choose levels in between as you need them, working your way
|
||||||
|
down from 10 (for debug and trace style logs) and up from 1 (for chattier
|
||||||
|
info-type logs.)
|
||||||
|
|
||||||
|
#### How do I choose my keys?
|
||||||
|
|
||||||
|
Keys are fairly flexible, and can hold more or less any string
|
||||||
|
value. For best compatibility with implementations and consistency
|
||||||
|
with existing code in other projects, there are a few conventions you
|
||||||
|
should consider.
|
||||||
|
|
||||||
|
- Make your keys human-readable.
|
||||||
|
- Constant keys are generally a good idea.
|
||||||
|
- Be consistent across your codebase.
|
||||||
|
- Keys should naturally match parts of the message string.
|
||||||
|
- Use lower case for simple keys and
|
||||||
|
[lowerCamelCase](https://en.wiktionary.org/wiki/lowerCamelCase) for
|
||||||
|
more complex ones. Kubernetes is one example of a project that has
|
||||||
|
[adopted that
|
||||||
|
convention](https://github.com/kubernetes/community/blob/HEAD/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments).
|
||||||
|
|
||||||
|
While key names are mostly unrestricted (and spaces are acceptable),
|
||||||
|
it's generally a good idea to stick to printable ascii characters, or at
|
||||||
|
least match the general character set of your log lines.
|
||||||
|
|
||||||
|
#### Why should keys be constant values?
|
||||||
|
|
||||||
|
The point of structured logging is to make later log processing easier. Your
|
||||||
|
keys are, effectively, the schema of each log message. If you use different
|
||||||
|
keys across instances of the same log line, you will make your structured logs
|
||||||
|
much harder to use. `Sprintf()` is for values, not for keys!
|
||||||
|
|
||||||
|
#### Why is this not a pure interface?
|
||||||
|
|
||||||
|
The Logger type is implemented as a struct in order to allow the Go compiler to
|
||||||
|
optimize things like high-V `Info` logs that are not triggered. Not all of
|
||||||
|
these implementations are implemented yet, but this structure was suggested as
|
||||||
|
a way to ensure they *can* be implemented. All of the real work is behind the
|
||||||
|
`LogSink` interface.
|
||||||
|
|
||||||
|
[warning-makes-no-sense]: http://dave.cheney.net/2015/11/05/lets-talk-about-logging
|
54
vendor/github.com/go-logr/logr/discard.go
generated
vendored
Normal file
54
vendor/github.com/go-logr/logr/discard.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2020 The logr Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package logr
|
||||||
|
|
||||||
|
// Discard returns a Logger that discards all messages logged to it. It can be
|
||||||
|
// used whenever the caller is not interested in the logs. Logger instances
|
||||||
|
// produced by this function always compare as equal.
|
||||||
|
func Discard() Logger {
|
||||||
|
return Logger{
|
||||||
|
level: 0,
|
||||||
|
sink: discardLogSink{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// discardLogSink is a LogSink that discards all messages.
|
||||||
|
type discardLogSink struct{}
|
||||||
|
|
||||||
|
// Verify that it actually implements the interface
|
||||||
|
var _ LogSink = discardLogSink{}
|
||||||
|
|
||||||
|
func (l discardLogSink) Init(RuntimeInfo) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l discardLogSink) Enabled(int) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l discardLogSink) Info(int, string, ...interface{}) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l discardLogSink) Error(error, string, ...interface{}) {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l discardLogSink) WithValues(...interface{}) LogSink {
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l discardLogSink) WithName(string) LogSink {
|
||||||
|
return l
|
||||||
|
}
|
742
vendor/github.com/go-logr/logr/funcr/funcr.go
generated
vendored
Normal file
742
vendor/github.com/go-logr/logr/funcr/funcr.go
generated
vendored
Normal file
@ -0,0 +1,742 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2021 The logr Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Package funcr implements formatting of structured log messages and
|
||||||
|
// optionally captures the call site and timestamp.
|
||||||
|
//
|
||||||
|
// The simplest way to use it is via its implementation of a
|
||||||
|
// github.com/go-logr/logr.LogSink with output through an arbitrary
|
||||||
|
// "write" function. See New and NewJSON for details.
|
||||||
|
//
|
||||||
|
// Custom LogSinks
|
||||||
|
//
|
||||||
|
// For users who need more control, a funcr.Formatter can be embedded inside
|
||||||
|
// your own custom LogSink implementation. This is useful when the LogSink
|
||||||
|
// needs to implement additional methods, for example.
|
||||||
|
//
|
||||||
|
// Formatting
|
||||||
|
//
|
||||||
|
// This will respect logr.Marshaler, fmt.Stringer, and error interfaces for
|
||||||
|
// values which are being logged. When rendering a struct, funcr will use Go's
|
||||||
|
// standard JSON tags (all except "string").
|
||||||
|
package funcr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding"
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/go-logr/logr"
|
||||||
|
)
|
||||||
|
|
||||||
|
// New returns a logr.Logger which is implemented by an arbitrary function.
|
||||||
|
func New(fn func(prefix, args string), opts Options) logr.Logger {
|
||||||
|
return logr.New(newSink(fn, NewFormatter(opts)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewJSON returns a logr.Logger which is implemented by an arbitrary function
|
||||||
|
// and produces JSON output.
|
||||||
|
func NewJSON(fn func(obj string), opts Options) logr.Logger {
|
||||||
|
fnWrapper := func(_, obj string) {
|
||||||
|
fn(obj)
|
||||||
|
}
|
||||||
|
return logr.New(newSink(fnWrapper, NewFormatterJSON(opts)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Underlier exposes access to the underlying logging function. Since
|
||||||
|
// callers only have a logr.Logger, they have to know which
|
||||||
|
// implementation is in use, so this interface is less of an
|
||||||
|
// abstraction and more of a way to test type conversion.
|
||||||
|
type Underlier interface {
|
||||||
|
GetUnderlying() func(prefix, args string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSink(fn func(prefix, args string), formatter Formatter) logr.LogSink {
|
||||||
|
l := &fnlogger{
|
||||||
|
Formatter: formatter,
|
||||||
|
write: fn,
|
||||||
|
}
|
||||||
|
// For skipping fnlogger.Info and fnlogger.Error.
|
||||||
|
l.Formatter.AddCallDepth(1)
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// Options carries parameters which influence the way logs are generated.
|
||||||
|
type Options struct {
|
||||||
|
// LogCaller tells funcr to add a "caller" key to some or all log lines.
|
||||||
|
// This has some overhead, so some users might not want it.
|
||||||
|
LogCaller MessageClass
|
||||||
|
|
||||||
|
// LogCallerFunc tells funcr to also log the calling function name. This
|
||||||
|
// has no effect if caller logging is not enabled (see Options.LogCaller).
|
||||||
|
LogCallerFunc bool
|
||||||
|
|
||||||
|
// LogTimestamp tells funcr to add a "ts" key to log lines. This has some
|
||||||
|
// overhead, so some users might not want it.
|
||||||
|
LogTimestamp bool
|
||||||
|
|
||||||
|
// TimestampFormat tells funcr how to render timestamps when LogTimestamp
|
||||||
|
// is enabled. If not specified, a default format will be used. For more
|
||||||
|
// details, see docs for Go's time.Layout.
|
||||||
|
TimestampFormat string
|
||||||
|
|
||||||
|
// Verbosity tells funcr which V logs to produce. Higher values enable
|
||||||
|
// more logs. Info logs at or below this level will be written, while logs
|
||||||
|
// above this level will be discarded.
|
||||||
|
Verbosity int
|
||||||
|
|
||||||
|
// RenderBuiltinsHook allows users to mutate the list of key-value pairs
|
||||||
|
// while a log line is being rendered. The kvList argument follows logr
|
||||||
|
// conventions - each pair of slice elements is comprised of a string key
|
||||||
|
// and an arbitrary value (verified and sanitized before calling this
|
||||||
|
// hook). The value returned must follow the same conventions. This hook
|
||||||
|
// can be used to audit or modify logged data. For example, you might want
|
||||||
|
// to prefix all of funcr's built-in keys with some string. This hook is
|
||||||
|
// only called for built-in (provided by funcr itself) key-value pairs.
|
||||||
|
// Equivalent hooks are offered for key-value pairs saved via
|
||||||
|
// logr.Logger.WithValues or Formatter.AddValues (see RenderValuesHook) and
|
||||||
|
// for user-provided pairs (see RenderArgsHook).
|
||||||
|
RenderBuiltinsHook func(kvList []interface{}) []interface{}
|
||||||
|
|
||||||
|
// RenderValuesHook is the same as RenderBuiltinsHook, except that it is
|
||||||
|
// only called for key-value pairs saved via logr.Logger.WithValues. See
|
||||||
|
// RenderBuiltinsHook for more details.
|
||||||
|
RenderValuesHook func(kvList []interface{}) []interface{}
|
||||||
|
|
||||||
|
// RenderArgsHook is the same as RenderBuiltinsHook, except that it is only
|
||||||
|
// called for key-value pairs passed directly to Info and Error. See
|
||||||
|
// RenderBuiltinsHook for more details.
|
||||||
|
RenderArgsHook func(kvList []interface{}) []interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageClass indicates which category or categories of messages to consider.
|
||||||
|
type MessageClass int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// None ignores all message classes.
|
||||||
|
None MessageClass = iota
|
||||||
|
// All considers all message classes.
|
||||||
|
All
|
||||||
|
// Info only considers info messages.
|
||||||
|
Info
|
||||||
|
// Error only considers error messages.
|
||||||
|
Error
|
||||||
|
)
|
||||||
|
|
||||||
|
// fnlogger inherits some of its LogSink implementation from Formatter
|
||||||
|
// and just needs to add some glue code.
|
||||||
|
type fnlogger struct {
|
||||||
|
Formatter
|
||||||
|
write func(prefix, args string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l fnlogger) WithName(name string) logr.LogSink {
|
||||||
|
l.Formatter.AddName(name)
|
||||||
|
return &l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l fnlogger) WithValues(kvList ...interface{}) logr.LogSink {
|
||||||
|
l.Formatter.AddValues(kvList)
|
||||||
|
return &l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l fnlogger) WithCallDepth(depth int) logr.LogSink {
|
||||||
|
l.Formatter.AddCallDepth(depth)
|
||||||
|
return &l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l fnlogger) Info(level int, msg string, kvList ...interface{}) {
|
||||||
|
prefix, args := l.FormatInfo(level, msg, kvList)
|
||||||
|
l.write(prefix, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l fnlogger) Error(err error, msg string, kvList ...interface{}) {
|
||||||
|
prefix, args := l.FormatError(err, msg, kvList)
|
||||||
|
l.write(prefix, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l fnlogger) GetUnderlying() func(prefix, args string) {
|
||||||
|
return l.write
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assert conformance to the interfaces.
|
||||||
|
var _ logr.LogSink = &fnlogger{}
|
||||||
|
var _ logr.CallDepthLogSink = &fnlogger{}
|
||||||
|
var _ Underlier = &fnlogger{}
|
||||||
|
|
||||||
|
// NewFormatter constructs a Formatter which emits a JSON-like key=value format.
|
||||||
|
func NewFormatter(opts Options) Formatter {
|
||||||
|
return newFormatter(opts, outputKeyValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFormatterJSON constructs a Formatter which emits strict JSON.
|
||||||
|
func NewFormatterJSON(opts Options) Formatter {
|
||||||
|
return newFormatter(opts, outputJSON)
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultTimestampFmt = "2006-01-02 15:04:05.000000"
|
||||||
|
|
||||||
|
func newFormatter(opts Options, outfmt outputFormat) Formatter {
|
||||||
|
if opts.TimestampFormat == "" {
|
||||||
|
opts.TimestampFormat = defaultTimestampFmt
|
||||||
|
}
|
||||||
|
f := Formatter{
|
||||||
|
outputFormat: outfmt,
|
||||||
|
prefix: "",
|
||||||
|
values: nil,
|
||||||
|
depth: 0,
|
||||||
|
opts: opts,
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Formatter is an opaque struct which can be embedded in a LogSink
|
||||||
|
// implementation. It should be constructed with NewFormatter. Some of
|
||||||
|
// its methods directly implement logr.LogSink.
|
||||||
|
type Formatter struct {
|
||||||
|
outputFormat outputFormat
|
||||||
|
prefix string
|
||||||
|
values []interface{}
|
||||||
|
valuesStr string
|
||||||
|
depth int
|
||||||
|
opts Options
|
||||||
|
}
|
||||||
|
|
||||||
|
// outputFormat indicates which outputFormat to use.
|
||||||
|
type outputFormat int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// outputKeyValue emits a JSON-like key=value format, but not strict JSON.
|
||||||
|
outputKeyValue outputFormat = iota
|
||||||
|
// outputJSON emits strict JSON.
|
||||||
|
outputJSON
|
||||||
|
)
|
||||||
|
|
||||||
|
// PseudoStruct is a list of key-value pairs that gets logged as a struct.
|
||||||
|
type PseudoStruct []interface{}
|
||||||
|
|
||||||
|
// render produces a log line, ready to use.
|
||||||
|
func (f Formatter) render(builtins, args []interface{}) string {
|
||||||
|
// Empirically bytes.Buffer is faster than strings.Builder for this.
|
||||||
|
buf := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||||
|
if f.outputFormat == outputJSON {
|
||||||
|
buf.WriteByte('{')
|
||||||
|
}
|
||||||
|
vals := builtins
|
||||||
|
if hook := f.opts.RenderBuiltinsHook; hook != nil {
|
||||||
|
vals = hook(f.sanitize(vals))
|
||||||
|
}
|
||||||
|
f.flatten(buf, vals, false, false) // keys are ours, no need to escape
|
||||||
|
continuing := len(builtins) > 0
|
||||||
|
if len(f.valuesStr) > 0 {
|
||||||
|
if continuing {
|
||||||
|
if f.outputFormat == outputJSON {
|
||||||
|
buf.WriteByte(',')
|
||||||
|
} else {
|
||||||
|
buf.WriteByte(' ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continuing = true
|
||||||
|
buf.WriteString(f.valuesStr)
|
||||||
|
}
|
||||||
|
vals = args
|
||||||
|
if hook := f.opts.RenderArgsHook; hook != nil {
|
||||||
|
vals = hook(f.sanitize(vals))
|
||||||
|
}
|
||||||
|
f.flatten(buf, vals, continuing, true) // escape user-provided keys
|
||||||
|
if f.outputFormat == outputJSON {
|
||||||
|
buf.WriteByte('}')
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// flatten renders a list of key-value pairs into a buffer. If continuing is
|
||||||
|
// true, it assumes that the buffer has previous values and will emit a
|
||||||
|
// separator (which depends on the output format) before the first pair it
|
||||||
|
// writes. If escapeKeys is true, the keys are assumed to have
|
||||||
|
// non-JSON-compatible characters in them and must be evaluated for escapes.
|
||||||
|
//
|
||||||
|
// This function returns a potentially modified version of kvList, which
|
||||||
|
// ensures that there is a value for every key (adding a value if needed) and
|
||||||
|
// that each key is a string (substituting a key if needed).
|
||||||
|
func (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing bool, escapeKeys bool) []interface{} {
|
||||||
|
// This logic overlaps with sanitize() but saves one type-cast per key,
|
||||||
|
// which can be measurable.
|
||||||
|
if len(kvList)%2 != 0 {
|
||||||
|
kvList = append(kvList, noValue)
|
||||||
|
}
|
||||||
|
for i := 0; i < len(kvList); i += 2 {
|
||||||
|
k, ok := kvList[i].(string)
|
||||||
|
if !ok {
|
||||||
|
k = f.nonStringKey(kvList[i])
|
||||||
|
kvList[i] = k
|
||||||
|
}
|
||||||
|
v := kvList[i+1]
|
||||||
|
|
||||||
|
if i > 0 || continuing {
|
||||||
|
if f.outputFormat == outputJSON {
|
||||||
|
buf.WriteByte(',')
|
||||||
|
} else {
|
||||||
|
// In theory the format could be something we don't understand. In
|
||||||
|
// practice, we control it, so it won't be.
|
||||||
|
buf.WriteByte(' ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if escapeKeys {
|
||||||
|
buf.WriteString(prettyString(k))
|
||||||
|
} else {
|
||||||
|
// this is faster
|
||||||
|
buf.WriteByte('"')
|
||||||
|
buf.WriteString(k)
|
||||||
|
buf.WriteByte('"')
|
||||||
|
}
|
||||||
|
if f.outputFormat == outputJSON {
|
||||||
|
buf.WriteByte(':')
|
||||||
|
} else {
|
||||||
|
buf.WriteByte('=')
|
||||||
|
}
|
||||||
|
buf.WriteString(f.pretty(v))
|
||||||
|
}
|
||||||
|
return kvList
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f Formatter) pretty(value interface{}) string {
|
||||||
|
return f.prettyWithFlags(value, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
flagRawStruct = 0x1 // do not print braces on structs
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: This is not fast. Most of the overhead goes here.
|
||||||
|
func (f Formatter) prettyWithFlags(value interface{}, flags uint32) string {
|
||||||
|
// Handle types that take full control of logging.
|
||||||
|
if v, ok := value.(logr.Marshaler); ok {
|
||||||
|
// Replace the value with what the type wants to get logged.
|
||||||
|
// That then gets handled below via reflection.
|
||||||
|
value = v.MarshalLog()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle types that want to format themselves.
|
||||||
|
switch v := value.(type) {
|
||||||
|
case fmt.Stringer:
|
||||||
|
value = v.String()
|
||||||
|
case error:
|
||||||
|
value = v.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handling the most common types without reflect is a small perf win.
|
||||||
|
switch v := value.(type) {
|
||||||
|
case bool:
|
||||||
|
return strconv.FormatBool(v)
|
||||||
|
case string:
|
||||||
|
return prettyString(v)
|
||||||
|
case int:
|
||||||
|
return strconv.FormatInt(int64(v), 10)
|
||||||
|
case int8:
|
||||||
|
return strconv.FormatInt(int64(v), 10)
|
||||||
|
case int16:
|
||||||
|
return strconv.FormatInt(int64(v), 10)
|
||||||
|
case int32:
|
||||||
|
return strconv.FormatInt(int64(v), 10)
|
||||||
|
case int64:
|
||||||
|
return strconv.FormatInt(int64(v), 10)
|
||||||
|
case uint:
|
||||||
|
return strconv.FormatUint(uint64(v), 10)
|
||||||
|
case uint8:
|
||||||
|
return strconv.FormatUint(uint64(v), 10)
|
||||||
|
case uint16:
|
||||||
|
return strconv.FormatUint(uint64(v), 10)
|
||||||
|
case uint32:
|
||||||
|
return strconv.FormatUint(uint64(v), 10)
|
||||||
|
case uint64:
|
||||||
|
return strconv.FormatUint(v, 10)
|
||||||
|
case uintptr:
|
||||||
|
return strconv.FormatUint(uint64(v), 10)
|
||||||
|
case float32:
|
||||||
|
return strconv.FormatFloat(float64(v), 'f', -1, 32)
|
||||||
|
case float64:
|
||||||
|
return strconv.FormatFloat(v, 'f', -1, 64)
|
||||||
|
case complex64:
|
||||||
|
return `"` + strconv.FormatComplex(complex128(v), 'f', -1, 64) + `"`
|
||||||
|
case complex128:
|
||||||
|
return `"` + strconv.FormatComplex(v, 'f', -1, 128) + `"`
|
||||||
|
case PseudoStruct:
|
||||||
|
buf := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||||
|
v = f.sanitize(v)
|
||||||
|
if flags&flagRawStruct == 0 {
|
||||||
|
buf.WriteByte('{')
|
||||||
|
}
|
||||||
|
for i := 0; i < len(v); i += 2 {
|
||||||
|
if i > 0 {
|
||||||
|
buf.WriteByte(',')
|
||||||
|
}
|
||||||
|
// arbitrary keys might need escaping
|
||||||
|
buf.WriteString(prettyString(v[i].(string)))
|
||||||
|
buf.WriteByte(':')
|
||||||
|
buf.WriteString(f.pretty(v[i+1]))
|
||||||
|
}
|
||||||
|
if flags&flagRawStruct == 0 {
|
||||||
|
buf.WriteByte('}')
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := bytes.NewBuffer(make([]byte, 0, 256))
|
||||||
|
t := reflect.TypeOf(value)
|
||||||
|
if t == nil {
|
||||||
|
return "null"
|
||||||
|
}
|
||||||
|
v := reflect.ValueOf(value)
|
||||||
|
switch t.Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
return strconv.FormatBool(v.Bool())
|
||||||
|
case reflect.String:
|
||||||
|
return prettyString(v.String())
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return strconv.FormatInt(int64(v.Int()), 10)
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return strconv.FormatUint(uint64(v.Uint()), 10)
|
||||||
|
case reflect.Float32:
|
||||||
|
return strconv.FormatFloat(float64(v.Float()), 'f', -1, 32)
|
||||||
|
case reflect.Float64:
|
||||||
|
return strconv.FormatFloat(v.Float(), 'f', -1, 64)
|
||||||
|
case reflect.Complex64:
|
||||||
|
return `"` + strconv.FormatComplex(complex128(v.Complex()), 'f', -1, 64) + `"`
|
||||||
|
case reflect.Complex128:
|
||||||
|
return `"` + strconv.FormatComplex(v.Complex(), 'f', -1, 128) + `"`
|
||||||
|
case reflect.Struct:
|
||||||
|
if flags&flagRawStruct == 0 {
|
||||||
|
buf.WriteByte('{')
|
||||||
|
}
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
fld := t.Field(i)
|
||||||
|
if fld.PkgPath != "" {
|
||||||
|
// reflect says this field is only defined for non-exported fields.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !v.Field(i).CanInterface() {
|
||||||
|
// reflect isn't clear exactly what this means, but we can't use it.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name := ""
|
||||||
|
omitempty := false
|
||||||
|
if tag, found := fld.Tag.Lookup("json"); found {
|
||||||
|
if tag == "-" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if comma := strings.Index(tag, ","); comma != -1 {
|
||||||
|
if n := tag[:comma]; n != "" {
|
||||||
|
name = n
|
||||||
|
}
|
||||||
|
rest := tag[comma:]
|
||||||
|
if strings.Contains(rest, ",omitempty,") || strings.HasSuffix(rest, ",omitempty") {
|
||||||
|
omitempty = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
name = tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if omitempty && isEmpty(v.Field(i)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if i > 0 {
|
||||||
|
buf.WriteByte(',')
|
||||||
|
}
|
||||||
|
if fld.Anonymous && fld.Type.Kind() == reflect.Struct && name == "" {
|
||||||
|
buf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), flags|flagRawStruct))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if name == "" {
|
||||||
|
name = fld.Name
|
||||||
|
}
|
||||||
|
// field names can't contain characters which need escaping
|
||||||
|
buf.WriteByte('"')
|
||||||
|
buf.WriteString(name)
|
||||||
|
buf.WriteByte('"')
|
||||||
|
buf.WriteByte(':')
|
||||||
|
buf.WriteString(f.pretty(v.Field(i).Interface()))
|
||||||
|
}
|
||||||
|
if flags&flagRawStruct == 0 {
|
||||||
|
buf.WriteByte('}')
|
||||||
|
}
|
||||||
|
return buf.String()
|
||||||
|
case reflect.Slice, reflect.Array:
|
||||||
|
buf.WriteByte('[')
|
||||||
|
for i := 0; i < v.Len(); i++ {
|
||||||
|
if i > 0 {
|
||||||
|
buf.WriteByte(',')
|
||||||
|
}
|
||||||
|
e := v.Index(i)
|
||||||
|
buf.WriteString(f.pretty(e.Interface()))
|
||||||
|
}
|
||||||
|
buf.WriteByte(']')
|
||||||
|
return buf.String()
|
||||||
|
case reflect.Map:
|
||||||
|
buf.WriteByte('{')
|
||||||
|
// This does not sort the map keys, for best perf.
|
||||||
|
it := v.MapRange()
|
||||||
|
i := 0
|
||||||
|
for it.Next() {
|
||||||
|
if i > 0 {
|
||||||
|
buf.WriteByte(',')
|
||||||
|
}
|
||||||
|
// If a map key supports TextMarshaler, use it.
|
||||||
|
keystr := ""
|
||||||
|
if m, ok := it.Key().Interface().(encoding.TextMarshaler); ok {
|
||||||
|
txt, err := m.MarshalText()
|
||||||
|
if err != nil {
|
||||||
|
keystr = fmt.Sprintf("<error-MarshalText: %s>", err.Error())
|
||||||
|
} else {
|
||||||
|
keystr = string(txt)
|
||||||
|
}
|
||||||
|
keystr = prettyString(keystr)
|
||||||
|
} else {
|
||||||
|
// prettyWithFlags will produce already-escaped values
|
||||||
|
keystr = f.prettyWithFlags(it.Key().Interface(), 0)
|
||||||
|
if t.Key().Kind() != reflect.String {
|
||||||
|
// JSON only does string keys. Unlike Go's standard JSON, we'll
|
||||||
|
// convert just about anything to a string.
|
||||||
|
keystr = prettyString(keystr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.WriteString(keystr)
|
||||||
|
buf.WriteByte(':')
|
||||||
|
buf.WriteString(f.pretty(it.Value().Interface()))
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
buf.WriteByte('}')
|
||||||
|
return buf.String()
|
||||||
|
case reflect.Ptr, reflect.Interface:
|
||||||
|
if v.IsNil() {
|
||||||
|
return "null"
|
||||||
|
}
|
||||||
|
return f.pretty(v.Elem().Interface())
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(`"<unhandled-%s>"`, t.Kind().String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func prettyString(s string) string {
|
||||||
|
// Avoid escaping (which does allocations) if we can.
|
||||||
|
if needsEscape(s) {
|
||||||
|
return strconv.Quote(s)
|
||||||
|
}
|
||||||
|
b := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||||
|
b.WriteByte('"')
|
||||||
|
b.WriteString(s)
|
||||||
|
b.WriteByte('"')
|
||||||
|
return b.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// needsEscape determines whether the input string needs to be escaped or not,
|
||||||
|
// without doing any allocations.
|
||||||
|
func needsEscape(s string) bool {
|
||||||
|
for _, r := range s {
|
||||||
|
if !strconv.IsPrint(r) || r == '\\' || r == '"' {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func isEmpty(v reflect.Value) bool {
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
||||||
|
return v.Len() == 0
|
||||||
|
case reflect.Bool:
|
||||||
|
return !v.Bool()
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return v.Int() == 0
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return v.Uint() == 0
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return v.Float() == 0
|
||||||
|
case reflect.Complex64, reflect.Complex128:
|
||||||
|
return v.Complex() == 0
|
||||||
|
case reflect.Interface, reflect.Ptr:
|
||||||
|
return v.IsNil()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Caller represents the original call site for a log line, after considering
|
||||||
|
// logr.Logger.WithCallDepth and logr.Logger.WithCallStackHelper. The File and
|
||||||
|
// Line fields will always be provided, while the Func field is optional.
|
||||||
|
// Users can set the render hook fields in Options to examine logged key-value
|
||||||
|
// pairs, one of which will be {"caller", Caller} if the Options.LogCaller
|
||||||
|
// field is enabled for the given MessageClass.
|
||||||
|
type Caller struct {
|
||||||
|
// File is the basename of the file for this call site.
|
||||||
|
File string `json:"file"`
|
||||||
|
// Line is the line number in the file for this call site.
|
||||||
|
Line int `json:"line"`
|
||||||
|
// Func is the function name for this call site, or empty if
|
||||||
|
// Options.LogCallerFunc is not enabled.
|
||||||
|
Func string `json:"function,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f Formatter) caller() Caller {
|
||||||
|
// +1 for this frame, +1 for Info/Error.
|
||||||
|
pc, file, line, ok := runtime.Caller(f.depth + 2)
|
||||||
|
if !ok {
|
||||||
|
return Caller{"<unknown>", 0, ""}
|
||||||
|
}
|
||||||
|
fn := ""
|
||||||
|
if f.opts.LogCallerFunc {
|
||||||
|
if fp := runtime.FuncForPC(pc); fp != nil {
|
||||||
|
fn = fp.Name()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Caller{filepath.Base(file), line, fn}
|
||||||
|
}
|
||||||
|
|
||||||
|
const noValue = "<no-value>"
|
||||||
|
|
||||||
|
func (f Formatter) nonStringKey(v interface{}) string {
|
||||||
|
return fmt.Sprintf("<non-string-key: %s>", f.snippet(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// snippet produces a short snippet string of an arbitrary value.
|
||||||
|
func (f Formatter) snippet(v interface{}) string {
|
||||||
|
const snipLen = 16
|
||||||
|
|
||||||
|
snip := f.pretty(v)
|
||||||
|
if len(snip) > snipLen {
|
||||||
|
snip = snip[:snipLen]
|
||||||
|
}
|
||||||
|
return snip
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanitize ensures that a list of key-value pairs has a value for every key
|
||||||
|
// (adding a value if needed) and that each key is a string (substituting a key
|
||||||
|
// if needed).
|
||||||
|
func (f Formatter) sanitize(kvList []interface{}) []interface{} {
|
||||||
|
if len(kvList)%2 != 0 {
|
||||||
|
kvList = append(kvList, noValue)
|
||||||
|
}
|
||||||
|
for i := 0; i < len(kvList); i += 2 {
|
||||||
|
_, ok := kvList[i].(string)
|
||||||
|
if !ok {
|
||||||
|
kvList[i] = f.nonStringKey(kvList[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return kvList
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init configures this Formatter from runtime info, such as the call depth
|
||||||
|
// imposed by logr itself.
|
||||||
|
// Note that this receiver is a pointer, so depth can be saved.
|
||||||
|
func (f *Formatter) Init(info logr.RuntimeInfo) {
|
||||||
|
f.depth += info.CallDepth
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enabled checks whether an info message at the given level should be logged.
|
||||||
|
func (f Formatter) Enabled(level int) bool {
|
||||||
|
return level <= f.opts.Verbosity
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDepth returns the current depth of this Formatter. This is useful for
|
||||||
|
// implementations which do their own caller attribution.
|
||||||
|
func (f Formatter) GetDepth() int {
|
||||||
|
return f.depth
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatInfo renders an Info log message into strings. The prefix will be
|
||||||
|
// empty when no names were set (via AddNames), or when the output is
|
||||||
|
// configured for JSON.
|
||||||
|
func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (prefix, argsStr string) {
|
||||||
|
args := make([]interface{}, 0, 64) // using a constant here impacts perf
|
||||||
|
prefix = f.prefix
|
||||||
|
if f.outputFormat == outputJSON {
|
||||||
|
args = append(args, "logger", prefix)
|
||||||
|
prefix = ""
|
||||||
|
}
|
||||||
|
if f.opts.LogTimestamp {
|
||||||
|
args = append(args, "ts", time.Now().Format(f.opts.TimestampFormat))
|
||||||
|
}
|
||||||
|
if policy := f.opts.LogCaller; policy == All || policy == Info {
|
||||||
|
args = append(args, "caller", f.caller())
|
||||||
|
}
|
||||||
|
args = append(args, "level", level, "msg", msg)
|
||||||
|
return prefix, f.render(args, kvList)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatError renders an Error log message into strings. The prefix will be
|
||||||
|
// empty when no names were set (via AddNames), or when the output is
|
||||||
|
// configured for JSON.
|
||||||
|
func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (prefix, argsStr string) {
|
||||||
|
args := make([]interface{}, 0, 64) // using a constant here impacts perf
|
||||||
|
prefix = f.prefix
|
||||||
|
if f.outputFormat == outputJSON {
|
||||||
|
args = append(args, "logger", prefix)
|
||||||
|
prefix = ""
|
||||||
|
}
|
||||||
|
if f.opts.LogTimestamp {
|
||||||
|
args = append(args, "ts", time.Now().Format(f.opts.TimestampFormat))
|
||||||
|
}
|
||||||
|
if policy := f.opts.LogCaller; policy == All || policy == Error {
|
||||||
|
args = append(args, "caller", f.caller())
|
||||||
|
}
|
||||||
|
args = append(args, "msg", msg)
|
||||||
|
var loggableErr interface{}
|
||||||
|
if err != nil {
|
||||||
|
loggableErr = err.Error()
|
||||||
|
}
|
||||||
|
args = append(args, "error", loggableErr)
|
||||||
|
return f.prefix, f.render(args, kvList)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddName appends the specified name. funcr uses '/' characters to separate
|
||||||
|
// name elements. Callers should not pass '/' in the provided name string, but
|
||||||
|
// this library does not actually enforce that.
|
||||||
|
func (f *Formatter) AddName(name string) {
|
||||||
|
if len(f.prefix) > 0 {
|
||||||
|
f.prefix += "/"
|
||||||
|
}
|
||||||
|
f.prefix += name
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddValues adds key-value pairs to the set of saved values to be logged with
|
||||||
|
// each log line.
|
||||||
|
func (f *Formatter) AddValues(kvList []interface{}) {
|
||||||
|
// Three slice args forces a copy.
|
||||||
|
n := len(f.values)
|
||||||
|
f.values = append(f.values[:n:n], kvList...)
|
||||||
|
|
||||||
|
vals := f.values
|
||||||
|
if hook := f.opts.RenderValuesHook; hook != nil {
|
||||||
|
vals = hook(f.sanitize(vals))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pre-render values, so we don't have to do it on each Info/Error call.
|
||||||
|
buf := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||||
|
f.flatten(buf, vals, false, true) // escape user-provided keys
|
||||||
|
f.valuesStr = buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddCallDepth increases the number of stack-frames to skip when attributing
|
||||||
|
// the log line to a file and line.
|
||||||
|
func (f *Formatter) AddCallDepth(depth int) {
|
||||||
|
f.depth += depth
|
||||||
|
}
|
501
vendor/github.com/go-logr/logr/logr.go
generated
vendored
Normal file
501
vendor/github.com/go-logr/logr/logr.go
generated
vendored
Normal file
@ -0,0 +1,501 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 The logr Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This design derives from Dave Cheney's blog:
|
||||||
|
// http://dave.cheney.net/2015/11/05/lets-talk-about-logging
|
||||||
|
|
||||||
|
// Package logr defines a general-purpose logging API and abstract interfaces
|
||||||
|
// to back that API. Packages in the Go ecosystem can depend on this package,
|
||||||
|
// while callers can implement logging with whatever backend is appropriate.
|
||||||
|
//
|
||||||
|
// Usage
|
||||||
|
//
|
||||||
|
// Logging is done using a Logger instance. Logger is a concrete type with
|
||||||
|
// methods, which defers the actual logging to a LogSink interface. The main
|
||||||
|
// methods of Logger are Info() and Error(). Arguments to Info() and Error()
|
||||||
|
// are key/value pairs rather than printf-style formatted strings, emphasizing
|
||||||
|
// "structured logging".
|
||||||
|
//
|
||||||
|
// With Go's standard log package, we might write:
|
||||||
|
// log.Printf("setting target value %s", targetValue)
|
||||||
|
//
|
||||||
|
// With logr's structured logging, we'd write:
|
||||||
|
// logger.Info("setting target", "value", targetValue)
|
||||||
|
//
|
||||||
|
// Errors are much the same. Instead of:
|
||||||
|
// log.Printf("failed to open the pod bay door for user %s: %v", user, err)
|
||||||
|
//
|
||||||
|
// We'd write:
|
||||||
|
// logger.Error(err, "failed to open the pod bay door", "user", user)
|
||||||
|
//
|
||||||
|
// Info() and Error() are very similar, but they are separate methods so that
|
||||||
|
// LogSink implementations can choose to do things like attach additional
|
||||||
|
// information (such as stack traces) on calls to Error(). Error() messages are
|
||||||
|
// always logged, regardless of the current verbosity. If there is no error
|
||||||
|
// instance available, passing nil is valid.
|
||||||
|
//
|
||||||
|
// Verbosity
|
||||||
|
//
|
||||||
|
// Often we want to log information only when the application in "verbose
|
||||||
|
// mode". To write log lines that are more verbose, Logger has a V() method.
|
||||||
|
// The higher the V-level of a log line, the less critical it is considered.
|
||||||
|
// Log-lines with V-levels that are not enabled (as per the LogSink) will not
|
||||||
|
// be written. Level V(0) is the default, and logger.V(0).Info() has the same
|
||||||
|
// meaning as logger.Info(). Negative V-levels have the same meaning as V(0).
|
||||||
|
// Error messages do not have a verbosity level and are always logged.
|
||||||
|
//
|
||||||
|
// Where we might have written:
|
||||||
|
// if flVerbose >= 2 {
|
||||||
|
// log.Printf("an unusual thing happened")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// We can write:
|
||||||
|
// logger.V(2).Info("an unusual thing happened")
|
||||||
|
//
|
||||||
|
// Logger Names
|
||||||
|
//
|
||||||
|
// Logger instances can have name strings so that all messages logged through
|
||||||
|
// that instance have additional context. For example, you might want to add
|
||||||
|
// a subsystem name:
|
||||||
|
//
|
||||||
|
// logger.WithName("compactor").Info("started", "time", time.Now())
|
||||||
|
//
|
||||||
|
// The WithName() method returns a new Logger, which can be passed to
|
||||||
|
// constructors or other functions for further use. Repeated use of WithName()
|
||||||
|
// will accumulate name "segments". These name segments will be joined in some
|
||||||
|
// way by the LogSink implementation. It is strongly recommended that name
|
||||||
|
// segments contain simple identifiers (letters, digits, and hyphen), and do
|
||||||
|
// not contain characters that could muddle the log output or confuse the
|
||||||
|
// joining operation (e.g. whitespace, commas, periods, slashes, brackets,
|
||||||
|
// quotes, etc).
|
||||||
|
//
|
||||||
|
// Saved Values
|
||||||
|
//
|
||||||
|
// Logger instances can store any number of key/value pairs, which will be
|
||||||
|
// logged alongside all messages logged through that instance. For example,
|
||||||
|
// you might want to create a Logger instance per managed object:
|
||||||
|
//
|
||||||
|
// With the standard log package, we might write:
|
||||||
|
// log.Printf("decided to set field foo to value %q for object %s/%s",
|
||||||
|
// targetValue, object.Namespace, object.Name)
|
||||||
|
//
|
||||||
|
// With logr we'd write:
|
||||||
|
// // Elsewhere: set up the logger to log the object name.
|
||||||
|
// obj.logger = mainLogger.WithValues(
|
||||||
|
// "name", obj.name, "namespace", obj.namespace)
|
||||||
|
//
|
||||||
|
// // later on...
|
||||||
|
// obj.logger.Info("setting foo", "value", targetValue)
|
||||||
|
//
|
||||||
|
// Best Practices
|
||||||
|
//
|
||||||
|
// Logger has very few hard rules, with the goal that LogSink implementations
|
||||||
|
// might have a lot of freedom to differentiate. There are, however, some
|
||||||
|
// things to consider.
|
||||||
|
//
|
||||||
|
// The log message consists of a constant message attached to the log line.
|
||||||
|
// This should generally be a simple description of what's occurring, and should
|
||||||
|
// never be a format string. Variable information can then be attached using
|
||||||
|
// named values.
|
||||||
|
//
|
||||||
|
// Keys are arbitrary strings, but should generally be constant values. Values
|
||||||
|
// may be any Go value, but how the value is formatted is determined by the
|
||||||
|
// LogSink implementation.
|
||||||
|
//
|
||||||
|
// Key Naming Conventions
|
||||||
|
//
|
||||||
|
// Keys are not strictly required to conform to any specification or regex, but
|
||||||
|
// it is recommended that they:
|
||||||
|
// * be human-readable and meaningful (not auto-generated or simple ordinals)
|
||||||
|
// * be constant (not dependent on input data)
|
||||||
|
// * contain only printable characters
|
||||||
|
// * not contain whitespace or punctuation
|
||||||
|
// * use lower case for simple keys and lowerCamelCase for more complex ones
|
||||||
|
//
|
||||||
|
// These guidelines help ensure that log data is processed properly regardless
|
||||||
|
// of the log implementation. For example, log implementations will try to
|
||||||
|
// output JSON data or will store data for later database (e.g. SQL) queries.
|
||||||
|
//
|
||||||
|
// While users are generally free to use key names of their choice, it's
|
||||||
|
// generally best to avoid using the following keys, as they're frequently used
|
||||||
|
// by implementations:
|
||||||
|
// * "caller": the calling information (file/line) of a particular log line
|
||||||
|
// * "error": the underlying error value in the `Error` method
|
||||||
|
// * "level": the log level
|
||||||
|
// * "logger": the name of the associated logger
|
||||||
|
// * "msg": the log message
|
||||||
|
// * "stacktrace": the stack trace associated with a particular log line or
|
||||||
|
// error (often from the `Error` message)
|
||||||
|
// * "ts": the timestamp for a log line
|
||||||
|
//
|
||||||
|
// Implementations are encouraged to make use of these keys to represent the
|
||||||
|
// above concepts, when necessary (for example, in a pure-JSON output form, it
|
||||||
|
// would be necessary to represent at least message and timestamp as ordinary
|
||||||
|
// named values).
|
||||||
|
//
|
||||||
|
// Break Glass
|
||||||
|
//
|
||||||
|
// Implementations may choose to give callers access to the underlying
|
||||||
|
// logging implementation. The recommended pattern for this is:
|
||||||
|
// // Underlier exposes access to the underlying logging implementation.
|
||||||
|
// // Since callers only have a logr.Logger, they have to know which
|
||||||
|
// // implementation is in use, so this interface is less of an abstraction
|
||||||
|
// // and more of way to test type conversion.
|
||||||
|
// type Underlier interface {
|
||||||
|
// GetUnderlying() <underlying-type>
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Logger grants access to the sink to enable type assertions like this:
|
||||||
|
// func DoSomethingWithImpl(log logr.Logger) {
|
||||||
|
// if underlier, ok := log.GetSink()(impl.Underlier) {
|
||||||
|
// implLogger := underlier.GetUnderlying()
|
||||||
|
// ...
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Custom `With*` functions can be implemented by copying the complete
|
||||||
|
// Logger struct and replacing the sink in the copy:
|
||||||
|
// // WithFooBar changes the foobar parameter in the log sink and returns a
|
||||||
|
// // new logger with that modified sink. It does nothing for loggers where
|
||||||
|
// // the sink doesn't support that parameter.
|
||||||
|
// func WithFoobar(log logr.Logger, foobar int) logr.Logger {
|
||||||
|
// if foobarLogSink, ok := log.GetSink()(FoobarSink); ok {
|
||||||
|
// log = log.WithSink(foobarLogSink.WithFooBar(foobar))
|
||||||
|
// }
|
||||||
|
// return log
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Don't use New to construct a new Logger with a LogSink retrieved from an
|
||||||
|
// existing Logger. Source code attribution might not work correctly and
|
||||||
|
// unexported fields in Logger get lost.
|
||||||
|
//
|
||||||
|
// Beware that the same LogSink instance may be shared by different logger
|
||||||
|
// instances. Calling functions that modify the LogSink will affect all of
|
||||||
|
// those.
|
||||||
|
package logr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// New returns a new Logger instance. This is primarily used by libraries
|
||||||
|
// implementing LogSink, rather than end users.
|
||||||
|
func New(sink LogSink) Logger {
|
||||||
|
logger := Logger{}
|
||||||
|
logger.setSink(sink)
|
||||||
|
sink.Init(runtimeInfo)
|
||||||
|
return logger
|
||||||
|
}
|
||||||
|
|
||||||
|
// setSink stores the sink and updates any related fields. It mutates the
|
||||||
|
// logger and thus is only safe to use for loggers that are not currently being
|
||||||
|
// used concurrently.
|
||||||
|
func (l *Logger) setSink(sink LogSink) {
|
||||||
|
l.sink = sink
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSink returns the stored sink.
|
||||||
|
func (l Logger) GetSink() LogSink {
|
||||||
|
return l.sink
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSink returns a copy of the logger with the new sink.
|
||||||
|
func (l Logger) WithSink(sink LogSink) Logger {
|
||||||
|
l.setSink(sink)
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logger is an interface to an abstract logging implementation. This is a
|
||||||
|
// concrete type for performance reasons, but all the real work is passed on to
|
||||||
|
// a LogSink. Implementations of LogSink should provide their own constructors
|
||||||
|
// that return Logger, not LogSink.
|
||||||
|
//
|
||||||
|
// The underlying sink can be accessed through GetSink and be modified through
|
||||||
|
// WithSink. This enables the implementation of custom extensions (see "Break
|
||||||
|
// Glass" in the package documentation). Normally the sink should be used only
|
||||||
|
// indirectly.
|
||||||
|
type Logger struct {
|
||||||
|
sink LogSink
|
||||||
|
level int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enabled tests whether this Logger is enabled. For example, commandline
|
||||||
|
// flags might be used to set the logging verbosity and disable some info logs.
|
||||||
|
func (l Logger) Enabled() bool {
|
||||||
|
return l.sink.Enabled(l.level)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info logs a non-error message with the given key/value pairs as context.
|
||||||
|
//
|
||||||
|
// The msg argument should be used to add some constant description to the log
|
||||||
|
// line. The key/value pairs can then be used to add additional variable
|
||||||
|
// information. The key/value pairs must alternate string keys and arbitrary
|
||||||
|
// values.
|
||||||
|
func (l Logger) Info(msg string, keysAndValues ...interface{}) {
|
||||||
|
if l.Enabled() {
|
||||||
|
if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
|
||||||
|
withHelper.GetCallStackHelper()()
|
||||||
|
}
|
||||||
|
l.sink.Info(l.level, msg, keysAndValues...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error logs an error, with the given message and key/value pairs as context.
|
||||||
|
// It functions similarly to Info, but may have unique behavior, and should be
|
||||||
|
// preferred for logging errors (see the package documentations for more
|
||||||
|
// information). The log message will always be emitted, regardless of
|
||||||
|
// verbosity level.
|
||||||
|
//
|
||||||
|
// The msg argument should be used to add context to any underlying error,
|
||||||
|
// while the err argument should be used to attach the actual error that
|
||||||
|
// triggered this log line, if present. The err parameter is optional
|
||||||
|
// and nil may be passed instead of an error instance.
|
||||||
|
func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) {
|
||||||
|
if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
|
||||||
|
withHelper.GetCallStackHelper()()
|
||||||
|
}
|
||||||
|
l.sink.Error(err, msg, keysAndValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// V returns a new Logger instance for a specific verbosity level, relative to
|
||||||
|
// this Logger. In other words, V-levels are additive. A higher verbosity
|
||||||
|
// level means a log message is less important. Negative V-levels are treated
|
||||||
|
// as 0.
|
||||||
|
func (l Logger) V(level int) Logger {
|
||||||
|
if level < 0 {
|
||||||
|
level = 0
|
||||||
|
}
|
||||||
|
l.level += level
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithValues returns a new Logger instance with additional key/value pairs.
|
||||||
|
// See Info for documentation on how key/value pairs work.
|
||||||
|
func (l Logger) WithValues(keysAndValues ...interface{}) Logger {
|
||||||
|
l.setSink(l.sink.WithValues(keysAndValues...))
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithName returns a new Logger instance with the specified name element added
|
||||||
|
// to the Logger's name. Successive calls with WithName append additional
|
||||||
|
// suffixes to the Logger's name. It's strongly recommended that name segments
|
||||||
|
// contain only letters, digits, and hyphens (see the package documentation for
|
||||||
|
// more information).
|
||||||
|
func (l Logger) WithName(name string) Logger {
|
||||||
|
l.setSink(l.sink.WithName(name))
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithCallDepth returns a Logger instance that offsets the call stack by the
|
||||||
|
// specified number of frames when logging call site information, if possible.
|
||||||
|
// This is useful for users who have helper functions between the "real" call
|
||||||
|
// site and the actual calls to Logger methods. If depth is 0 the attribution
|
||||||
|
// should be to the direct caller of this function. If depth is 1 the
|
||||||
|
// attribution should skip 1 call frame, and so on. Successive calls to this
|
||||||
|
// are additive.
|
||||||
|
//
|
||||||
|
// If the underlying log implementation supports a WithCallDepth(int) method,
|
||||||
|
// it will be called and the result returned. If the implementation does not
|
||||||
|
// support CallDepthLogSink, the original Logger will be returned.
|
||||||
|
//
|
||||||
|
// To skip one level, WithCallStackHelper() should be used instead of
|
||||||
|
// WithCallDepth(1) because it works with implementions that support the
|
||||||
|
// CallDepthLogSink and/or CallStackHelperLogSink interfaces.
|
||||||
|
func (l Logger) WithCallDepth(depth int) Logger {
|
||||||
|
if withCallDepth, ok := l.sink.(CallDepthLogSink); ok {
|
||||||
|
l.setSink(withCallDepth.WithCallDepth(depth))
|
||||||
|
}
|
||||||
|
return l
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithCallStackHelper returns a new Logger instance that skips the direct
|
||||||
|
// caller when logging call site information, if possible. This is useful for
|
||||||
|
// users who have helper functions between the "real" call site and the actual
|
||||||
|
// calls to Logger methods and want to support loggers which depend on marking
|
||||||
|
// each individual helper function, like loggers based on testing.T.
|
||||||
|
//
|
||||||
|
// In addition to using that new logger instance, callers also must call the
|
||||||
|
// returned function.
|
||||||
|
//
|
||||||
|
// If the underlying log implementation supports a WithCallDepth(int) method,
|
||||||
|
// WithCallDepth(1) will be called to produce a new logger. If it supports a
|
||||||
|
// WithCallStackHelper() method, that will be also called. If the
|
||||||
|
// implementation does not support either of these, the original Logger will be
|
||||||
|
// returned.
|
||||||
|
func (l Logger) WithCallStackHelper() (func(), Logger) {
|
||||||
|
var helper func()
|
||||||
|
if withCallDepth, ok := l.sink.(CallDepthLogSink); ok {
|
||||||
|
l.setSink(withCallDepth.WithCallDepth(1))
|
||||||
|
}
|
||||||
|
if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
|
||||||
|
helper = withHelper.GetCallStackHelper()
|
||||||
|
} else {
|
||||||
|
helper = func() {}
|
||||||
|
}
|
||||||
|
return helper, l
|
||||||
|
}
|
||||||
|
|
||||||
|
// contextKey is how we find Loggers in a context.Context.
|
||||||
|
type contextKey struct{}
|
||||||
|
|
||||||
|
// FromContext returns a Logger from ctx or an error if no Logger is found.
|
||||||
|
func FromContext(ctx context.Context) (Logger, error) {
|
||||||
|
if v, ok := ctx.Value(contextKey{}).(Logger); ok {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return Logger{}, notFoundError{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// notFoundError exists to carry an IsNotFound method.
|
||||||
|
type notFoundError struct{}
|
||||||
|
|
||||||
|
func (notFoundError) Error() string {
|
||||||
|
return "no logr.Logger was present"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (notFoundError) IsNotFound() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromContextOrDiscard returns a Logger from ctx. If no Logger is found, this
|
||||||
|
// returns a Logger that discards all log messages.
|
||||||
|
func FromContextOrDiscard(ctx context.Context) Logger {
|
||||||
|
if v, ok := ctx.Value(contextKey{}).(Logger); ok {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
return Discard()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewContext returns a new Context, derived from ctx, which carries the
|
||||||
|
// provided Logger.
|
||||||
|
func NewContext(ctx context.Context, logger Logger) context.Context {
|
||||||
|
return context.WithValue(ctx, contextKey{}, logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RuntimeInfo holds information that the logr "core" library knows which
|
||||||
|
// LogSinks might want to know.
|
||||||
|
type RuntimeInfo struct {
|
||||||
|
// CallDepth is the number of call frames the logr library adds between the
|
||||||
|
// end-user and the LogSink. LogSink implementations which choose to print
|
||||||
|
// the original logging site (e.g. file & line) should climb this many
|
||||||
|
// additional frames to find it.
|
||||||
|
CallDepth int
|
||||||
|
}
|
||||||
|
|
||||||
|
// runtimeInfo is a static global. It must not be changed at run time.
|
||||||
|
var runtimeInfo = RuntimeInfo{
|
||||||
|
CallDepth: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogSink represents a logging implementation. End-users will generally not
|
||||||
|
// interact with this type.
|
||||||
|
type LogSink interface {
|
||||||
|
// Init receives optional information about the logr library for LogSink
|
||||||
|
// implementations that need it.
|
||||||
|
Init(info RuntimeInfo)
|
||||||
|
|
||||||
|
// Enabled tests whether this LogSink is enabled at the specified V-level.
|
||||||
|
// For example, commandline flags might be used to set the logging
|
||||||
|
// verbosity and disable some info logs.
|
||||||
|
Enabled(level int) bool
|
||||||
|
|
||||||
|
// Info logs a non-error message with the given key/value pairs as context.
|
||||||
|
// The level argument is provided for optional logging. This method will
|
||||||
|
// only be called when Enabled(level) is true. See Logger.Info for more
|
||||||
|
// details.
|
||||||
|
Info(level int, msg string, keysAndValues ...interface{})
|
||||||
|
|
||||||
|
// Error logs an error, with the given message and key/value pairs as
|
||||||
|
// context. See Logger.Error for more details.
|
||||||
|
Error(err error, msg string, keysAndValues ...interface{})
|
||||||
|
|
||||||
|
// WithValues returns a new LogSink with additional key/value pairs. See
|
||||||
|
// Logger.WithValues for more details.
|
||||||
|
WithValues(keysAndValues ...interface{}) LogSink
|
||||||
|
|
||||||
|
// WithName returns a new LogSink with the specified name appended. See
|
||||||
|
// Logger.WithName for more details.
|
||||||
|
WithName(name string) LogSink
|
||||||
|
}
|
||||||
|
|
||||||
|
// CallDepthLogSink represents a Logger that knows how to climb the call stack
|
||||||
|
// to identify the original call site and can offset the depth by a specified
|
||||||
|
// number of frames. This is useful for users who have helper functions
|
||||||
|
// between the "real" call site and the actual calls to Logger methods.
|
||||||
|
// Implementations that log information about the call site (such as file,
|
||||||
|
// function, or line) would otherwise log information about the intermediate
|
||||||
|
// helper functions.
|
||||||
|
//
|
||||||
|
// This is an optional interface and implementations are not required to
|
||||||
|
// support it.
|
||||||
|
type CallDepthLogSink interface {
|
||||||
|
// WithCallDepth returns a LogSink that will offset the call
|
||||||
|
// stack by the specified number of frames when logging call
|
||||||
|
// site information.
|
||||||
|
//
|
||||||
|
// If depth is 0, the LogSink should skip exactly the number
|
||||||
|
// of call frames defined in RuntimeInfo.CallDepth when Info
|
||||||
|
// or Error are called, i.e. the attribution should be to the
|
||||||
|
// direct caller of Logger.Info or Logger.Error.
|
||||||
|
//
|
||||||
|
// If depth is 1 the attribution should skip 1 call frame, and so on.
|
||||||
|
// Successive calls to this are additive.
|
||||||
|
WithCallDepth(depth int) LogSink
|
||||||
|
}
|
||||||
|
|
||||||
|
// CallStackHelperLogSink represents a Logger that knows how to climb
|
||||||
|
// the call stack to identify the original call site and can skip
|
||||||
|
// intermediate helper functions if they mark themselves as
|
||||||
|
// helper. Go's testing package uses that approach.
|
||||||
|
//
|
||||||
|
// This is useful for users who have helper functions between the
|
||||||
|
// "real" call site and the actual calls to Logger methods.
|
||||||
|
// Implementations that log information about the call site (such as
|
||||||
|
// file, function, or line) would otherwise log information about the
|
||||||
|
// intermediate helper functions.
|
||||||
|
//
|
||||||
|
// This is an optional interface and implementations are not required
|
||||||
|
// to support it. Implementations that choose to support this must not
|
||||||
|
// simply implement it as WithCallDepth(1), because
|
||||||
|
// Logger.WithCallStackHelper will call both methods if they are
|
||||||
|
// present. This should only be implemented for LogSinks that actually
|
||||||
|
// need it, as with testing.T.
|
||||||
|
type CallStackHelperLogSink interface {
|
||||||
|
// GetCallStackHelper returns a function that must be called
|
||||||
|
// to mark the direct caller as helper function when logging
|
||||||
|
// call site information.
|
||||||
|
GetCallStackHelper() func()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshaler is an optional interface that logged values may choose to
|
||||||
|
// implement. Loggers with structured output, such as JSON, should
|
||||||
|
// log the object return by the MarshalLog method instead of the
|
||||||
|
// original value.
|
||||||
|
type Marshaler interface {
|
||||||
|
// MarshalLog can be used to:
|
||||||
|
// - ensure that structs are not logged as strings when the original
|
||||||
|
// value has a String method: return a different type without a
|
||||||
|
// String method
|
||||||
|
// - select which fields of a complex type should get logged:
|
||||||
|
// return a simpler struct with fewer fields
|
||||||
|
// - log unexported fields: return a different struct
|
||||||
|
// with exported fields
|
||||||
|
//
|
||||||
|
// It may return any value of any type.
|
||||||
|
MarshalLog() interface{}
|
||||||
|
}
|
201
vendor/github.com/go-logr/stdr/LICENSE
generated
vendored
Normal file
201
vendor/github.com/go-logr/stdr/LICENSE
generated
vendored
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
6
vendor/github.com/go-logr/stdr/README.md
generated
vendored
Normal file
6
vendor/github.com/go-logr/stdr/README.md
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Minimal Go logging using logr and Go's standard library
|
||||||
|
|
||||||
|
[](https://pkg.go.dev/github.com/go-logr/stdr)
|
||||||
|
|
||||||
|
This package implements the [logr interface](https://github.com/go-logr/logr)
|
||||||
|
in terms of Go's standard log package(https://pkg.go.dev/log).
|
170
vendor/github.com/go-logr/stdr/stdr.go
generated
vendored
Normal file
170
vendor/github.com/go-logr/stdr/stdr.go
generated
vendored
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 The logr Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Package stdr implements github.com/go-logr/logr.Logger in terms of
|
||||||
|
// Go's standard log package.
|
||||||
|
package stdr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/go-logr/logr"
|
||||||
|
"github.com/go-logr/logr/funcr"
|
||||||
|
)
|
||||||
|
|
||||||
|
// The global verbosity level. See SetVerbosity().
|
||||||
|
var globalVerbosity int
|
||||||
|
|
||||||
|
// SetVerbosity sets the global level against which all info logs will be
|
||||||
|
// compared. If this is greater than or equal to the "V" of the logger, the
|
||||||
|
// message will be logged. A higher value here means more logs will be written.
|
||||||
|
// The previous verbosity value is returned. This is not concurrent-safe -
|
||||||
|
// callers must be sure to call it from only one goroutine.
|
||||||
|
func SetVerbosity(v int) int {
|
||||||
|
old := globalVerbosity
|
||||||
|
globalVerbosity = v
|
||||||
|
return old
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns a logr.Logger which is implemented by Go's standard log package,
|
||||||
|
// or something like it. If std is nil, this will use a default logger
|
||||||
|
// instead.
|
||||||
|
//
|
||||||
|
// Example: stdr.New(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile)))
|
||||||
|
func New(std StdLogger) logr.Logger {
|
||||||
|
return NewWithOptions(std, Options{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWithOptions returns a logr.Logger which is implemented by Go's standard
|
||||||
|
// log package, or something like it. See New for details.
|
||||||
|
func NewWithOptions(std StdLogger, opts Options) logr.Logger {
|
||||||
|
if std == nil {
|
||||||
|
// Go's log.Default() is only available in 1.16 and higher.
|
||||||
|
std = log.New(os.Stderr, "", log.LstdFlags)
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.Depth < 0 {
|
||||||
|
opts.Depth = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fopts := funcr.Options{
|
||||||
|
LogCaller: funcr.MessageClass(opts.LogCaller),
|
||||||
|
}
|
||||||
|
|
||||||
|
sl := &logger{
|
||||||
|
Formatter: funcr.NewFormatter(fopts),
|
||||||
|
std: std,
|
||||||
|
}
|
||||||
|
|
||||||
|
// For skipping our own logger.Info/Error.
|
||||||
|
sl.Formatter.AddCallDepth(1 + opts.Depth)
|
||||||
|
|
||||||
|
return logr.New(sl)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Options carries parameters which influence the way logs are generated.
|
||||||
|
type Options struct {
|
||||||
|
// Depth biases the assumed number of call frames to the "true" caller.
|
||||||
|
// This is useful when the calling code calls a function which then calls
|
||||||
|
// stdr (e.g. a logging shim to another API). Values less than zero will
|
||||||
|
// be treated as zero.
|
||||||
|
Depth int
|
||||||
|
|
||||||
|
// LogCaller tells stdr to add a "caller" key to some or all log lines.
|
||||||
|
// Go's log package has options to log this natively, too.
|
||||||
|
LogCaller MessageClass
|
||||||
|
|
||||||
|
// TODO: add an option to log the date/time
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageClass indicates which category or categories of messages to consider.
|
||||||
|
type MessageClass int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// None ignores all message classes.
|
||||||
|
None MessageClass = iota
|
||||||
|
// All considers all message classes.
|
||||||
|
All
|
||||||
|
// Info only considers info messages.
|
||||||
|
Info
|
||||||
|
// Error only considers error messages.
|
||||||
|
Error
|
||||||
|
)
|
||||||
|
|
||||||
|
// StdLogger is the subset of the Go stdlib log.Logger API that is needed for
|
||||||
|
// this adapter.
|
||||||
|
type StdLogger interface {
|
||||||
|
// Output is the same as log.Output and log.Logger.Output.
|
||||||
|
Output(calldepth int, logline string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type logger struct {
|
||||||
|
funcr.Formatter
|
||||||
|
std StdLogger
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ logr.LogSink = &logger{}
|
||||||
|
var _ logr.CallDepthLogSink = &logger{}
|
||||||
|
|
||||||
|
func (l logger) Enabled(level int) bool {
|
||||||
|
return globalVerbosity >= level
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l logger) Info(level int, msg string, kvList ...interface{}) {
|
||||||
|
prefix, args := l.FormatInfo(level, msg, kvList)
|
||||||
|
if prefix != "" {
|
||||||
|
args = prefix + ": " + args
|
||||||
|
}
|
||||||
|
_ = l.std.Output(l.Formatter.GetDepth()+1, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l logger) Error(err error, msg string, kvList ...interface{}) {
|
||||||
|
prefix, args := l.FormatError(err, msg, kvList)
|
||||||
|
if prefix != "" {
|
||||||
|
args = prefix + ": " + args
|
||||||
|
}
|
||||||
|
_ = l.std.Output(l.Formatter.GetDepth()+1, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l logger) WithName(name string) logr.LogSink {
|
||||||
|
l.Formatter.AddName(name)
|
||||||
|
return &l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l logger) WithValues(kvList ...interface{}) logr.LogSink {
|
||||||
|
l.Formatter.AddValues(kvList)
|
||||||
|
return &l
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l logger) WithCallDepth(depth int) logr.LogSink {
|
||||||
|
l.Formatter.AddCallDepth(depth)
|
||||||
|
return &l
|
||||||
|
}
|
||||||
|
|
||||||
|
// Underlier exposes access to the underlying logging implementation. Since
|
||||||
|
// callers only have a logr.Logger, they have to know which implementation is
|
||||||
|
// in use, so this interface is less of an abstraction and more of way to test
|
||||||
|
// type conversion.
|
||||||
|
type Underlier interface {
|
||||||
|
GetUnderlying() StdLogger
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUnderlying returns the StdLogger underneath this logger. Since StdLogger
|
||||||
|
// is itself an interface, the result may or may not be a Go log.Logger.
|
||||||
|
func (l logger) GetUnderlying() StdLogger {
|
||||||
|
return l.std
|
||||||
|
}
|
324
vendor/github.com/golang/protobuf/proto/buffer.go
generated
vendored
324
vendor/github.com/golang/protobuf/proto/buffer.go
generated
vendored
@ -1,324 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"google.golang.org/protobuf/encoding/prototext"
|
|
||||||
"google.golang.org/protobuf/encoding/protowire"
|
|
||||||
"google.golang.org/protobuf/runtime/protoimpl"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
WireVarint = 0
|
|
||||||
WireFixed32 = 5
|
|
||||||
WireFixed64 = 1
|
|
||||||
WireBytes = 2
|
|
||||||
WireStartGroup = 3
|
|
||||||
WireEndGroup = 4
|
|
||||||
)
|
|
||||||
|
|
||||||
// EncodeVarint returns the varint encoded bytes of v.
|
|
||||||
func EncodeVarint(v uint64) []byte {
|
|
||||||
return protowire.AppendVarint(nil, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SizeVarint returns the length of the varint encoded bytes of v.
|
|
||||||
// This is equal to len(EncodeVarint(v)).
|
|
||||||
func SizeVarint(v uint64) int {
|
|
||||||
return protowire.SizeVarint(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeVarint parses a varint encoded integer from b,
|
|
||||||
// returning the integer value and the length of the varint.
|
|
||||||
// It returns (0, 0) if there is a parse error.
|
|
||||||
func DecodeVarint(b []byte) (uint64, int) {
|
|
||||||
v, n := protowire.ConsumeVarint(b)
|
|
||||||
if n < 0 {
|
|
||||||
return 0, 0
|
|
||||||
}
|
|
||||||
return v, n
|
|
||||||
}
|
|
||||||
|
|
||||||
// Buffer is a buffer for encoding and decoding the protobuf wire format.
|
|
||||||
// It may be reused between invocations to reduce memory usage.
|
|
||||||
type Buffer struct {
|
|
||||||
buf []byte
|
|
||||||
idx int
|
|
||||||
deterministic bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBuffer allocates a new Buffer initialized with buf,
|
|
||||||
// where the contents of buf are considered the unread portion of the buffer.
|
|
||||||
func NewBuffer(buf []byte) *Buffer {
|
|
||||||
return &Buffer{buf: buf}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDeterministic specifies whether to use deterministic serialization.
|
|
||||||
//
|
|
||||||
// Deterministic serialization guarantees that for a given binary, equal
|
|
||||||
// messages will always be serialized to the same bytes. This implies:
|
|
||||||
//
|
|
||||||
// - Repeated serialization of a message will return the same bytes.
|
|
||||||
// - Different processes of the same binary (which may be executing on
|
|
||||||
// different machines) will serialize equal messages to the same bytes.
|
|
||||||
//
|
|
||||||
// Note that the deterministic serialization is NOT canonical across
|
|
||||||
// languages. It is not guaranteed to remain stable over time. It is unstable
|
|
||||||
// across different builds with schema changes due to unknown fields.
|
|
||||||
// Users who need canonical serialization (e.g., persistent storage in a
|
|
||||||
// canonical form, fingerprinting, etc.) should define their own
|
|
||||||
// canonicalization specification and implement their own serializer rather
|
|
||||||
// than relying on this API.
|
|
||||||
//
|
|
||||||
// If deterministic serialization is requested, map entries will be sorted
|
|
||||||
// by keys in lexographical order. This is an implementation detail and
|
|
||||||
// subject to change.
|
|
||||||
func (b *Buffer) SetDeterministic(deterministic bool) {
|
|
||||||
b.deterministic = deterministic
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetBuf sets buf as the internal buffer,
|
|
||||||
// where the contents of buf are considered the unread portion of the buffer.
|
|
||||||
func (b *Buffer) SetBuf(buf []byte) {
|
|
||||||
b.buf = buf
|
|
||||||
b.idx = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset clears the internal buffer of all written and unread data.
|
|
||||||
func (b *Buffer) Reset() {
|
|
||||||
b.buf = b.buf[:0]
|
|
||||||
b.idx = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bytes returns the internal buffer.
|
|
||||||
func (b *Buffer) Bytes() []byte {
|
|
||||||
return b.buf
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unread returns the unread portion of the buffer.
|
|
||||||
func (b *Buffer) Unread() []byte {
|
|
||||||
return b.buf[b.idx:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal appends the wire-format encoding of m to the buffer.
|
|
||||||
func (b *Buffer) Marshal(m Message) error {
|
|
||||||
var err error
|
|
||||||
b.buf, err = marshalAppend(b.buf, m, b.deterministic)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal parses the wire-format message in the buffer and
|
|
||||||
// places the decoded results in m.
|
|
||||||
// It does not reset m before unmarshaling.
|
|
||||||
func (b *Buffer) Unmarshal(m Message) error {
|
|
||||||
err := UnmarshalMerge(b.Unread(), m)
|
|
||||||
b.idx = len(b.buf)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type unknownFields struct{ XXX_unrecognized protoimpl.UnknownFields }
|
|
||||||
|
|
||||||
func (m *unknownFields) String() string { panic("not implemented") }
|
|
||||||
func (m *unknownFields) Reset() { panic("not implemented") }
|
|
||||||
func (m *unknownFields) ProtoMessage() { panic("not implemented") }
|
|
||||||
|
|
||||||
// DebugPrint dumps the encoded bytes of b with a header and footer including s
|
|
||||||
// to stdout. This is only intended for debugging.
|
|
||||||
func (*Buffer) DebugPrint(s string, b []byte) {
|
|
||||||
m := MessageReflect(new(unknownFields))
|
|
||||||
m.SetUnknown(b)
|
|
||||||
b, _ = prototext.MarshalOptions{AllowPartial: true, Indent: "\t"}.Marshal(m.Interface())
|
|
||||||
fmt.Printf("==== %s ====\n%s==== %s ====\n", s, b, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeVarint appends an unsigned varint encoding to the buffer.
|
|
||||||
func (b *Buffer) EncodeVarint(v uint64) error {
|
|
||||||
b.buf = protowire.AppendVarint(b.buf, v)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeZigzag32 appends a 32-bit zig-zag varint encoding to the buffer.
|
|
||||||
func (b *Buffer) EncodeZigzag32(v uint64) error {
|
|
||||||
return b.EncodeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31))))
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeZigzag64 appends a 64-bit zig-zag varint encoding to the buffer.
|
|
||||||
func (b *Buffer) EncodeZigzag64(v uint64) error {
|
|
||||||
return b.EncodeVarint(uint64((uint64(v) << 1) ^ uint64((int64(v) >> 63))))
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeFixed32 appends a 32-bit little-endian integer to the buffer.
|
|
||||||
func (b *Buffer) EncodeFixed32(v uint64) error {
|
|
||||||
b.buf = protowire.AppendFixed32(b.buf, uint32(v))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeFixed64 appends a 64-bit little-endian integer to the buffer.
|
|
||||||
func (b *Buffer) EncodeFixed64(v uint64) error {
|
|
||||||
b.buf = protowire.AppendFixed64(b.buf, uint64(v))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeRawBytes appends a length-prefixed raw bytes to the buffer.
|
|
||||||
func (b *Buffer) EncodeRawBytes(v []byte) error {
|
|
||||||
b.buf = protowire.AppendBytes(b.buf, v)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeStringBytes appends a length-prefixed raw bytes to the buffer.
|
|
||||||
// It does not validate whether v contains valid UTF-8.
|
|
||||||
func (b *Buffer) EncodeStringBytes(v string) error {
|
|
||||||
b.buf = protowire.AppendString(b.buf, v)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeMessage appends a length-prefixed encoded message to the buffer.
|
|
||||||
func (b *Buffer) EncodeMessage(m Message) error {
|
|
||||||
var err error
|
|
||||||
b.buf = protowire.AppendVarint(b.buf, uint64(Size(m)))
|
|
||||||
b.buf, err = marshalAppend(b.buf, m, b.deterministic)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeVarint consumes an encoded unsigned varint from the buffer.
|
|
||||||
func (b *Buffer) DecodeVarint() (uint64, error) {
|
|
||||||
v, n := protowire.ConsumeVarint(b.buf[b.idx:])
|
|
||||||
if n < 0 {
|
|
||||||
return 0, protowire.ParseError(n)
|
|
||||||
}
|
|
||||||
b.idx += n
|
|
||||||
return uint64(v), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeZigzag32 consumes an encoded 32-bit zig-zag varint from the buffer.
|
|
||||||
func (b *Buffer) DecodeZigzag32() (uint64, error) {
|
|
||||||
v, err := b.DecodeVarint()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return uint64((uint32(v) >> 1) ^ uint32((int32(v&1)<<31)>>31)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeZigzag64 consumes an encoded 64-bit zig-zag varint from the buffer.
|
|
||||||
func (b *Buffer) DecodeZigzag64() (uint64, error) {
|
|
||||||
v, err := b.DecodeVarint()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return uint64((uint64(v) >> 1) ^ uint64((int64(v&1)<<63)>>63)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeFixed32 consumes a 32-bit little-endian integer from the buffer.
|
|
||||||
func (b *Buffer) DecodeFixed32() (uint64, error) {
|
|
||||||
v, n := protowire.ConsumeFixed32(b.buf[b.idx:])
|
|
||||||
if n < 0 {
|
|
||||||
return 0, protowire.ParseError(n)
|
|
||||||
}
|
|
||||||
b.idx += n
|
|
||||||
return uint64(v), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeFixed64 consumes a 64-bit little-endian integer from the buffer.
|
|
||||||
func (b *Buffer) DecodeFixed64() (uint64, error) {
|
|
||||||
v, n := protowire.ConsumeFixed64(b.buf[b.idx:])
|
|
||||||
if n < 0 {
|
|
||||||
return 0, protowire.ParseError(n)
|
|
||||||
}
|
|
||||||
b.idx += n
|
|
||||||
return uint64(v), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeRawBytes consumes a length-prefixed raw bytes from the buffer.
|
|
||||||
// If alloc is specified, it returns a copy the raw bytes
|
|
||||||
// rather than a sub-slice of the buffer.
|
|
||||||
func (b *Buffer) DecodeRawBytes(alloc bool) ([]byte, error) {
|
|
||||||
v, n := protowire.ConsumeBytes(b.buf[b.idx:])
|
|
||||||
if n < 0 {
|
|
||||||
return nil, protowire.ParseError(n)
|
|
||||||
}
|
|
||||||
b.idx += n
|
|
||||||
if alloc {
|
|
||||||
v = append([]byte(nil), v...)
|
|
||||||
}
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeStringBytes consumes a length-prefixed raw bytes from the buffer.
|
|
||||||
// It does not validate whether the raw bytes contain valid UTF-8.
|
|
||||||
func (b *Buffer) DecodeStringBytes() (string, error) {
|
|
||||||
v, n := protowire.ConsumeString(b.buf[b.idx:])
|
|
||||||
if n < 0 {
|
|
||||||
return "", protowire.ParseError(n)
|
|
||||||
}
|
|
||||||
b.idx += n
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeMessage consumes a length-prefixed message from the buffer.
|
|
||||||
// It does not reset m before unmarshaling.
|
|
||||||
func (b *Buffer) DecodeMessage(m Message) error {
|
|
||||||
v, err := b.DecodeRawBytes(false)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return UnmarshalMerge(v, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeGroup consumes a message group from the buffer.
|
|
||||||
// It assumes that the start group marker has already been consumed and
|
|
||||||
// consumes all bytes until (and including the end group marker).
|
|
||||||
// It does not reset m before unmarshaling.
|
|
||||||
func (b *Buffer) DecodeGroup(m Message) error {
|
|
||||||
v, n, err := consumeGroup(b.buf[b.idx:])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b.idx += n
|
|
||||||
return UnmarshalMerge(v, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// consumeGroup parses b until it finds an end group marker, returning
|
|
||||||
// the raw bytes of the message (excluding the end group marker) and the
|
|
||||||
// the total length of the message (including the end group marker).
|
|
||||||
func consumeGroup(b []byte) ([]byte, int, error) {
|
|
||||||
b0 := b
|
|
||||||
depth := 1 // assume this follows a start group marker
|
|
||||||
for {
|
|
||||||
_, wtyp, tagLen := protowire.ConsumeTag(b)
|
|
||||||
if tagLen < 0 {
|
|
||||||
return nil, 0, protowire.ParseError(tagLen)
|
|
||||||
}
|
|
||||||
b = b[tagLen:]
|
|
||||||
|
|
||||||
var valLen int
|
|
||||||
switch wtyp {
|
|
||||||
case protowire.VarintType:
|
|
||||||
_, valLen = protowire.ConsumeVarint(b)
|
|
||||||
case protowire.Fixed32Type:
|
|
||||||
_, valLen = protowire.ConsumeFixed32(b)
|
|
||||||
case protowire.Fixed64Type:
|
|
||||||
_, valLen = protowire.ConsumeFixed64(b)
|
|
||||||
case protowire.BytesType:
|
|
||||||
_, valLen = protowire.ConsumeBytes(b)
|
|
||||||
case protowire.StartGroupType:
|
|
||||||
depth++
|
|
||||||
case protowire.EndGroupType:
|
|
||||||
depth--
|
|
||||||
default:
|
|
||||||
return nil, 0, errors.New("proto: cannot parse reserved wire type")
|
|
||||||
}
|
|
||||||
if valLen < 0 {
|
|
||||||
return nil, 0, protowire.ParseError(valLen)
|
|
||||||
}
|
|
||||||
b = b[valLen:]
|
|
||||||
|
|
||||||
if depth == 0 {
|
|
||||||
return b0[:len(b0)-len(b)-tagLen], len(b0) - len(b), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
63
vendor/github.com/golang/protobuf/proto/defaults.go
generated
vendored
63
vendor/github.com/golang/protobuf/proto/defaults.go
generated
vendored
@ -1,63 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetDefaults sets unpopulated scalar fields to their default values.
|
|
||||||
// Fields within a oneof are not set even if they have a default value.
|
|
||||||
// SetDefaults is recursively called upon any populated message fields.
|
|
||||||
func SetDefaults(m Message) {
|
|
||||||
if m != nil {
|
|
||||||
setDefaults(MessageReflect(m))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setDefaults(m protoreflect.Message) {
|
|
||||||
fds := m.Descriptor().Fields()
|
|
||||||
for i := 0; i < fds.Len(); i++ {
|
|
||||||
fd := fds.Get(i)
|
|
||||||
if !m.Has(fd) {
|
|
||||||
if fd.HasDefault() && fd.ContainingOneof() == nil {
|
|
||||||
v := fd.Default()
|
|
||||||
if fd.Kind() == protoreflect.BytesKind {
|
|
||||||
v = protoreflect.ValueOf(append([]byte(nil), v.Bytes()...)) // copy the default bytes
|
|
||||||
}
|
|
||||||
m.Set(fd, v)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
|
|
||||||
switch {
|
|
||||||
// Handle singular message.
|
|
||||||
case fd.Cardinality() != protoreflect.Repeated:
|
|
||||||
if fd.Message() != nil {
|
|
||||||
setDefaults(m.Get(fd).Message())
|
|
||||||
}
|
|
||||||
// Handle list of messages.
|
|
||||||
case fd.IsList():
|
|
||||||
if fd.Message() != nil {
|
|
||||||
ls := m.Get(fd).List()
|
|
||||||
for i := 0; i < ls.Len(); i++ {
|
|
||||||
setDefaults(ls.Get(i).Message())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Handle map of messages.
|
|
||||||
case fd.IsMap():
|
|
||||||
if fd.MapValue().Message() != nil {
|
|
||||||
ms := m.Get(fd).Map()
|
|
||||||
ms.Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool {
|
|
||||||
setDefaults(v.Message())
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
113
vendor/github.com/golang/protobuf/proto/deprecated.go
generated
vendored
113
vendor/github.com/golang/protobuf/proto/deprecated.go
generated
vendored
@ -1,113 +0,0 @@
|
|||||||
// Copyright 2018 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
protoV2 "google.golang.org/protobuf/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// Deprecated: No longer returned.
|
|
||||||
ErrNil = errors.New("proto: Marshal called with nil")
|
|
||||||
|
|
||||||
// Deprecated: No longer returned.
|
|
||||||
ErrTooLarge = errors.New("proto: message encodes to over 2 GB")
|
|
||||||
|
|
||||||
// Deprecated: No longer returned.
|
|
||||||
ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof")
|
|
||||||
)
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 }
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func GetStats() Stats { return Stats{} }
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func MarshalMessageSet(interface{}) ([]byte, error) {
|
|
||||||
return nil, errors.New("proto: not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func UnmarshalMessageSet([]byte, interface{}) error {
|
|
||||||
return errors.New("proto: not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func MarshalMessageSetJSON(interface{}) ([]byte, error) {
|
|
||||||
return nil, errors.New("proto: not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func UnmarshalMessageSetJSON([]byte, interface{}) error {
|
|
||||||
return errors.New("proto: not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func RegisterMessageSetType(Message, int32, string) {}
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func EnumName(m map[int32]string, v int32) string {
|
|
||||||
s, ok := m[v]
|
|
||||||
if ok {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
return strconv.Itoa(int(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) {
|
|
||||||
if data[0] == '"' {
|
|
||||||
// New style: enums are strings.
|
|
||||||
var repr string
|
|
||||||
if err := json.Unmarshal(data, &repr); err != nil {
|
|
||||||
return -1, err
|
|
||||||
}
|
|
||||||
val, ok := m[repr]
|
|
||||||
if !ok {
|
|
||||||
return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr)
|
|
||||||
}
|
|
||||||
return val, nil
|
|
||||||
}
|
|
||||||
// Old style: enums are ints.
|
|
||||||
var val int32
|
|
||||||
if err := json.Unmarshal(data, &val); err != nil {
|
|
||||||
return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName)
|
|
||||||
}
|
|
||||||
return val, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use; this type existed for intenal-use only.
|
|
||||||
type InternalMessageInfo struct{}
|
|
||||||
|
|
||||||
// Deprecated: Do not use; this method existed for intenal-use only.
|
|
||||||
func (*InternalMessageInfo) DiscardUnknown(m Message) {
|
|
||||||
DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use; this method existed for intenal-use only.
|
|
||||||
func (*InternalMessageInfo) Marshal(b []byte, m Message, deterministic bool) ([]byte, error) {
|
|
||||||
return protoV2.MarshalOptions{Deterministic: deterministic}.MarshalAppend(b, MessageV2(m))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use; this method existed for intenal-use only.
|
|
||||||
func (*InternalMessageInfo) Merge(dst, src Message) {
|
|
||||||
protoV2.Merge(MessageV2(dst), MessageV2(src))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use; this method existed for intenal-use only.
|
|
||||||
func (*InternalMessageInfo) Size(m Message) int {
|
|
||||||
return protoV2.Size(MessageV2(m))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use; this method existed for intenal-use only.
|
|
||||||
func (*InternalMessageInfo) Unmarshal(m Message, b []byte) error {
|
|
||||||
return protoV2.UnmarshalOptions{Merge: true}.Unmarshal(b, MessageV2(m))
|
|
||||||
}
|
|
58
vendor/github.com/golang/protobuf/proto/discard.go
generated
vendored
58
vendor/github.com/golang/protobuf/proto/discard.go
generated
vendored
@ -1,58 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DiscardUnknown recursively discards all unknown fields from this message
|
|
||||||
// and all embedded messages.
|
|
||||||
//
|
|
||||||
// When unmarshaling a message with unrecognized fields, the tags and values
|
|
||||||
// of such fields are preserved in the Message. This allows a later call to
|
|
||||||
// marshal to be able to produce a message that continues to have those
|
|
||||||
// unrecognized fields. To avoid this, DiscardUnknown is used to
|
|
||||||
// explicitly clear the unknown fields after unmarshaling.
|
|
||||||
func DiscardUnknown(m Message) {
|
|
||||||
if m != nil {
|
|
||||||
discardUnknown(MessageReflect(m))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func discardUnknown(m protoreflect.Message) {
|
|
||||||
m.Range(func(fd protoreflect.FieldDescriptor, val protoreflect.Value) bool {
|
|
||||||
switch {
|
|
||||||
// Handle singular message.
|
|
||||||
case fd.Cardinality() != protoreflect.Repeated:
|
|
||||||
if fd.Message() != nil {
|
|
||||||
discardUnknown(m.Get(fd).Message())
|
|
||||||
}
|
|
||||||
// Handle list of messages.
|
|
||||||
case fd.IsList():
|
|
||||||
if fd.Message() != nil {
|
|
||||||
ls := m.Get(fd).List()
|
|
||||||
for i := 0; i < ls.Len(); i++ {
|
|
||||||
discardUnknown(ls.Get(i).Message())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Handle map of messages.
|
|
||||||
case fd.IsMap():
|
|
||||||
if fd.MapValue().Message() != nil {
|
|
||||||
ms := m.Get(fd).Map()
|
|
||||||
ms.Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool {
|
|
||||||
discardUnknown(v.Message())
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
// Discard unknown fields.
|
|
||||||
if len(m.GetUnknown()) > 0 {
|
|
||||||
m.SetUnknown(nil)
|
|
||||||
}
|
|
||||||
}
|
|
356
vendor/github.com/golang/protobuf/proto/extensions.go
generated
vendored
356
vendor/github.com/golang/protobuf/proto/extensions.go
generated
vendored
@ -1,356 +0,0 @@
|
|||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"google.golang.org/protobuf/encoding/protowire"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
"google.golang.org/protobuf/reflect/protoregistry"
|
|
||||||
"google.golang.org/protobuf/runtime/protoiface"
|
|
||||||
"google.golang.org/protobuf/runtime/protoimpl"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
// ExtensionDesc represents an extension descriptor and
|
|
||||||
// is used to interact with an extension field in a message.
|
|
||||||
//
|
|
||||||
// Variables of this type are generated in code by protoc-gen-go.
|
|
||||||
ExtensionDesc = protoimpl.ExtensionInfo
|
|
||||||
|
|
||||||
// ExtensionRange represents a range of message extensions.
|
|
||||||
// Used in code generated by protoc-gen-go.
|
|
||||||
ExtensionRange = protoiface.ExtensionRangeV1
|
|
||||||
|
|
||||||
// Deprecated: Do not use; this is an internal type.
|
|
||||||
Extension = protoimpl.ExtensionFieldV1
|
|
||||||
|
|
||||||
// Deprecated: Do not use; this is an internal type.
|
|
||||||
XXX_InternalExtensions = protoimpl.ExtensionFields
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrMissingExtension reports whether the extension was not present.
|
|
||||||
var ErrMissingExtension = errors.New("proto: missing extension")
|
|
||||||
|
|
||||||
var errNotExtendable = errors.New("proto: not an extendable proto.Message")
|
|
||||||
|
|
||||||
// HasExtension reports whether the extension field is present in m
|
|
||||||
// either as an explicitly populated field or as an unknown field.
|
|
||||||
func HasExtension(m Message, xt *ExtensionDesc) (has bool) {
|
|
||||||
mr := MessageReflect(m)
|
|
||||||
if mr == nil || !mr.IsValid() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether any populated known field matches the field number.
|
|
||||||
xtd := xt.TypeDescriptor()
|
|
||||||
if isValidExtension(mr.Descriptor(), xtd) {
|
|
||||||
has = mr.Has(xtd)
|
|
||||||
} else {
|
|
||||||
mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool {
|
|
||||||
has = int32(fd.Number()) == xt.Field
|
|
||||||
return !has
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether any unknown field matches the field number.
|
|
||||||
for b := mr.GetUnknown(); !has && len(b) > 0; {
|
|
||||||
num, _, n := protowire.ConsumeField(b)
|
|
||||||
has = int32(num) == xt.Field
|
|
||||||
b = b[n:]
|
|
||||||
}
|
|
||||||
return has
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClearExtension removes the extension field from m
|
|
||||||
// either as an explicitly populated field or as an unknown field.
|
|
||||||
func ClearExtension(m Message, xt *ExtensionDesc) {
|
|
||||||
mr := MessageReflect(m)
|
|
||||||
if mr == nil || !mr.IsValid() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
xtd := xt.TypeDescriptor()
|
|
||||||
if isValidExtension(mr.Descriptor(), xtd) {
|
|
||||||
mr.Clear(xtd)
|
|
||||||
} else {
|
|
||||||
mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool {
|
|
||||||
if int32(fd.Number()) == xt.Field {
|
|
||||||
mr.Clear(fd)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
clearUnknown(mr, fieldNum(xt.Field))
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClearAllExtensions clears all extensions from m.
|
|
||||||
// This includes populated fields and unknown fields in the extension range.
|
|
||||||
func ClearAllExtensions(m Message) {
|
|
||||||
mr := MessageReflect(m)
|
|
||||||
if mr == nil || !mr.IsValid() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool {
|
|
||||||
if fd.IsExtension() {
|
|
||||||
mr.Clear(fd)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
clearUnknown(mr, mr.Descriptor().ExtensionRanges())
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetExtension retrieves a proto2 extended field from m.
|
|
||||||
//
|
|
||||||
// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),
|
|
||||||
// then GetExtension parses the encoded field and returns a Go value of the specified type.
|
|
||||||
// If the field is not present, then the default value is returned (if one is specified),
|
|
||||||
// otherwise ErrMissingExtension is reported.
|
|
||||||
//
|
|
||||||
// If the descriptor is type incomplete (i.e., ExtensionDesc.ExtensionType is nil),
|
|
||||||
// then GetExtension returns the raw encoded bytes for the extension field.
|
|
||||||
func GetExtension(m Message, xt *ExtensionDesc) (interface{}, error) {
|
|
||||||
mr := MessageReflect(m)
|
|
||||||
if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 {
|
|
||||||
return nil, errNotExtendable
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve the unknown fields for this extension field.
|
|
||||||
var bo protoreflect.RawFields
|
|
||||||
for bi := mr.GetUnknown(); len(bi) > 0; {
|
|
||||||
num, _, n := protowire.ConsumeField(bi)
|
|
||||||
if int32(num) == xt.Field {
|
|
||||||
bo = append(bo, bi[:n]...)
|
|
||||||
}
|
|
||||||
bi = bi[n:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// For type incomplete descriptors, only retrieve the unknown fields.
|
|
||||||
if xt.ExtensionType == nil {
|
|
||||||
return []byte(bo), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the extension field only exists as unknown fields, unmarshal it.
|
|
||||||
// This is rarely done since proto.Unmarshal eagerly unmarshals extensions.
|
|
||||||
xtd := xt.TypeDescriptor()
|
|
||||||
if !isValidExtension(mr.Descriptor(), xtd) {
|
|
||||||
return nil, fmt.Errorf("proto: bad extended type; %T does not extend %T", xt.ExtendedType, m)
|
|
||||||
}
|
|
||||||
if !mr.Has(xtd) && len(bo) > 0 {
|
|
||||||
m2 := mr.New()
|
|
||||||
if err := (proto.UnmarshalOptions{
|
|
||||||
Resolver: extensionResolver{xt},
|
|
||||||
}.Unmarshal(bo, m2.Interface())); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if m2.Has(xtd) {
|
|
||||||
mr.Set(xtd, m2.Get(xtd))
|
|
||||||
clearUnknown(mr, fieldNum(xt.Field))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether the message has the extension field set or a default.
|
|
||||||
var pv protoreflect.Value
|
|
||||||
switch {
|
|
||||||
case mr.Has(xtd):
|
|
||||||
pv = mr.Get(xtd)
|
|
||||||
case xtd.HasDefault():
|
|
||||||
pv = xtd.Default()
|
|
||||||
default:
|
|
||||||
return nil, ErrMissingExtension
|
|
||||||
}
|
|
||||||
|
|
||||||
v := xt.InterfaceOf(pv)
|
|
||||||
rv := reflect.ValueOf(v)
|
|
||||||
if isScalarKind(rv.Kind()) {
|
|
||||||
rv2 := reflect.New(rv.Type())
|
|
||||||
rv2.Elem().Set(rv)
|
|
||||||
v = rv2.Interface()
|
|
||||||
}
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// extensionResolver is a custom extension resolver that stores a single
|
|
||||||
// extension type that takes precedence over the global registry.
|
|
||||||
type extensionResolver struct{ xt protoreflect.ExtensionType }
|
|
||||||
|
|
||||||
func (r extensionResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) {
|
|
||||||
if xtd := r.xt.TypeDescriptor(); xtd.FullName() == field {
|
|
||||||
return r.xt, nil
|
|
||||||
}
|
|
||||||
return protoregistry.GlobalTypes.FindExtensionByName(field)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r extensionResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {
|
|
||||||
if xtd := r.xt.TypeDescriptor(); xtd.ContainingMessage().FullName() == message && xtd.Number() == field {
|
|
||||||
return r.xt, nil
|
|
||||||
}
|
|
||||||
return protoregistry.GlobalTypes.FindExtensionByNumber(message, field)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetExtensions returns a list of the extensions values present in m,
|
|
||||||
// corresponding with the provided list of extension descriptors, xts.
|
|
||||||
// If an extension is missing in m, the corresponding value is nil.
|
|
||||||
func GetExtensions(m Message, xts []*ExtensionDesc) ([]interface{}, error) {
|
|
||||||
mr := MessageReflect(m)
|
|
||||||
if mr == nil || !mr.IsValid() {
|
|
||||||
return nil, errNotExtendable
|
|
||||||
}
|
|
||||||
|
|
||||||
vs := make([]interface{}, len(xts))
|
|
||||||
for i, xt := range xts {
|
|
||||||
v, err := GetExtension(m, xt)
|
|
||||||
if err != nil {
|
|
||||||
if err == ErrMissingExtension {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return vs, err
|
|
||||||
}
|
|
||||||
vs[i] = v
|
|
||||||
}
|
|
||||||
return vs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetExtension sets an extension field in m to the provided value.
|
|
||||||
func SetExtension(m Message, xt *ExtensionDesc, v interface{}) error {
|
|
||||||
mr := MessageReflect(m)
|
|
||||||
if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 {
|
|
||||||
return errNotExtendable
|
|
||||||
}
|
|
||||||
|
|
||||||
rv := reflect.ValueOf(v)
|
|
||||||
if reflect.TypeOf(v) != reflect.TypeOf(xt.ExtensionType) {
|
|
||||||
return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", v, xt.ExtensionType)
|
|
||||||
}
|
|
||||||
if rv.Kind() == reflect.Ptr {
|
|
||||||
if rv.IsNil() {
|
|
||||||
return fmt.Errorf("proto: SetExtension called with nil value of type %T", v)
|
|
||||||
}
|
|
||||||
if isScalarKind(rv.Elem().Kind()) {
|
|
||||||
v = rv.Elem().Interface()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xtd := xt.TypeDescriptor()
|
|
||||||
if !isValidExtension(mr.Descriptor(), xtd) {
|
|
||||||
return fmt.Errorf("proto: bad extended type; %T does not extend %T", xt.ExtendedType, m)
|
|
||||||
}
|
|
||||||
mr.Set(xtd, xt.ValueOf(v))
|
|
||||||
clearUnknown(mr, fieldNum(xt.Field))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetRawExtension inserts b into the unknown fields of m.
|
|
||||||
//
|
|
||||||
// Deprecated: Use Message.ProtoReflect.SetUnknown instead.
|
|
||||||
func SetRawExtension(m Message, fnum int32, b []byte) {
|
|
||||||
mr := MessageReflect(m)
|
|
||||||
if mr == nil || !mr.IsValid() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify that the raw field is valid.
|
|
||||||
for b0 := b; len(b0) > 0; {
|
|
||||||
num, _, n := protowire.ConsumeField(b0)
|
|
||||||
if int32(num) != fnum {
|
|
||||||
panic(fmt.Sprintf("mismatching field number: got %d, want %d", num, fnum))
|
|
||||||
}
|
|
||||||
b0 = b0[n:]
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearExtension(m, &ExtensionDesc{Field: fnum})
|
|
||||||
mr.SetUnknown(append(mr.GetUnknown(), b...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExtensionDescs returns a list of extension descriptors found in m,
|
|
||||||
// containing descriptors for both populated extension fields in m and
|
|
||||||
// also unknown fields of m that are in the extension range.
|
|
||||||
// For the later case, an type incomplete descriptor is provided where only
|
|
||||||
// the ExtensionDesc.Field field is populated.
|
|
||||||
// The order of the extension descriptors is undefined.
|
|
||||||
func ExtensionDescs(m Message) ([]*ExtensionDesc, error) {
|
|
||||||
mr := MessageReflect(m)
|
|
||||||
if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 {
|
|
||||||
return nil, errNotExtendable
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect a set of known extension descriptors.
|
|
||||||
extDescs := make(map[protoreflect.FieldNumber]*ExtensionDesc)
|
|
||||||
mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
|
|
||||||
if fd.IsExtension() {
|
|
||||||
xt := fd.(protoreflect.ExtensionTypeDescriptor)
|
|
||||||
if xd, ok := xt.Type().(*ExtensionDesc); ok {
|
|
||||||
extDescs[fd.Number()] = xd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
// Collect a set of unknown extension descriptors.
|
|
||||||
extRanges := mr.Descriptor().ExtensionRanges()
|
|
||||||
for b := mr.GetUnknown(); len(b) > 0; {
|
|
||||||
num, _, n := protowire.ConsumeField(b)
|
|
||||||
if extRanges.Has(num) && extDescs[num] == nil {
|
|
||||||
extDescs[num] = nil
|
|
||||||
}
|
|
||||||
b = b[n:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transpose the set of descriptors into a list.
|
|
||||||
var xts []*ExtensionDesc
|
|
||||||
for num, xt := range extDescs {
|
|
||||||
if xt == nil {
|
|
||||||
xt = &ExtensionDesc{Field: int32(num)}
|
|
||||||
}
|
|
||||||
xts = append(xts, xt)
|
|
||||||
}
|
|
||||||
return xts, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// isValidExtension reports whether xtd is a valid extension descriptor for md.
|
|
||||||
func isValidExtension(md protoreflect.MessageDescriptor, xtd protoreflect.ExtensionTypeDescriptor) bool {
|
|
||||||
return xtd.ContainingMessage() == md && md.ExtensionRanges().Has(xtd.Number())
|
|
||||||
}
|
|
||||||
|
|
||||||
// isScalarKind reports whether k is a protobuf scalar kind (except bytes).
|
|
||||||
// This function exists for historical reasons since the representation of
|
|
||||||
// scalars differs between v1 and v2, where v1 uses *T and v2 uses T.
|
|
||||||
func isScalarKind(k reflect.Kind) bool {
|
|
||||||
switch k {
|
|
||||||
case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// clearUnknown removes unknown fields from m where remover.Has reports true.
|
|
||||||
func clearUnknown(m protoreflect.Message, remover interface {
|
|
||||||
Has(protoreflect.FieldNumber) bool
|
|
||||||
}) {
|
|
||||||
var bo protoreflect.RawFields
|
|
||||||
for bi := m.GetUnknown(); len(bi) > 0; {
|
|
||||||
num, _, n := protowire.ConsumeField(bi)
|
|
||||||
if !remover.Has(num) {
|
|
||||||
bo = append(bo, bi[:n]...)
|
|
||||||
}
|
|
||||||
bi = bi[n:]
|
|
||||||
}
|
|
||||||
if bi := m.GetUnknown(); len(bi) != len(bo) {
|
|
||||||
m.SetUnknown(bo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type fieldNum protoreflect.FieldNumber
|
|
||||||
|
|
||||||
func (n1 fieldNum) Has(n2 protoreflect.FieldNumber) bool {
|
|
||||||
return protoreflect.FieldNumber(n1) == n2
|
|
||||||
}
|
|
306
vendor/github.com/golang/protobuf/proto/properties.go
generated
vendored
306
vendor/github.com/golang/protobuf/proto/properties.go
generated
vendored
@ -1,306 +0,0 @@
|
|||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
"google.golang.org/protobuf/runtime/protoimpl"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StructProperties represents protocol buffer type information for a
|
|
||||||
// generated protobuf message in the open-struct API.
|
|
||||||
//
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
type StructProperties struct {
|
|
||||||
// Prop are the properties for each field.
|
|
||||||
//
|
|
||||||
// Fields belonging to a oneof are stored in OneofTypes instead, with a
|
|
||||||
// single Properties representing the parent oneof held here.
|
|
||||||
//
|
|
||||||
// The order of Prop matches the order of fields in the Go struct.
|
|
||||||
// Struct fields that are not related to protobufs have a "XXX_" prefix
|
|
||||||
// in the Properties.Name and must be ignored by the user.
|
|
||||||
Prop []*Properties
|
|
||||||
|
|
||||||
// OneofTypes contains information about the oneof fields in this message.
|
|
||||||
// It is keyed by the protobuf field name.
|
|
||||||
OneofTypes map[string]*OneofProperties
|
|
||||||
}
|
|
||||||
|
|
||||||
// Properties represents the type information for a protobuf message field.
|
|
||||||
//
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
type Properties struct {
|
|
||||||
// Name is a placeholder name with little meaningful semantic value.
|
|
||||||
// If the name has an "XXX_" prefix, the entire Properties must be ignored.
|
|
||||||
Name string
|
|
||||||
// OrigName is the protobuf field name or oneof name.
|
|
||||||
OrigName string
|
|
||||||
// JSONName is the JSON name for the protobuf field.
|
|
||||||
JSONName string
|
|
||||||
// Enum is a placeholder name for enums.
|
|
||||||
// For historical reasons, this is neither the Go name for the enum,
|
|
||||||
// nor the protobuf name for the enum.
|
|
||||||
Enum string // Deprecated: Do not use.
|
|
||||||
// Weak contains the full name of the weakly referenced message.
|
|
||||||
Weak string
|
|
||||||
// Wire is a string representation of the wire type.
|
|
||||||
Wire string
|
|
||||||
// WireType is the protobuf wire type for the field.
|
|
||||||
WireType int
|
|
||||||
// Tag is the protobuf field number.
|
|
||||||
Tag int
|
|
||||||
// Required reports whether this is a required field.
|
|
||||||
Required bool
|
|
||||||
// Optional reports whether this is a optional field.
|
|
||||||
Optional bool
|
|
||||||
// Repeated reports whether this is a repeated field.
|
|
||||||
Repeated bool
|
|
||||||
// Packed reports whether this is a packed repeated field of scalars.
|
|
||||||
Packed bool
|
|
||||||
// Proto3 reports whether this field operates under the proto3 syntax.
|
|
||||||
Proto3 bool
|
|
||||||
// Oneof reports whether this field belongs within a oneof.
|
|
||||||
Oneof bool
|
|
||||||
|
|
||||||
// Default is the default value in string form.
|
|
||||||
Default string
|
|
||||||
// HasDefault reports whether the field has a default value.
|
|
||||||
HasDefault bool
|
|
||||||
|
|
||||||
// MapKeyProp is the properties for the key field for a map field.
|
|
||||||
MapKeyProp *Properties
|
|
||||||
// MapValProp is the properties for the value field for a map field.
|
|
||||||
MapValProp *Properties
|
|
||||||
}
|
|
||||||
|
|
||||||
// OneofProperties represents the type information for a protobuf oneof.
|
|
||||||
//
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
type OneofProperties struct {
|
|
||||||
// Type is a pointer to the generated wrapper type for the field value.
|
|
||||||
// This is nil for messages that are not in the open-struct API.
|
|
||||||
Type reflect.Type
|
|
||||||
// Field is the index into StructProperties.Prop for the containing oneof.
|
|
||||||
Field int
|
|
||||||
// Prop is the properties for the field.
|
|
||||||
Prop *Properties
|
|
||||||
}
|
|
||||||
|
|
||||||
// String formats the properties in the protobuf struct field tag style.
|
|
||||||
func (p *Properties) String() string {
|
|
||||||
s := p.Wire
|
|
||||||
s += "," + strconv.Itoa(p.Tag)
|
|
||||||
if p.Required {
|
|
||||||
s += ",req"
|
|
||||||
}
|
|
||||||
if p.Optional {
|
|
||||||
s += ",opt"
|
|
||||||
}
|
|
||||||
if p.Repeated {
|
|
||||||
s += ",rep"
|
|
||||||
}
|
|
||||||
if p.Packed {
|
|
||||||
s += ",packed"
|
|
||||||
}
|
|
||||||
s += ",name=" + p.OrigName
|
|
||||||
if p.JSONName != "" {
|
|
||||||
s += ",json=" + p.JSONName
|
|
||||||
}
|
|
||||||
if len(p.Enum) > 0 {
|
|
||||||
s += ",enum=" + p.Enum
|
|
||||||
}
|
|
||||||
if len(p.Weak) > 0 {
|
|
||||||
s += ",weak=" + p.Weak
|
|
||||||
}
|
|
||||||
if p.Proto3 {
|
|
||||||
s += ",proto3"
|
|
||||||
}
|
|
||||||
if p.Oneof {
|
|
||||||
s += ",oneof"
|
|
||||||
}
|
|
||||||
if p.HasDefault {
|
|
||||||
s += ",def=" + p.Default
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse populates p by parsing a string in the protobuf struct field tag style.
|
|
||||||
func (p *Properties) Parse(tag string) {
|
|
||||||
// For example: "bytes,49,opt,name=foo,def=hello!"
|
|
||||||
for len(tag) > 0 {
|
|
||||||
i := strings.IndexByte(tag, ',')
|
|
||||||
if i < 0 {
|
|
||||||
i = len(tag)
|
|
||||||
}
|
|
||||||
switch s := tag[:i]; {
|
|
||||||
case strings.HasPrefix(s, "name="):
|
|
||||||
p.OrigName = s[len("name="):]
|
|
||||||
case strings.HasPrefix(s, "json="):
|
|
||||||
p.JSONName = s[len("json="):]
|
|
||||||
case strings.HasPrefix(s, "enum="):
|
|
||||||
p.Enum = s[len("enum="):]
|
|
||||||
case strings.HasPrefix(s, "weak="):
|
|
||||||
p.Weak = s[len("weak="):]
|
|
||||||
case strings.Trim(s, "0123456789") == "":
|
|
||||||
n, _ := strconv.ParseUint(s, 10, 32)
|
|
||||||
p.Tag = int(n)
|
|
||||||
case s == "opt":
|
|
||||||
p.Optional = true
|
|
||||||
case s == "req":
|
|
||||||
p.Required = true
|
|
||||||
case s == "rep":
|
|
||||||
p.Repeated = true
|
|
||||||
case s == "varint" || s == "zigzag32" || s == "zigzag64":
|
|
||||||
p.Wire = s
|
|
||||||
p.WireType = WireVarint
|
|
||||||
case s == "fixed32":
|
|
||||||
p.Wire = s
|
|
||||||
p.WireType = WireFixed32
|
|
||||||
case s == "fixed64":
|
|
||||||
p.Wire = s
|
|
||||||
p.WireType = WireFixed64
|
|
||||||
case s == "bytes":
|
|
||||||
p.Wire = s
|
|
||||||
p.WireType = WireBytes
|
|
||||||
case s == "group":
|
|
||||||
p.Wire = s
|
|
||||||
p.WireType = WireStartGroup
|
|
||||||
case s == "packed":
|
|
||||||
p.Packed = true
|
|
||||||
case s == "proto3":
|
|
||||||
p.Proto3 = true
|
|
||||||
case s == "oneof":
|
|
||||||
p.Oneof = true
|
|
||||||
case strings.HasPrefix(s, "def="):
|
|
||||||
// The default tag is special in that everything afterwards is the
|
|
||||||
// default regardless of the presence of commas.
|
|
||||||
p.HasDefault = true
|
|
||||||
p.Default, i = tag[len("def="):], len(tag)
|
|
||||||
}
|
|
||||||
tag = strings.TrimPrefix(tag[i:], ",")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init populates the properties from a protocol buffer struct tag.
|
|
||||||
//
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
|
|
||||||
p.Name = name
|
|
||||||
p.OrigName = name
|
|
||||||
if tag == "" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
p.Parse(tag)
|
|
||||||
|
|
||||||
if typ != nil && typ.Kind() == reflect.Map {
|
|
||||||
p.MapKeyProp = new(Properties)
|
|
||||||
p.MapKeyProp.Init(nil, "Key", f.Tag.Get("protobuf_key"), nil)
|
|
||||||
p.MapValProp = new(Properties)
|
|
||||||
p.MapValProp.Init(nil, "Value", f.Tag.Get("protobuf_val"), nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var propertiesCache sync.Map // map[reflect.Type]*StructProperties
|
|
||||||
|
|
||||||
// GetProperties returns the list of properties for the type represented by t,
|
|
||||||
// which must be a generated protocol buffer message in the open-struct API,
|
|
||||||
// where protobuf message fields are represented by exported Go struct fields.
|
|
||||||
//
|
|
||||||
// Deprecated: Use protobuf reflection instead.
|
|
||||||
func GetProperties(t reflect.Type) *StructProperties {
|
|
||||||
if p, ok := propertiesCache.Load(t); ok {
|
|
||||||
return p.(*StructProperties)
|
|
||||||
}
|
|
||||||
p, _ := propertiesCache.LoadOrStore(t, newProperties(t))
|
|
||||||
return p.(*StructProperties)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newProperties(t reflect.Type) *StructProperties {
|
|
||||||
if t.Kind() != reflect.Struct {
|
|
||||||
panic(fmt.Sprintf("%v is not a generated message in the open-struct API", t))
|
|
||||||
}
|
|
||||||
|
|
||||||
var hasOneof bool
|
|
||||||
prop := new(StructProperties)
|
|
||||||
|
|
||||||
// Construct a list of properties for each field in the struct.
|
|
||||||
for i := 0; i < t.NumField(); i++ {
|
|
||||||
p := new(Properties)
|
|
||||||
f := t.Field(i)
|
|
||||||
tagField := f.Tag.Get("protobuf")
|
|
||||||
p.Init(f.Type, f.Name, tagField, &f)
|
|
||||||
|
|
||||||
tagOneof := f.Tag.Get("protobuf_oneof")
|
|
||||||
if tagOneof != "" {
|
|
||||||
hasOneof = true
|
|
||||||
p.OrigName = tagOneof
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rename unrelated struct fields with the "XXX_" prefix since so much
|
|
||||||
// user code simply checks for this to exclude special fields.
|
|
||||||
if tagField == "" && tagOneof == "" && !strings.HasPrefix(p.Name, "XXX_") {
|
|
||||||
p.Name = "XXX_" + p.Name
|
|
||||||
p.OrigName = "XXX_" + p.OrigName
|
|
||||||
} else if p.Weak != "" {
|
|
||||||
p.Name = p.OrigName // avoid possible "XXX_" prefix on weak field
|
|
||||||
}
|
|
||||||
|
|
||||||
prop.Prop = append(prop.Prop, p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct a mapping of oneof field names to properties.
|
|
||||||
if hasOneof {
|
|
||||||
var oneofWrappers []interface{}
|
|
||||||
if fn, ok := reflect.PtrTo(t).MethodByName("XXX_OneofFuncs"); ok {
|
|
||||||
oneofWrappers = fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[3].Interface().([]interface{})
|
|
||||||
}
|
|
||||||
if fn, ok := reflect.PtrTo(t).MethodByName("XXX_OneofWrappers"); ok {
|
|
||||||
oneofWrappers = fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0].Interface().([]interface{})
|
|
||||||
}
|
|
||||||
if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(protoreflect.ProtoMessage); ok {
|
|
||||||
if m, ok := m.ProtoReflect().(interface{ ProtoMessageInfo() *protoimpl.MessageInfo }); ok {
|
|
||||||
oneofWrappers = m.ProtoMessageInfo().OneofWrappers
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
prop.OneofTypes = make(map[string]*OneofProperties)
|
|
||||||
for _, wrapper := range oneofWrappers {
|
|
||||||
p := &OneofProperties{
|
|
||||||
Type: reflect.ValueOf(wrapper).Type(), // *T
|
|
||||||
Prop: new(Properties),
|
|
||||||
}
|
|
||||||
f := p.Type.Elem().Field(0)
|
|
||||||
p.Prop.Name = f.Name
|
|
||||||
p.Prop.Parse(f.Tag.Get("protobuf"))
|
|
||||||
|
|
||||||
// Determine the struct field that contains this oneof.
|
|
||||||
// Each wrapper is assignable to exactly one parent field.
|
|
||||||
var foundOneof bool
|
|
||||||
for i := 0; i < t.NumField() && !foundOneof; i++ {
|
|
||||||
if p.Type.AssignableTo(t.Field(i).Type) {
|
|
||||||
p.Field = i
|
|
||||||
foundOneof = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !foundOneof {
|
|
||||||
panic(fmt.Sprintf("%v is not a generated message in the open-struct API", t))
|
|
||||||
}
|
|
||||||
prop.OneofTypes[p.Prop.OrigName] = p
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return prop
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sp *StructProperties) Len() int { return len(sp.Prop) }
|
|
||||||
func (sp *StructProperties) Less(i, j int) bool { return false }
|
|
||||||
func (sp *StructProperties) Swap(i, j int) { return }
|
|
167
vendor/github.com/golang/protobuf/proto/proto.go
generated
vendored
167
vendor/github.com/golang/protobuf/proto/proto.go
generated
vendored
@ -1,167 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package proto provides functionality for handling protocol buffer messages.
|
|
||||||
// In particular, it provides marshaling and unmarshaling between a protobuf
|
|
||||||
// message and the binary wire format.
|
|
||||||
//
|
|
||||||
// See https://developers.google.com/protocol-buffers/docs/gotutorial for
|
|
||||||
// more information.
|
|
||||||
//
|
|
||||||
// Deprecated: Use the "google.golang.org/protobuf/proto" package instead.
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
protoV2 "google.golang.org/protobuf/proto"
|
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
"google.golang.org/protobuf/runtime/protoiface"
|
|
||||||
"google.golang.org/protobuf/runtime/protoimpl"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
ProtoPackageIsVersion1 = true
|
|
||||||
ProtoPackageIsVersion2 = true
|
|
||||||
ProtoPackageIsVersion3 = true
|
|
||||||
ProtoPackageIsVersion4 = true
|
|
||||||
)
|
|
||||||
|
|
||||||
// GeneratedEnum is any enum type generated by protoc-gen-go
|
|
||||||
// which is a named int32 kind.
|
|
||||||
// This type exists for documentation purposes.
|
|
||||||
type GeneratedEnum interface{}
|
|
||||||
|
|
||||||
// GeneratedMessage is any message type generated by protoc-gen-go
|
|
||||||
// which is a pointer to a named struct kind.
|
|
||||||
// This type exists for documentation purposes.
|
|
||||||
type GeneratedMessage interface{}
|
|
||||||
|
|
||||||
// Message is a protocol buffer message.
|
|
||||||
//
|
|
||||||
// This is the v1 version of the message interface and is marginally better
|
|
||||||
// than an empty interface as it lacks any method to programatically interact
|
|
||||||
// with the contents of the message.
|
|
||||||
//
|
|
||||||
// A v2 message is declared in "google.golang.org/protobuf/proto".Message and
|
|
||||||
// exposes protobuf reflection as a first-class feature of the interface.
|
|
||||||
//
|
|
||||||
// To convert a v1 message to a v2 message, use the MessageV2 function.
|
|
||||||
// To convert a v2 message to a v1 message, use the MessageV1 function.
|
|
||||||
type Message = protoiface.MessageV1
|
|
||||||
|
|
||||||
// MessageV1 converts either a v1 or v2 message to a v1 message.
|
|
||||||
// It returns nil if m is nil.
|
|
||||||
func MessageV1(m GeneratedMessage) protoiface.MessageV1 {
|
|
||||||
return protoimpl.X.ProtoMessageV1Of(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MessageV2 converts either a v1 or v2 message to a v2 message.
|
|
||||||
// It returns nil if m is nil.
|
|
||||||
func MessageV2(m GeneratedMessage) protoV2.Message {
|
|
||||||
return protoimpl.X.ProtoMessageV2Of(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MessageReflect returns a reflective view for a message.
|
|
||||||
// It returns nil if m is nil.
|
|
||||||
func MessageReflect(m Message) protoreflect.Message {
|
|
||||||
return protoimpl.X.MessageOf(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshaler is implemented by messages that can marshal themselves.
|
|
||||||
// This interface is used by the following functions: Size, Marshal,
|
|
||||||
// Buffer.Marshal, and Buffer.EncodeMessage.
|
|
||||||
//
|
|
||||||
// Deprecated: Do not implement.
|
|
||||||
type Marshaler interface {
|
|
||||||
// Marshal formats the encoded bytes of the message.
|
|
||||||
// It should be deterministic and emit valid protobuf wire data.
|
|
||||||
// The caller takes ownership of the returned buffer.
|
|
||||||
Marshal() ([]byte, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshaler is implemented by messages that can unmarshal themselves.
|
|
||||||
// This interface is used by the following functions: Unmarshal, UnmarshalMerge,
|
|
||||||
// Buffer.Unmarshal, Buffer.DecodeMessage, and Buffer.DecodeGroup.
|
|
||||||
//
|
|
||||||
// Deprecated: Do not implement.
|
|
||||||
type Unmarshaler interface {
|
|
||||||
// Unmarshal parses the encoded bytes of the protobuf wire input.
|
|
||||||
// The provided buffer is only valid for during method call.
|
|
||||||
// It should not reset the receiver message.
|
|
||||||
Unmarshal([]byte) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Merger is implemented by messages that can merge themselves.
|
|
||||||
// This interface is used by the following functions: Clone and Merge.
|
|
||||||
//
|
|
||||||
// Deprecated: Do not implement.
|
|
||||||
type Merger interface {
|
|
||||||
// Merge merges the contents of src into the receiver message.
|
|
||||||
// It clones all data structures in src such that it aliases no mutable
|
|
||||||
// memory referenced by src.
|
|
||||||
Merge(src Message)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RequiredNotSetError is an error type returned when
|
|
||||||
// marshaling or unmarshaling a message with missing required fields.
|
|
||||||
type RequiredNotSetError struct {
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *RequiredNotSetError) Error() string {
|
|
||||||
if e.err != nil {
|
|
||||||
return e.err.Error()
|
|
||||||
}
|
|
||||||
return "proto: required field not set"
|
|
||||||
}
|
|
||||||
func (e *RequiredNotSetError) RequiredNotSet() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkRequiredNotSet(m protoV2.Message) error {
|
|
||||||
if err := protoV2.CheckInitialized(m); err != nil {
|
|
||||||
return &RequiredNotSetError{err: err}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clone returns a deep copy of src.
|
|
||||||
func Clone(src Message) Message {
|
|
||||||
return MessageV1(protoV2.Clone(MessageV2(src)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Merge merges src into dst, which must be messages of the same type.
|
|
||||||
//
|
|
||||||
// Populated scalar fields in src are copied to dst, while populated
|
|
||||||
// singular messages in src are merged into dst by recursively calling Merge.
|
|
||||||
// The elements of every list field in src is appended to the corresponded
|
|
||||||
// list fields in dst. The entries of every map field in src is copied into
|
|
||||||
// the corresponding map field in dst, possibly replacing existing entries.
|
|
||||||
// The unknown fields of src are appended to the unknown fields of dst.
|
|
||||||
func Merge(dst, src Message) {
|
|
||||||
protoV2.Merge(MessageV2(dst), MessageV2(src))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equal reports whether two messages are equal.
|
|
||||||
// If two messages marshal to the same bytes under deterministic serialization,
|
|
||||||
// then Equal is guaranteed to report true.
|
|
||||||
//
|
|
||||||
// Two messages are equal if they are the same protobuf message type,
|
|
||||||
// have the same set of populated known and extension field values,
|
|
||||||
// and the same set of unknown fields values.
|
|
||||||
//
|
|
||||||
// Scalar values are compared with the equivalent of the == operator in Go,
|
|
||||||
// except bytes values which are compared using bytes.Equal and
|
|
||||||
// floating point values which specially treat NaNs as equal.
|
|
||||||
// Message values are compared by recursively calling Equal.
|
|
||||||
// Lists are equal if each element value is also equal.
|
|
||||||
// Maps are equal if they have the same set of keys, where the pair of values
|
|
||||||
// for each key is also equal.
|
|
||||||
func Equal(x, y Message) bool {
|
|
||||||
return protoV2.Equal(MessageV2(x), MessageV2(y))
|
|
||||||
}
|
|
||||||
|
|
||||||
func isMessageSet(md protoreflect.MessageDescriptor) bool {
|
|
||||||
ms, ok := md.(interface{ IsMessageSet() bool })
|
|
||||||
return ok && ms.IsMessageSet()
|
|
||||||
}
|
|
317
vendor/github.com/golang/protobuf/proto/registry.go
generated
vendored
317
vendor/github.com/golang/protobuf/proto/registry.go
generated
vendored
@ -1,317 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"compress/gzip"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"google.golang.org/protobuf/reflect/protodesc"
|
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
"google.golang.org/protobuf/reflect/protoregistry"
|
|
||||||
"google.golang.org/protobuf/runtime/protoimpl"
|
|
||||||
)
|
|
||||||
|
|
||||||
// filePath is the path to the proto source file.
|
|
||||||
type filePath = string // e.g., "google/protobuf/descriptor.proto"
|
|
||||||
|
|
||||||
// fileDescGZIP is the compressed contents of the encoded FileDescriptorProto.
|
|
||||||
type fileDescGZIP = []byte
|
|
||||||
|
|
||||||
var fileCache sync.Map // map[filePath]fileDescGZIP
|
|
||||||
|
|
||||||
// RegisterFile is called from generated code to register the compressed
|
|
||||||
// FileDescriptorProto with the file path for a proto source file.
|
|
||||||
//
|
|
||||||
// Deprecated: Use protoregistry.GlobalFiles.RegisterFile instead.
|
|
||||||
func RegisterFile(s filePath, d fileDescGZIP) {
|
|
||||||
// Decompress the descriptor.
|
|
||||||
zr, err := gzip.NewReader(bytes.NewReader(d))
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("proto: invalid compressed file descriptor: %v", err))
|
|
||||||
}
|
|
||||||
b, err := ioutil.ReadAll(zr)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("proto: invalid compressed file descriptor: %v", err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct a protoreflect.FileDescriptor from the raw descriptor.
|
|
||||||
// Note that DescBuilder.Build automatically registers the constructed
|
|
||||||
// file descriptor with the v2 registry.
|
|
||||||
protoimpl.DescBuilder{RawDescriptor: b}.Build()
|
|
||||||
|
|
||||||
// Locally cache the raw descriptor form for the file.
|
|
||||||
fileCache.Store(s, d)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileDescriptor returns the compressed FileDescriptorProto given the file path
|
|
||||||
// for a proto source file. It returns nil if not found.
|
|
||||||
//
|
|
||||||
// Deprecated: Use protoregistry.GlobalFiles.FindFileByPath instead.
|
|
||||||
func FileDescriptor(s filePath) fileDescGZIP {
|
|
||||||
if v, ok := fileCache.Load(s); ok {
|
|
||||||
return v.(fileDescGZIP)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the descriptor in the v2 registry.
|
|
||||||
var b []byte
|
|
||||||
if fd, _ := protoregistry.GlobalFiles.FindFileByPath(s); fd != nil {
|
|
||||||
b, _ = Marshal(protodesc.ToFileDescriptorProto(fd))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Locally cache the raw descriptor form for the file.
|
|
||||||
if len(b) > 0 {
|
|
||||||
v, _ := fileCache.LoadOrStore(s, protoimpl.X.CompressGZIP(b))
|
|
||||||
return v.(fileDescGZIP)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// enumName is the name of an enum. For historical reasons, the enum name is
|
|
||||||
// neither the full Go name nor the full protobuf name of the enum.
|
|
||||||
// The name is the dot-separated combination of just the proto package that the
|
|
||||||
// enum is declared within followed by the Go type name of the generated enum.
|
|
||||||
type enumName = string // e.g., "my.proto.package.GoMessage_GoEnum"
|
|
||||||
|
|
||||||
// enumsByName maps enum values by name to their numeric counterpart.
|
|
||||||
type enumsByName = map[string]int32
|
|
||||||
|
|
||||||
// enumsByNumber maps enum values by number to their name counterpart.
|
|
||||||
type enumsByNumber = map[int32]string
|
|
||||||
|
|
||||||
var enumCache sync.Map // map[enumName]enumsByName
|
|
||||||
var numFilesCache sync.Map // map[protoreflect.FullName]int
|
|
||||||
|
|
||||||
// RegisterEnum is called from the generated code to register the mapping of
|
|
||||||
// enum value names to enum numbers for the enum identified by s.
|
|
||||||
//
|
|
||||||
// Deprecated: Use protoregistry.GlobalTypes.RegisterEnum instead.
|
|
||||||
func RegisterEnum(s enumName, _ enumsByNumber, m enumsByName) {
|
|
||||||
if _, ok := enumCache.Load(s); ok {
|
|
||||||
panic("proto: duplicate enum registered: " + s)
|
|
||||||
}
|
|
||||||
enumCache.Store(s, m)
|
|
||||||
|
|
||||||
// This does not forward registration to the v2 registry since this API
|
|
||||||
// lacks sufficient information to construct a complete v2 enum descriptor.
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnumValueMap returns the mapping from enum value names to enum numbers for
|
|
||||||
// the enum of the given name. It returns nil if not found.
|
|
||||||
//
|
|
||||||
// Deprecated: Use protoregistry.GlobalTypes.FindEnumByName instead.
|
|
||||||
func EnumValueMap(s enumName) enumsByName {
|
|
||||||
if v, ok := enumCache.Load(s); ok {
|
|
||||||
return v.(enumsByName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether the cache is stale. If the number of files in the current
|
|
||||||
// package differs, then it means that some enums may have been recently
|
|
||||||
// registered upstream that we do not know about.
|
|
||||||
var protoPkg protoreflect.FullName
|
|
||||||
if i := strings.LastIndexByte(s, '.'); i >= 0 {
|
|
||||||
protoPkg = protoreflect.FullName(s[:i])
|
|
||||||
}
|
|
||||||
v, _ := numFilesCache.Load(protoPkg)
|
|
||||||
numFiles, _ := v.(int)
|
|
||||||
if protoregistry.GlobalFiles.NumFilesByPackage(protoPkg) == numFiles {
|
|
||||||
return nil // cache is up-to-date; was not found earlier
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the enum cache for all enums declared in the given proto package.
|
|
||||||
numFiles = 0
|
|
||||||
protoregistry.GlobalFiles.RangeFilesByPackage(protoPkg, func(fd protoreflect.FileDescriptor) bool {
|
|
||||||
walkEnums(fd, func(ed protoreflect.EnumDescriptor) {
|
|
||||||
name := protoimpl.X.LegacyEnumName(ed)
|
|
||||||
if _, ok := enumCache.Load(name); !ok {
|
|
||||||
m := make(enumsByName)
|
|
||||||
evs := ed.Values()
|
|
||||||
for i := evs.Len() - 1; i >= 0; i-- {
|
|
||||||
ev := evs.Get(i)
|
|
||||||
m[string(ev.Name())] = int32(ev.Number())
|
|
||||||
}
|
|
||||||
enumCache.LoadOrStore(name, m)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
numFiles++
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
numFilesCache.Store(protoPkg, numFiles)
|
|
||||||
|
|
||||||
// Check cache again for enum map.
|
|
||||||
if v, ok := enumCache.Load(s); ok {
|
|
||||||
return v.(enumsByName)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// walkEnums recursively walks all enums declared in d.
|
|
||||||
func walkEnums(d interface {
|
|
||||||
Enums() protoreflect.EnumDescriptors
|
|
||||||
Messages() protoreflect.MessageDescriptors
|
|
||||||
}, f func(protoreflect.EnumDescriptor)) {
|
|
||||||
eds := d.Enums()
|
|
||||||
for i := eds.Len() - 1; i >= 0; i-- {
|
|
||||||
f(eds.Get(i))
|
|
||||||
}
|
|
||||||
mds := d.Messages()
|
|
||||||
for i := mds.Len() - 1; i >= 0; i-- {
|
|
||||||
walkEnums(mds.Get(i), f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// messageName is the full name of protobuf message.
|
|
||||||
type messageName = string
|
|
||||||
|
|
||||||
var messageTypeCache sync.Map // map[messageName]reflect.Type
|
|
||||||
|
|
||||||
// RegisterType is called from generated code to register the message Go type
|
|
||||||
// for a message of the given name.
|
|
||||||
//
|
|
||||||
// Deprecated: Use protoregistry.GlobalTypes.RegisterMessage instead.
|
|
||||||
func RegisterType(m Message, s messageName) {
|
|
||||||
mt := protoimpl.X.LegacyMessageTypeOf(m, protoreflect.FullName(s))
|
|
||||||
if err := protoregistry.GlobalTypes.RegisterMessage(mt); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
messageTypeCache.Store(s, reflect.TypeOf(m))
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterMapType is called from generated code to register the Go map type
|
|
||||||
// for a protobuf message representing a map entry.
|
|
||||||
//
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func RegisterMapType(m interface{}, s messageName) {
|
|
||||||
t := reflect.TypeOf(m)
|
|
||||||
if t.Kind() != reflect.Map {
|
|
||||||
panic(fmt.Sprintf("invalid map kind: %v", t))
|
|
||||||
}
|
|
||||||
if _, ok := messageTypeCache.Load(s); ok {
|
|
||||||
panic(fmt.Errorf("proto: duplicate proto message registered: %s", s))
|
|
||||||
}
|
|
||||||
messageTypeCache.Store(s, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MessageType returns the message type for a named message.
|
|
||||||
// It returns nil if not found.
|
|
||||||
//
|
|
||||||
// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead.
|
|
||||||
func MessageType(s messageName) reflect.Type {
|
|
||||||
if v, ok := messageTypeCache.Load(s); ok {
|
|
||||||
return v.(reflect.Type)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Derive the message type from the v2 registry.
|
|
||||||
var t reflect.Type
|
|
||||||
if mt, _ := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(s)); mt != nil {
|
|
||||||
t = messageGoType(mt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we could not get a concrete type, it is possible that it is a
|
|
||||||
// pseudo-message for a map entry.
|
|
||||||
if t == nil {
|
|
||||||
d, _ := protoregistry.GlobalFiles.FindDescriptorByName(protoreflect.FullName(s))
|
|
||||||
if md, _ := d.(protoreflect.MessageDescriptor); md != nil && md.IsMapEntry() {
|
|
||||||
kt := goTypeForField(md.Fields().ByNumber(1))
|
|
||||||
vt := goTypeForField(md.Fields().ByNumber(2))
|
|
||||||
t = reflect.MapOf(kt, vt)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Locally cache the message type for the given name.
|
|
||||||
if t != nil {
|
|
||||||
v, _ := messageTypeCache.LoadOrStore(s, t)
|
|
||||||
return v.(reflect.Type)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func goTypeForField(fd protoreflect.FieldDescriptor) reflect.Type {
|
|
||||||
switch k := fd.Kind(); k {
|
|
||||||
case protoreflect.EnumKind:
|
|
||||||
if et, _ := protoregistry.GlobalTypes.FindEnumByName(fd.Enum().FullName()); et != nil {
|
|
||||||
return enumGoType(et)
|
|
||||||
}
|
|
||||||
return reflect.TypeOf(protoreflect.EnumNumber(0))
|
|
||||||
case protoreflect.MessageKind, protoreflect.GroupKind:
|
|
||||||
if mt, _ := protoregistry.GlobalTypes.FindMessageByName(fd.Message().FullName()); mt != nil {
|
|
||||||
return messageGoType(mt)
|
|
||||||
}
|
|
||||||
return reflect.TypeOf((*protoreflect.Message)(nil)).Elem()
|
|
||||||
default:
|
|
||||||
return reflect.TypeOf(fd.Default().Interface())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func enumGoType(et protoreflect.EnumType) reflect.Type {
|
|
||||||
return reflect.TypeOf(et.New(0))
|
|
||||||
}
|
|
||||||
|
|
||||||
func messageGoType(mt protoreflect.MessageType) reflect.Type {
|
|
||||||
return reflect.TypeOf(MessageV1(mt.Zero().Interface()))
|
|
||||||
}
|
|
||||||
|
|
||||||
// MessageName returns the full protobuf name for the given message type.
|
|
||||||
//
|
|
||||||
// Deprecated: Use protoreflect.MessageDescriptor.FullName instead.
|
|
||||||
func MessageName(m Message) messageName {
|
|
||||||
if m == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
if m, ok := m.(interface{ XXX_MessageName() messageName }); ok {
|
|
||||||
return m.XXX_MessageName()
|
|
||||||
}
|
|
||||||
return messageName(protoimpl.X.MessageDescriptorOf(m).FullName())
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterExtension is called from the generated code to register
|
|
||||||
// the extension descriptor.
|
|
||||||
//
|
|
||||||
// Deprecated: Use protoregistry.GlobalTypes.RegisterExtension instead.
|
|
||||||
func RegisterExtension(d *ExtensionDesc) {
|
|
||||||
if err := protoregistry.GlobalTypes.RegisterExtension(d); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type extensionsByNumber = map[int32]*ExtensionDesc
|
|
||||||
|
|
||||||
var extensionCache sync.Map // map[messageName]extensionsByNumber
|
|
||||||
|
|
||||||
// RegisteredExtensions returns a map of the registered extensions for the
|
|
||||||
// provided protobuf message, indexed by the extension field number.
|
|
||||||
//
|
|
||||||
// Deprecated: Use protoregistry.GlobalTypes.RangeExtensionsByMessage instead.
|
|
||||||
func RegisteredExtensions(m Message) extensionsByNumber {
|
|
||||||
// Check whether the cache is stale. If the number of extensions for
|
|
||||||
// the given message differs, then it means that some extensions were
|
|
||||||
// recently registered upstream that we do not know about.
|
|
||||||
s := MessageName(m)
|
|
||||||
v, _ := extensionCache.Load(s)
|
|
||||||
xs, _ := v.(extensionsByNumber)
|
|
||||||
if protoregistry.GlobalTypes.NumExtensionsByMessage(protoreflect.FullName(s)) == len(xs) {
|
|
||||||
return xs // cache is up-to-date
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache is stale, re-compute the extensions map.
|
|
||||||
xs = make(extensionsByNumber)
|
|
||||||
protoregistry.GlobalTypes.RangeExtensionsByMessage(protoreflect.FullName(s), func(xt protoreflect.ExtensionType) bool {
|
|
||||||
if xd, ok := xt.(*ExtensionDesc); ok {
|
|
||||||
xs[int32(xt.TypeDescriptor().Number())] = xd
|
|
||||||
} else {
|
|
||||||
// TODO: This implies that the protoreflect.ExtensionType is a
|
|
||||||
// custom type not generated by protoc-gen-go. We could try and
|
|
||||||
// convert the type to an ExtensionDesc.
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
extensionCache.Store(s, xs)
|
|
||||||
return xs
|
|
||||||
}
|
|
801
vendor/github.com/golang/protobuf/proto/text_decode.go
generated
vendored
801
vendor/github.com/golang/protobuf/proto/text_decode.go
generated
vendored
@ -1,801 +0,0 @@
|
|||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"unicode/utf8"
|
|
||||||
|
|
||||||
"google.golang.org/protobuf/encoding/prototext"
|
|
||||||
protoV2 "google.golang.org/protobuf/proto"
|
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
"google.golang.org/protobuf/reflect/protoregistry"
|
|
||||||
)
|
|
||||||
|
|
||||||
const wrapTextUnmarshalV2 = false
|
|
||||||
|
|
||||||
// ParseError is returned by UnmarshalText.
|
|
||||||
type ParseError struct {
|
|
||||||
Message string
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
Line, Offset int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *ParseError) Error() string {
|
|
||||||
if wrapTextUnmarshalV2 {
|
|
||||||
return e.Message
|
|
||||||
}
|
|
||||||
if e.Line == 1 {
|
|
||||||
return fmt.Sprintf("line 1.%d: %v", e.Offset, e.Message)
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("line %d: %v", e.Line, e.Message)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalText parses a proto text formatted string into m.
|
|
||||||
func UnmarshalText(s string, m Message) error {
|
|
||||||
if u, ok := m.(encoding.TextUnmarshaler); ok {
|
|
||||||
return u.UnmarshalText([]byte(s))
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Reset()
|
|
||||||
mi := MessageV2(m)
|
|
||||||
|
|
||||||
if wrapTextUnmarshalV2 {
|
|
||||||
err := prototext.UnmarshalOptions{
|
|
||||||
AllowPartial: true,
|
|
||||||
}.Unmarshal([]byte(s), mi)
|
|
||||||
if err != nil {
|
|
||||||
return &ParseError{Message: err.Error()}
|
|
||||||
}
|
|
||||||
return checkRequiredNotSet(mi)
|
|
||||||
} else {
|
|
||||||
if err := newTextParser(s).unmarshalMessage(mi.ProtoReflect(), ""); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return checkRequiredNotSet(mi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type textParser struct {
|
|
||||||
s string // remaining input
|
|
||||||
done bool // whether the parsing is finished (success or error)
|
|
||||||
backed bool // whether back() was called
|
|
||||||
offset, line int
|
|
||||||
cur token
|
|
||||||
}
|
|
||||||
|
|
||||||
type token struct {
|
|
||||||
value string
|
|
||||||
err *ParseError
|
|
||||||
line int // line number
|
|
||||||
offset int // byte number from start of input, not start of line
|
|
||||||
unquoted string // the unquoted version of value, if it was a quoted string
|
|
||||||
}
|
|
||||||
|
|
||||||
func newTextParser(s string) *textParser {
|
|
||||||
p := new(textParser)
|
|
||||||
p.s = s
|
|
||||||
p.line = 1
|
|
||||||
p.cur.line = 1
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *textParser) unmarshalMessage(m protoreflect.Message, terminator string) (err error) {
|
|
||||||
md := m.Descriptor()
|
|
||||||
fds := md.Fields()
|
|
||||||
|
|
||||||
// A struct is a sequence of "name: value", terminated by one of
|
|
||||||
// '>' or '}', or the end of the input. A name may also be
|
|
||||||
// "[extension]" or "[type/url]".
|
|
||||||
//
|
|
||||||
// The whole struct can also be an expanded Any message, like:
|
|
||||||
// [type/url] < ... struct contents ... >
|
|
||||||
seen := make(map[protoreflect.FieldNumber]bool)
|
|
||||||
for {
|
|
||||||
tok := p.next()
|
|
||||||
if tok.err != nil {
|
|
||||||
return tok.err
|
|
||||||
}
|
|
||||||
if tok.value == terminator {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if tok.value == "[" {
|
|
||||||
if err := p.unmarshalExtensionOrAny(m, seen); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a normal, non-extension field.
|
|
||||||
name := protoreflect.Name(tok.value)
|
|
||||||
fd := fds.ByName(name)
|
|
||||||
switch {
|
|
||||||
case fd == nil:
|
|
||||||
gd := fds.ByName(protoreflect.Name(strings.ToLower(string(name))))
|
|
||||||
if gd != nil && gd.Kind() == protoreflect.GroupKind && gd.Message().Name() == name {
|
|
||||||
fd = gd
|
|
||||||
}
|
|
||||||
case fd.Kind() == protoreflect.GroupKind && fd.Message().Name() != name:
|
|
||||||
fd = nil
|
|
||||||
case fd.IsWeak() && fd.Message().IsPlaceholder():
|
|
||||||
fd = nil
|
|
||||||
}
|
|
||||||
if fd == nil {
|
|
||||||
typeName := string(md.FullName())
|
|
||||||
if m, ok := m.Interface().(Message); ok {
|
|
||||||
t := reflect.TypeOf(m)
|
|
||||||
if t.Kind() == reflect.Ptr {
|
|
||||||
typeName = t.Elem().String()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return p.errorf("unknown field name %q in %v", name, typeName)
|
|
||||||
}
|
|
||||||
if od := fd.ContainingOneof(); od != nil && m.WhichOneof(od) != nil {
|
|
||||||
return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, od.Name())
|
|
||||||
}
|
|
||||||
if fd.Cardinality() != protoreflect.Repeated && seen[fd.Number()] {
|
|
||||||
return p.errorf("non-repeated field %q was repeated", fd.Name())
|
|
||||||
}
|
|
||||||
seen[fd.Number()] = true
|
|
||||||
|
|
||||||
// Consume any colon.
|
|
||||||
if err := p.checkForColon(fd); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse into the field.
|
|
||||||
v := m.Get(fd)
|
|
||||||
if !m.Has(fd) && (fd.IsList() || fd.IsMap() || fd.Message() != nil) {
|
|
||||||
v = m.Mutable(fd)
|
|
||||||
}
|
|
||||||
if v, err = p.unmarshalValue(v, fd); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
m.Set(fd, v)
|
|
||||||
|
|
||||||
if err := p.consumeOptionalSeparator(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *textParser) unmarshalExtensionOrAny(m protoreflect.Message, seen map[protoreflect.FieldNumber]bool) error {
|
|
||||||
name, err := p.consumeExtensionOrAnyName()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If it contains a slash, it's an Any type URL.
|
|
||||||
if slashIdx := strings.LastIndex(name, "/"); slashIdx >= 0 {
|
|
||||||
tok := p.next()
|
|
||||||
if tok.err != nil {
|
|
||||||
return tok.err
|
|
||||||
}
|
|
||||||
// consume an optional colon
|
|
||||||
if tok.value == ":" {
|
|
||||||
tok = p.next()
|
|
||||||
if tok.err != nil {
|
|
||||||
return tok.err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var terminator string
|
|
||||||
switch tok.value {
|
|
||||||
case "<":
|
|
||||||
terminator = ">"
|
|
||||||
case "{":
|
|
||||||
terminator = "}"
|
|
||||||
default:
|
|
||||||
return p.errorf("expected '{' or '<', found %q", tok.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
mt, err := protoregistry.GlobalTypes.FindMessageByURL(name)
|
|
||||||
if err != nil {
|
|
||||||
return p.errorf("unrecognized message %q in google.protobuf.Any", name[slashIdx+len("/"):])
|
|
||||||
}
|
|
||||||
m2 := mt.New()
|
|
||||||
if err := p.unmarshalMessage(m2, terminator); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b, err := protoV2.Marshal(m2.Interface())
|
|
||||||
if err != nil {
|
|
||||||
return p.errorf("failed to marshal message of type %q: %v", name[slashIdx+len("/"):], err)
|
|
||||||
}
|
|
||||||
|
|
||||||
urlFD := m.Descriptor().Fields().ByName("type_url")
|
|
||||||
valFD := m.Descriptor().Fields().ByName("value")
|
|
||||||
if seen[urlFD.Number()] {
|
|
||||||
return p.errorf("Any message unpacked multiple times, or %q already set", urlFD.Name())
|
|
||||||
}
|
|
||||||
if seen[valFD.Number()] {
|
|
||||||
return p.errorf("Any message unpacked multiple times, or %q already set", valFD.Name())
|
|
||||||
}
|
|
||||||
m.Set(urlFD, protoreflect.ValueOfString(name))
|
|
||||||
m.Set(valFD, protoreflect.ValueOfBytes(b))
|
|
||||||
seen[urlFD.Number()] = true
|
|
||||||
seen[valFD.Number()] = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
xname := protoreflect.FullName(name)
|
|
||||||
xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname)
|
|
||||||
if xt == nil && isMessageSet(m.Descriptor()) {
|
|
||||||
xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension"))
|
|
||||||
}
|
|
||||||
if xt == nil {
|
|
||||||
return p.errorf("unrecognized extension %q", name)
|
|
||||||
}
|
|
||||||
fd := xt.TypeDescriptor()
|
|
||||||
if fd.ContainingMessage().FullName() != m.Descriptor().FullName() {
|
|
||||||
return p.errorf("extension field %q does not extend message %q", name, m.Descriptor().FullName())
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := p.checkForColon(fd); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
v := m.Get(fd)
|
|
||||||
if !m.Has(fd) && (fd.IsList() || fd.IsMap() || fd.Message() != nil) {
|
|
||||||
v = m.Mutable(fd)
|
|
||||||
}
|
|
||||||
v, err = p.unmarshalValue(v, fd)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
m.Set(fd, v)
|
|
||||||
return p.consumeOptionalSeparator()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *textParser) unmarshalValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
|
|
||||||
tok := p.next()
|
|
||||||
if tok.err != nil {
|
|
||||||
return v, tok.err
|
|
||||||
}
|
|
||||||
if tok.value == "" {
|
|
||||||
return v, p.errorf("unexpected EOF")
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case fd.IsList():
|
|
||||||
lv := v.List()
|
|
||||||
var err error
|
|
||||||
if tok.value == "[" {
|
|
||||||
// Repeated field with list notation, like [1,2,3].
|
|
||||||
for {
|
|
||||||
vv := lv.NewElement()
|
|
||||||
vv, err = p.unmarshalSingularValue(vv, fd)
|
|
||||||
if err != nil {
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
lv.Append(vv)
|
|
||||||
|
|
||||||
tok := p.next()
|
|
||||||
if tok.err != nil {
|
|
||||||
return v, tok.err
|
|
||||||
}
|
|
||||||
if tok.value == "]" {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if tok.value != "," {
|
|
||||||
return v, p.errorf("Expected ']' or ',' found %q", tok.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// One value of the repeated field.
|
|
||||||
p.back()
|
|
||||||
vv := lv.NewElement()
|
|
||||||
vv, err = p.unmarshalSingularValue(vv, fd)
|
|
||||||
if err != nil {
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
lv.Append(vv)
|
|
||||||
return v, nil
|
|
||||||
case fd.IsMap():
|
|
||||||
// The map entry should be this sequence of tokens:
|
|
||||||
// < key : KEY value : VALUE >
|
|
||||||
// However, implementations may omit key or value, and technically
|
|
||||||
// we should support them in any order.
|
|
||||||
var terminator string
|
|
||||||
switch tok.value {
|
|
||||||
case "<":
|
|
||||||
terminator = ">"
|
|
||||||
case "{":
|
|
||||||
terminator = "}"
|
|
||||||
default:
|
|
||||||
return v, p.errorf("expected '{' or '<', found %q", tok.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
keyFD := fd.MapKey()
|
|
||||||
valFD := fd.MapValue()
|
|
||||||
|
|
||||||
mv := v.Map()
|
|
||||||
kv := keyFD.Default()
|
|
||||||
vv := mv.NewValue()
|
|
||||||
for {
|
|
||||||
tok := p.next()
|
|
||||||
if tok.err != nil {
|
|
||||||
return v, tok.err
|
|
||||||
}
|
|
||||||
if tok.value == terminator {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
switch tok.value {
|
|
||||||
case "key":
|
|
||||||
if err := p.consumeToken(":"); err != nil {
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
if kv, err = p.unmarshalSingularValue(kv, keyFD); err != nil {
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
if err := p.consumeOptionalSeparator(); err != nil {
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
case "value":
|
|
||||||
if err := p.checkForColon(valFD); err != nil {
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
if vv, err = p.unmarshalSingularValue(vv, valFD); err != nil {
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
if err := p.consumeOptionalSeparator(); err != nil {
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
p.back()
|
|
||||||
return v, p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mv.Set(kv.MapKey(), vv)
|
|
||||||
return v, nil
|
|
||||||
default:
|
|
||||||
p.back()
|
|
||||||
return p.unmarshalSingularValue(v, fd)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *textParser) unmarshalSingularValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {
|
|
||||||
tok := p.next()
|
|
||||||
if tok.err != nil {
|
|
||||||
return v, tok.err
|
|
||||||
}
|
|
||||||
if tok.value == "" {
|
|
||||||
return v, p.errorf("unexpected EOF")
|
|
||||||
}
|
|
||||||
|
|
||||||
switch fd.Kind() {
|
|
||||||
case protoreflect.BoolKind:
|
|
||||||
switch tok.value {
|
|
||||||
case "true", "1", "t", "True":
|
|
||||||
return protoreflect.ValueOfBool(true), nil
|
|
||||||
case "false", "0", "f", "False":
|
|
||||||
return protoreflect.ValueOfBool(false), nil
|
|
||||||
}
|
|
||||||
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
|
|
||||||
if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil {
|
|
||||||
return protoreflect.ValueOfInt32(int32(x)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// The C++ parser accepts large positive hex numbers that uses
|
|
||||||
// two's complement arithmetic to represent negative numbers.
|
|
||||||
// This feature is here for backwards compatibility with C++.
|
|
||||||
if strings.HasPrefix(tok.value, "0x") {
|
|
||||||
if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {
|
|
||||||
return protoreflect.ValueOfInt32(int32(-(int64(^x) + 1))), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
|
|
||||||
if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil {
|
|
||||||
return protoreflect.ValueOfInt64(int64(x)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// The C++ parser accepts large positive hex numbers that uses
|
|
||||||
// two's complement arithmetic to represent negative numbers.
|
|
||||||
// This feature is here for backwards compatibility with C++.
|
|
||||||
if strings.HasPrefix(tok.value, "0x") {
|
|
||||||
if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil {
|
|
||||||
return protoreflect.ValueOfInt64(int64(-(int64(^x) + 1))), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
|
|
||||||
if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {
|
|
||||||
return protoreflect.ValueOfUint32(uint32(x)), nil
|
|
||||||
}
|
|
||||||
case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
|
|
||||||
if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil {
|
|
||||||
return protoreflect.ValueOfUint64(uint64(x)), nil
|
|
||||||
}
|
|
||||||
case protoreflect.FloatKind:
|
|
||||||
// Ignore 'f' for compatibility with output generated by C++,
|
|
||||||
// but don't remove 'f' when the value is "-inf" or "inf".
|
|
||||||
v := tok.value
|
|
||||||
if strings.HasSuffix(v, "f") && v != "-inf" && v != "inf" {
|
|
||||||
v = v[:len(v)-len("f")]
|
|
||||||
}
|
|
||||||
if x, err := strconv.ParseFloat(v, 32); err == nil {
|
|
||||||
return protoreflect.ValueOfFloat32(float32(x)), nil
|
|
||||||
}
|
|
||||||
case protoreflect.DoubleKind:
|
|
||||||
// Ignore 'f' for compatibility with output generated by C++,
|
|
||||||
// but don't remove 'f' when the value is "-inf" or "inf".
|
|
||||||
v := tok.value
|
|
||||||
if strings.HasSuffix(v, "f") && v != "-inf" && v != "inf" {
|
|
||||||
v = v[:len(v)-len("f")]
|
|
||||||
}
|
|
||||||
if x, err := strconv.ParseFloat(v, 64); err == nil {
|
|
||||||
return protoreflect.ValueOfFloat64(float64(x)), nil
|
|
||||||
}
|
|
||||||
case protoreflect.StringKind:
|
|
||||||
if isQuote(tok.value[0]) {
|
|
||||||
return protoreflect.ValueOfString(tok.unquoted), nil
|
|
||||||
}
|
|
||||||
case protoreflect.BytesKind:
|
|
||||||
if isQuote(tok.value[0]) {
|
|
||||||
return protoreflect.ValueOfBytes([]byte(tok.unquoted)), nil
|
|
||||||
}
|
|
||||||
case protoreflect.EnumKind:
|
|
||||||
if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil {
|
|
||||||
return protoreflect.ValueOfEnum(protoreflect.EnumNumber(x)), nil
|
|
||||||
}
|
|
||||||
vd := fd.Enum().Values().ByName(protoreflect.Name(tok.value))
|
|
||||||
if vd != nil {
|
|
||||||
return protoreflect.ValueOfEnum(vd.Number()), nil
|
|
||||||
}
|
|
||||||
case protoreflect.MessageKind, protoreflect.GroupKind:
|
|
||||||
var terminator string
|
|
||||||
switch tok.value {
|
|
||||||
case "{":
|
|
||||||
terminator = "}"
|
|
||||||
case "<":
|
|
||||||
terminator = ">"
|
|
||||||
default:
|
|
||||||
return v, p.errorf("expected '{' or '<', found %q", tok.value)
|
|
||||||
}
|
|
||||||
err := p.unmarshalMessage(v.Message(), terminator)
|
|
||||||
return v, err
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("invalid kind %v", fd.Kind()))
|
|
||||||
}
|
|
||||||
return v, p.errorf("invalid %v: %v", fd.Kind(), tok.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Consume a ':' from the input stream (if the next token is a colon),
|
|
||||||
// returning an error if a colon is needed but not present.
|
|
||||||
func (p *textParser) checkForColon(fd protoreflect.FieldDescriptor) *ParseError {
|
|
||||||
tok := p.next()
|
|
||||||
if tok.err != nil {
|
|
||||||
return tok.err
|
|
||||||
}
|
|
||||||
if tok.value != ":" {
|
|
||||||
if fd.Message() == nil {
|
|
||||||
return p.errorf("expected ':', found %q", tok.value)
|
|
||||||
}
|
|
||||||
p.back()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// consumeExtensionOrAnyName consumes an extension name or an Any type URL and
|
|
||||||
// the following ']'. It returns the name or URL consumed.
|
|
||||||
func (p *textParser) consumeExtensionOrAnyName() (string, error) {
|
|
||||||
tok := p.next()
|
|
||||||
if tok.err != nil {
|
|
||||||
return "", tok.err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If extension name or type url is quoted, it's a single token.
|
|
||||||
if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] {
|
|
||||||
name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0]))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return name, p.consumeToken("]")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Consume everything up to "]"
|
|
||||||
var parts []string
|
|
||||||
for tok.value != "]" {
|
|
||||||
parts = append(parts, tok.value)
|
|
||||||
tok = p.next()
|
|
||||||
if tok.err != nil {
|
|
||||||
return "", p.errorf("unrecognized type_url or extension name: %s", tok.err)
|
|
||||||
}
|
|
||||||
if p.done && tok.value != "]" {
|
|
||||||
return "", p.errorf("unclosed type_url or extension name")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return strings.Join(parts, ""), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// consumeOptionalSeparator consumes an optional semicolon or comma.
|
|
||||||
// It is used in unmarshalMessage to provide backward compatibility.
|
|
||||||
func (p *textParser) consumeOptionalSeparator() error {
|
|
||||||
tok := p.next()
|
|
||||||
if tok.err != nil {
|
|
||||||
return tok.err
|
|
||||||
}
|
|
||||||
if tok.value != ";" && tok.value != "," {
|
|
||||||
p.back()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *textParser) errorf(format string, a ...interface{}) *ParseError {
|
|
||||||
pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset}
|
|
||||||
p.cur.err = pe
|
|
||||||
p.done = true
|
|
||||||
return pe
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *textParser) skipWhitespace() {
|
|
||||||
i := 0
|
|
||||||
for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') {
|
|
||||||
if p.s[i] == '#' {
|
|
||||||
// comment; skip to end of line or input
|
|
||||||
for i < len(p.s) && p.s[i] != '\n' {
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
if i == len(p.s) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if p.s[i] == '\n' {
|
|
||||||
p.line++
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
p.offset += i
|
|
||||||
p.s = p.s[i:len(p.s)]
|
|
||||||
if len(p.s) == 0 {
|
|
||||||
p.done = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *textParser) advance() {
|
|
||||||
// Skip whitespace
|
|
||||||
p.skipWhitespace()
|
|
||||||
if p.done {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start of non-whitespace
|
|
||||||
p.cur.err = nil
|
|
||||||
p.cur.offset, p.cur.line = p.offset, p.line
|
|
||||||
p.cur.unquoted = ""
|
|
||||||
switch p.s[0] {
|
|
||||||
case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/':
|
|
||||||
// Single symbol
|
|
||||||
p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]
|
|
||||||
case '"', '\'':
|
|
||||||
// Quoted string
|
|
||||||
i := 1
|
|
||||||
for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' {
|
|
||||||
if p.s[i] == '\\' && i+1 < len(p.s) {
|
|
||||||
// skip escaped char
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
if i >= len(p.s) || p.s[i] != p.s[0] {
|
|
||||||
p.errorf("unmatched quote")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
unq, err := unquoteC(p.s[1:i], rune(p.s[0]))
|
|
||||||
if err != nil {
|
|
||||||
p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]
|
|
||||||
p.cur.unquoted = unq
|
|
||||||
default:
|
|
||||||
i := 0
|
|
||||||
for i < len(p.s) && isIdentOrNumberChar(p.s[i]) {
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
if i == 0 {
|
|
||||||
p.errorf("unexpected byte %#x", p.s[0])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)]
|
|
||||||
}
|
|
||||||
p.offset += len(p.cur.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Back off the parser by one token. Can only be done between calls to next().
|
|
||||||
// It makes the next advance() a no-op.
|
|
||||||
func (p *textParser) back() { p.backed = true }
|
|
||||||
|
|
||||||
// Advances the parser and returns the new current token.
|
|
||||||
func (p *textParser) next() *token {
|
|
||||||
if p.backed || p.done {
|
|
||||||
p.backed = false
|
|
||||||
return &p.cur
|
|
||||||
}
|
|
||||||
p.advance()
|
|
||||||
if p.done {
|
|
||||||
p.cur.value = ""
|
|
||||||
} else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) {
|
|
||||||
// Look for multiple quoted strings separated by whitespace,
|
|
||||||
// and concatenate them.
|
|
||||||
cat := p.cur
|
|
||||||
for {
|
|
||||||
p.skipWhitespace()
|
|
||||||
if p.done || !isQuote(p.s[0]) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
p.advance()
|
|
||||||
if p.cur.err != nil {
|
|
||||||
return &p.cur
|
|
||||||
}
|
|
||||||
cat.value += " " + p.cur.value
|
|
||||||
cat.unquoted += p.cur.unquoted
|
|
||||||
}
|
|
||||||
p.done = false // parser may have seen EOF, but we want to return cat
|
|
||||||
p.cur = cat
|
|
||||||
}
|
|
||||||
return &p.cur
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *textParser) consumeToken(s string) error {
|
|
||||||
tok := p.next()
|
|
||||||
if tok.err != nil {
|
|
||||||
return tok.err
|
|
||||||
}
|
|
||||||
if tok.value != s {
|
|
||||||
p.back()
|
|
||||||
return p.errorf("expected %q, found %q", s, tok.value)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var errBadUTF8 = errors.New("proto: bad UTF-8")
|
|
||||||
|
|
||||||
func unquoteC(s string, quote rune) (string, error) {
|
|
||||||
// This is based on C++'s tokenizer.cc.
|
|
||||||
// Despite its name, this is *not* parsing C syntax.
|
|
||||||
// For instance, "\0" is an invalid quoted string.
|
|
||||||
|
|
||||||
// Avoid allocation in trivial cases.
|
|
||||||
simple := true
|
|
||||||
for _, r := range s {
|
|
||||||
if r == '\\' || r == quote {
|
|
||||||
simple = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if simple {
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
buf := make([]byte, 0, 3*len(s)/2)
|
|
||||||
for len(s) > 0 {
|
|
||||||
r, n := utf8.DecodeRuneInString(s)
|
|
||||||
if r == utf8.RuneError && n == 1 {
|
|
||||||
return "", errBadUTF8
|
|
||||||
}
|
|
||||||
s = s[n:]
|
|
||||||
if r != '\\' {
|
|
||||||
if r < utf8.RuneSelf {
|
|
||||||
buf = append(buf, byte(r))
|
|
||||||
} else {
|
|
||||||
buf = append(buf, string(r)...)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
ch, tail, err := unescape(s)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
buf = append(buf, ch...)
|
|
||||||
s = tail
|
|
||||||
}
|
|
||||||
return string(buf), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func unescape(s string) (ch string, tail string, err error) {
|
|
||||||
r, n := utf8.DecodeRuneInString(s)
|
|
||||||
if r == utf8.RuneError && n == 1 {
|
|
||||||
return "", "", errBadUTF8
|
|
||||||
}
|
|
||||||
s = s[n:]
|
|
||||||
switch r {
|
|
||||||
case 'a':
|
|
||||||
return "\a", s, nil
|
|
||||||
case 'b':
|
|
||||||
return "\b", s, nil
|
|
||||||
case 'f':
|
|
||||||
return "\f", s, nil
|
|
||||||
case 'n':
|
|
||||||
return "\n", s, nil
|
|
||||||
case 'r':
|
|
||||||
return "\r", s, nil
|
|
||||||
case 't':
|
|
||||||
return "\t", s, nil
|
|
||||||
case 'v':
|
|
||||||
return "\v", s, nil
|
|
||||||
case '?':
|
|
||||||
return "?", s, nil // trigraph workaround
|
|
||||||
case '\'', '"', '\\':
|
|
||||||
return string(r), s, nil
|
|
||||||
case '0', '1', '2', '3', '4', '5', '6', '7':
|
|
||||||
if len(s) < 2 {
|
|
||||||
return "", "", fmt.Errorf(`\%c requires 2 following digits`, r)
|
|
||||||
}
|
|
||||||
ss := string(r) + s[:2]
|
|
||||||
s = s[2:]
|
|
||||||
i, err := strconv.ParseUint(ss, 8, 8)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", fmt.Errorf(`\%s contains non-octal digits`, ss)
|
|
||||||
}
|
|
||||||
return string([]byte{byte(i)}), s, nil
|
|
||||||
case 'x', 'X', 'u', 'U':
|
|
||||||
var n int
|
|
||||||
switch r {
|
|
||||||
case 'x', 'X':
|
|
||||||
n = 2
|
|
||||||
case 'u':
|
|
||||||
n = 4
|
|
||||||
case 'U':
|
|
||||||
n = 8
|
|
||||||
}
|
|
||||||
if len(s) < n {
|
|
||||||
return "", "", fmt.Errorf(`\%c requires %d following digits`, r, n)
|
|
||||||
}
|
|
||||||
ss := s[:n]
|
|
||||||
s = s[n:]
|
|
||||||
i, err := strconv.ParseUint(ss, 16, 64)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, r, ss)
|
|
||||||
}
|
|
||||||
if r == 'x' || r == 'X' {
|
|
||||||
return string([]byte{byte(i)}), s, nil
|
|
||||||
}
|
|
||||||
if i > utf8.MaxRune {
|
|
||||||
return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss)
|
|
||||||
}
|
|
||||||
return string(rune(i)), s, nil
|
|
||||||
}
|
|
||||||
return "", "", fmt.Errorf(`unknown escape \%c`, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func isIdentOrNumberChar(c byte) bool {
|
|
||||||
switch {
|
|
||||||
case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z':
|
|
||||||
return true
|
|
||||||
case '0' <= c && c <= '9':
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
switch c {
|
|
||||||
case '-', '+', '.', '_':
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func isWhitespace(c byte) bool {
|
|
||||||
switch c {
|
|
||||||
case ' ', '\t', '\n', '\r':
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func isQuote(c byte) bool {
|
|
||||||
switch c {
|
|
||||||
case '"', '\'':
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
560
vendor/github.com/golang/protobuf/proto/text_encode.go
generated
vendored
560
vendor/github.com/golang/protobuf/proto/text_encode.go
generated
vendored
@ -1,560 +0,0 @@
|
|||||||
// Copyright 2010 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"encoding"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"math"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"google.golang.org/protobuf/encoding/prototext"
|
|
||||||
"google.golang.org/protobuf/encoding/protowire"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
"google.golang.org/protobuf/reflect/protoregistry"
|
|
||||||
)
|
|
||||||
|
|
||||||
const wrapTextMarshalV2 = false
|
|
||||||
|
|
||||||
// TextMarshaler is a configurable text format marshaler.
|
|
||||||
type TextMarshaler struct {
|
|
||||||
Compact bool // use compact text format (one line)
|
|
||||||
ExpandAny bool // expand google.protobuf.Any messages of known types
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal writes the proto text format of m to w.
|
|
||||||
func (tm *TextMarshaler) Marshal(w io.Writer, m Message) error {
|
|
||||||
b, err := tm.marshal(m)
|
|
||||||
if len(b) > 0 {
|
|
||||||
if _, err := w.Write(b); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Text returns a proto text formatted string of m.
|
|
||||||
func (tm *TextMarshaler) Text(m Message) string {
|
|
||||||
b, _ := tm.marshal(m)
|
|
||||||
return string(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tm *TextMarshaler) marshal(m Message) ([]byte, error) {
|
|
||||||
mr := MessageReflect(m)
|
|
||||||
if mr == nil || !mr.IsValid() {
|
|
||||||
return []byte("<nil>"), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if wrapTextMarshalV2 {
|
|
||||||
if m, ok := m.(encoding.TextMarshaler); ok {
|
|
||||||
return m.MarshalText()
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := prototext.MarshalOptions{
|
|
||||||
AllowPartial: true,
|
|
||||||
EmitUnknown: true,
|
|
||||||
}
|
|
||||||
if !tm.Compact {
|
|
||||||
opts.Indent = " "
|
|
||||||
}
|
|
||||||
if !tm.ExpandAny {
|
|
||||||
opts.Resolver = (*protoregistry.Types)(nil)
|
|
||||||
}
|
|
||||||
return opts.Marshal(mr.Interface())
|
|
||||||
} else {
|
|
||||||
w := &textWriter{
|
|
||||||
compact: tm.Compact,
|
|
||||||
expandAny: tm.ExpandAny,
|
|
||||||
complete: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
if m, ok := m.(encoding.TextMarshaler); ok {
|
|
||||||
b, err := m.MarshalText()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
w.Write(b)
|
|
||||||
return w.buf, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err := w.writeMessage(mr)
|
|
||||||
return w.buf, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
defaultTextMarshaler = TextMarshaler{}
|
|
||||||
compactTextMarshaler = TextMarshaler{Compact: true}
|
|
||||||
)
|
|
||||||
|
|
||||||
// MarshalText writes the proto text format of m to w.
|
|
||||||
func MarshalText(w io.Writer, m Message) error { return defaultTextMarshaler.Marshal(w, m) }
|
|
||||||
|
|
||||||
// MarshalTextString returns a proto text formatted string of m.
|
|
||||||
func MarshalTextString(m Message) string { return defaultTextMarshaler.Text(m) }
|
|
||||||
|
|
||||||
// CompactText writes the compact proto text format of m to w.
|
|
||||||
func CompactText(w io.Writer, m Message) error { return compactTextMarshaler.Marshal(w, m) }
|
|
||||||
|
|
||||||
// CompactTextString returns a compact proto text formatted string of m.
|
|
||||||
func CompactTextString(m Message) string { return compactTextMarshaler.Text(m) }
|
|
||||||
|
|
||||||
var (
|
|
||||||
newline = []byte("\n")
|
|
||||||
endBraceNewline = []byte("}\n")
|
|
||||||
posInf = []byte("inf")
|
|
||||||
negInf = []byte("-inf")
|
|
||||||
nan = []byte("nan")
|
|
||||||
)
|
|
||||||
|
|
||||||
// textWriter is an io.Writer that tracks its indentation level.
|
|
||||||
type textWriter struct {
|
|
||||||
compact bool // same as TextMarshaler.Compact
|
|
||||||
expandAny bool // same as TextMarshaler.ExpandAny
|
|
||||||
complete bool // whether the current position is a complete line
|
|
||||||
indent int // indentation level; never negative
|
|
||||||
buf []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *textWriter) Write(p []byte) (n int, _ error) {
|
|
||||||
newlines := bytes.Count(p, newline)
|
|
||||||
if newlines == 0 {
|
|
||||||
if !w.compact && w.complete {
|
|
||||||
w.writeIndent()
|
|
||||||
}
|
|
||||||
w.buf = append(w.buf, p...)
|
|
||||||
w.complete = false
|
|
||||||
return len(p), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
frags := bytes.SplitN(p, newline, newlines+1)
|
|
||||||
if w.compact {
|
|
||||||
for i, frag := range frags {
|
|
||||||
if i > 0 {
|
|
||||||
w.buf = append(w.buf, ' ')
|
|
||||||
n++
|
|
||||||
}
|
|
||||||
w.buf = append(w.buf, frag...)
|
|
||||||
n += len(frag)
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, frag := range frags {
|
|
||||||
if w.complete {
|
|
||||||
w.writeIndent()
|
|
||||||
}
|
|
||||||
w.buf = append(w.buf, frag...)
|
|
||||||
n += len(frag)
|
|
||||||
if i+1 < len(frags) {
|
|
||||||
w.buf = append(w.buf, '\n')
|
|
||||||
n++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.complete = len(frags[len(frags)-1]) == 0
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *textWriter) WriteByte(c byte) error {
|
|
||||||
if w.compact && c == '\n' {
|
|
||||||
c = ' '
|
|
||||||
}
|
|
||||||
if !w.compact && w.complete {
|
|
||||||
w.writeIndent()
|
|
||||||
}
|
|
||||||
w.buf = append(w.buf, c)
|
|
||||||
w.complete = c == '\n'
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *textWriter) writeName(fd protoreflect.FieldDescriptor) {
|
|
||||||
if !w.compact && w.complete {
|
|
||||||
w.writeIndent()
|
|
||||||
}
|
|
||||||
w.complete = false
|
|
||||||
|
|
||||||
if fd.Kind() != protoreflect.GroupKind {
|
|
||||||
w.buf = append(w.buf, fd.Name()...)
|
|
||||||
w.WriteByte(':')
|
|
||||||
} else {
|
|
||||||
// Use message type name for group field name.
|
|
||||||
w.buf = append(w.buf, fd.Message().Name()...)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !w.compact {
|
|
||||||
w.WriteByte(' ')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func requiresQuotes(u string) bool {
|
|
||||||
// When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted.
|
|
||||||
for _, ch := range u {
|
|
||||||
switch {
|
|
||||||
case ch == '.' || ch == '/' || ch == '_':
|
|
||||||
continue
|
|
||||||
case '0' <= ch && ch <= '9':
|
|
||||||
continue
|
|
||||||
case 'A' <= ch && ch <= 'Z':
|
|
||||||
continue
|
|
||||||
case 'a' <= ch && ch <= 'z':
|
|
||||||
continue
|
|
||||||
default:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// writeProto3Any writes an expanded google.protobuf.Any message.
|
|
||||||
//
|
|
||||||
// It returns (false, nil) if sv value can't be unmarshaled (e.g. because
|
|
||||||
// required messages are not linked in).
|
|
||||||
//
|
|
||||||
// It returns (true, error) when sv was written in expanded format or an error
|
|
||||||
// was encountered.
|
|
||||||
func (w *textWriter) writeProto3Any(m protoreflect.Message) (bool, error) {
|
|
||||||
md := m.Descriptor()
|
|
||||||
fdURL := md.Fields().ByName("type_url")
|
|
||||||
fdVal := md.Fields().ByName("value")
|
|
||||||
|
|
||||||
url := m.Get(fdURL).String()
|
|
||||||
mt, err := protoregistry.GlobalTypes.FindMessageByURL(url)
|
|
||||||
if err != nil {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
b := m.Get(fdVal).Bytes()
|
|
||||||
m2 := mt.New()
|
|
||||||
if err := proto.Unmarshal(b, m2.Interface()); err != nil {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
w.Write([]byte("["))
|
|
||||||
if requiresQuotes(url) {
|
|
||||||
w.writeQuotedString(url)
|
|
||||||
} else {
|
|
||||||
w.Write([]byte(url))
|
|
||||||
}
|
|
||||||
if w.compact {
|
|
||||||
w.Write([]byte("]:<"))
|
|
||||||
} else {
|
|
||||||
w.Write([]byte("]: <\n"))
|
|
||||||
w.indent++
|
|
||||||
}
|
|
||||||
if err := w.writeMessage(m2); err != nil {
|
|
||||||
return true, err
|
|
||||||
}
|
|
||||||
if w.compact {
|
|
||||||
w.Write([]byte("> "))
|
|
||||||
} else {
|
|
||||||
w.indent--
|
|
||||||
w.Write([]byte(">\n"))
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *textWriter) writeMessage(m protoreflect.Message) error {
|
|
||||||
md := m.Descriptor()
|
|
||||||
if w.expandAny && md.FullName() == "google.protobuf.Any" {
|
|
||||||
if canExpand, err := w.writeProto3Any(m); canExpand {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fds := md.Fields()
|
|
||||||
for i := 0; i < fds.Len(); {
|
|
||||||
fd := fds.Get(i)
|
|
||||||
if od := fd.ContainingOneof(); od != nil {
|
|
||||||
fd = m.WhichOneof(od)
|
|
||||||
i += od.Fields().Len()
|
|
||||||
} else {
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
if fd == nil || !m.Has(fd) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case fd.IsList():
|
|
||||||
lv := m.Get(fd).List()
|
|
||||||
for j := 0; j < lv.Len(); j++ {
|
|
||||||
w.writeName(fd)
|
|
||||||
v := lv.Get(j)
|
|
||||||
if err := w.writeSingularValue(v, fd); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
w.WriteByte('\n')
|
|
||||||
}
|
|
||||||
case fd.IsMap():
|
|
||||||
kfd := fd.MapKey()
|
|
||||||
vfd := fd.MapValue()
|
|
||||||
mv := m.Get(fd).Map()
|
|
||||||
|
|
||||||
type entry struct{ key, val protoreflect.Value }
|
|
||||||
var entries []entry
|
|
||||||
mv.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool {
|
|
||||||
entries = append(entries, entry{k.Value(), v})
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
sort.Slice(entries, func(i, j int) bool {
|
|
||||||
switch kfd.Kind() {
|
|
||||||
case protoreflect.BoolKind:
|
|
||||||
return !entries[i].key.Bool() && entries[j].key.Bool()
|
|
||||||
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
|
|
||||||
return entries[i].key.Int() < entries[j].key.Int()
|
|
||||||
case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
|
|
||||||
return entries[i].key.Uint() < entries[j].key.Uint()
|
|
||||||
case protoreflect.StringKind:
|
|
||||||
return entries[i].key.String() < entries[j].key.String()
|
|
||||||
default:
|
|
||||||
panic("invalid kind")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
for _, entry := range entries {
|
|
||||||
w.writeName(fd)
|
|
||||||
w.WriteByte('<')
|
|
||||||
if !w.compact {
|
|
||||||
w.WriteByte('\n')
|
|
||||||
}
|
|
||||||
w.indent++
|
|
||||||
w.writeName(kfd)
|
|
||||||
if err := w.writeSingularValue(entry.key, kfd); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
w.WriteByte('\n')
|
|
||||||
w.writeName(vfd)
|
|
||||||
if err := w.writeSingularValue(entry.val, vfd); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
w.WriteByte('\n')
|
|
||||||
w.indent--
|
|
||||||
w.WriteByte('>')
|
|
||||||
w.WriteByte('\n')
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
w.writeName(fd)
|
|
||||||
if err := w.writeSingularValue(m.Get(fd), fd); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
w.WriteByte('\n')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if b := m.GetUnknown(); len(b) > 0 {
|
|
||||||
w.writeUnknownFields(b)
|
|
||||||
}
|
|
||||||
return w.writeExtensions(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *textWriter) writeSingularValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) error {
|
|
||||||
switch fd.Kind() {
|
|
||||||
case protoreflect.FloatKind, protoreflect.DoubleKind:
|
|
||||||
switch vf := v.Float(); {
|
|
||||||
case math.IsInf(vf, +1):
|
|
||||||
w.Write(posInf)
|
|
||||||
case math.IsInf(vf, -1):
|
|
||||||
w.Write(negInf)
|
|
||||||
case math.IsNaN(vf):
|
|
||||||
w.Write(nan)
|
|
||||||
default:
|
|
||||||
fmt.Fprint(w, v.Interface())
|
|
||||||
}
|
|
||||||
case protoreflect.StringKind:
|
|
||||||
// NOTE: This does not validate UTF-8 for historical reasons.
|
|
||||||
w.writeQuotedString(string(v.String()))
|
|
||||||
case protoreflect.BytesKind:
|
|
||||||
w.writeQuotedString(string(v.Bytes()))
|
|
||||||
case protoreflect.MessageKind, protoreflect.GroupKind:
|
|
||||||
var bra, ket byte = '<', '>'
|
|
||||||
if fd.Kind() == protoreflect.GroupKind {
|
|
||||||
bra, ket = '{', '}'
|
|
||||||
}
|
|
||||||
w.WriteByte(bra)
|
|
||||||
if !w.compact {
|
|
||||||
w.WriteByte('\n')
|
|
||||||
}
|
|
||||||
w.indent++
|
|
||||||
m := v.Message()
|
|
||||||
if m2, ok := m.Interface().(encoding.TextMarshaler); ok {
|
|
||||||
b, err := m2.MarshalText()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
w.Write(b)
|
|
||||||
} else {
|
|
||||||
w.writeMessage(m)
|
|
||||||
}
|
|
||||||
w.indent--
|
|
||||||
w.WriteByte(ket)
|
|
||||||
case protoreflect.EnumKind:
|
|
||||||
if ev := fd.Enum().Values().ByNumber(v.Enum()); ev != nil {
|
|
||||||
fmt.Fprint(w, ev.Name())
|
|
||||||
} else {
|
|
||||||
fmt.Fprint(w, v.Enum())
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
fmt.Fprint(w, v.Interface())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// writeQuotedString writes a quoted string in the protocol buffer text format.
|
|
||||||
func (w *textWriter) writeQuotedString(s string) {
|
|
||||||
w.WriteByte('"')
|
|
||||||
for i := 0; i < len(s); i++ {
|
|
||||||
switch c := s[i]; c {
|
|
||||||
case '\n':
|
|
||||||
w.buf = append(w.buf, `\n`...)
|
|
||||||
case '\r':
|
|
||||||
w.buf = append(w.buf, `\r`...)
|
|
||||||
case '\t':
|
|
||||||
w.buf = append(w.buf, `\t`...)
|
|
||||||
case '"':
|
|
||||||
w.buf = append(w.buf, `\"`...)
|
|
||||||
case '\\':
|
|
||||||
w.buf = append(w.buf, `\\`...)
|
|
||||||
default:
|
|
||||||
if isPrint := c >= 0x20 && c < 0x7f; isPrint {
|
|
||||||
w.buf = append(w.buf, c)
|
|
||||||
} else {
|
|
||||||
w.buf = append(w.buf, fmt.Sprintf(`\%03o`, c)...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
w.WriteByte('"')
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *textWriter) writeUnknownFields(b []byte) {
|
|
||||||
if !w.compact {
|
|
||||||
fmt.Fprintf(w, "/* %d unknown bytes */\n", len(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
for len(b) > 0 {
|
|
||||||
num, wtyp, n := protowire.ConsumeTag(b)
|
|
||||||
if n < 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b = b[n:]
|
|
||||||
|
|
||||||
if wtyp == protowire.EndGroupType {
|
|
||||||
w.indent--
|
|
||||||
w.Write(endBraceNewline)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fmt.Fprint(w, num)
|
|
||||||
if wtyp != protowire.StartGroupType {
|
|
||||||
w.WriteByte(':')
|
|
||||||
}
|
|
||||||
if !w.compact || wtyp == protowire.StartGroupType {
|
|
||||||
w.WriteByte(' ')
|
|
||||||
}
|
|
||||||
switch wtyp {
|
|
||||||
case protowire.VarintType:
|
|
||||||
v, n := protowire.ConsumeVarint(b)
|
|
||||||
if n < 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b = b[n:]
|
|
||||||
fmt.Fprint(w, v)
|
|
||||||
case protowire.Fixed32Type:
|
|
||||||
v, n := protowire.ConsumeFixed32(b)
|
|
||||||
if n < 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b = b[n:]
|
|
||||||
fmt.Fprint(w, v)
|
|
||||||
case protowire.Fixed64Type:
|
|
||||||
v, n := protowire.ConsumeFixed64(b)
|
|
||||||
if n < 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b = b[n:]
|
|
||||||
fmt.Fprint(w, v)
|
|
||||||
case protowire.BytesType:
|
|
||||||
v, n := protowire.ConsumeBytes(b)
|
|
||||||
if n < 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
b = b[n:]
|
|
||||||
fmt.Fprintf(w, "%q", v)
|
|
||||||
case protowire.StartGroupType:
|
|
||||||
w.WriteByte('{')
|
|
||||||
w.indent++
|
|
||||||
default:
|
|
||||||
fmt.Fprintf(w, "/* unknown wire type %d */", wtyp)
|
|
||||||
}
|
|
||||||
w.WriteByte('\n')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// writeExtensions writes all the extensions in m.
|
|
||||||
func (w *textWriter) writeExtensions(m protoreflect.Message) error {
|
|
||||||
md := m.Descriptor()
|
|
||||||
if md.ExtensionRanges().Len() == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type ext struct {
|
|
||||||
desc protoreflect.FieldDescriptor
|
|
||||||
val protoreflect.Value
|
|
||||||
}
|
|
||||||
var exts []ext
|
|
||||||
m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
|
|
||||||
if fd.IsExtension() {
|
|
||||||
exts = append(exts, ext{fd, v})
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
sort.Slice(exts, func(i, j int) bool {
|
|
||||||
return exts[i].desc.Number() < exts[j].desc.Number()
|
|
||||||
})
|
|
||||||
|
|
||||||
for _, ext := range exts {
|
|
||||||
// For message set, use the name of the message as the extension name.
|
|
||||||
name := string(ext.desc.FullName())
|
|
||||||
if isMessageSet(ext.desc.ContainingMessage()) {
|
|
||||||
name = strings.TrimSuffix(name, ".message_set_extension")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !ext.desc.IsList() {
|
|
||||||
if err := w.writeSingularExtension(name, ext.val, ext.desc); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
lv := ext.val.List()
|
|
||||||
for i := 0; i < lv.Len(); i++ {
|
|
||||||
if err := w.writeSingularExtension(name, lv.Get(i), ext.desc); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *textWriter) writeSingularExtension(name string, v protoreflect.Value, fd protoreflect.FieldDescriptor) error {
|
|
||||||
fmt.Fprintf(w, "[%s]:", name)
|
|
||||||
if !w.compact {
|
|
||||||
w.WriteByte(' ')
|
|
||||||
}
|
|
||||||
if err := w.writeSingularValue(v, fd); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
w.WriteByte('\n')
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *textWriter) writeIndent() {
|
|
||||||
if !w.complete {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < w.indent*2; i++ {
|
|
||||||
w.buf = append(w.buf, ' ')
|
|
||||||
}
|
|
||||||
w.complete = false
|
|
||||||
}
|
|
78
vendor/github.com/golang/protobuf/proto/wire.go
generated
vendored
78
vendor/github.com/golang/protobuf/proto/wire.go
generated
vendored
@ -1,78 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
protoV2 "google.golang.org/protobuf/proto"
|
|
||||||
"google.golang.org/protobuf/runtime/protoiface"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Size returns the size in bytes of the wire-format encoding of m.
|
|
||||||
func Size(m Message) int {
|
|
||||||
if m == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
mi := MessageV2(m)
|
|
||||||
return protoV2.Size(mi)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal returns the wire-format encoding of m.
|
|
||||||
func Marshal(m Message) ([]byte, error) {
|
|
||||||
b, err := marshalAppend(nil, m, false)
|
|
||||||
if b == nil {
|
|
||||||
b = zeroBytes
|
|
||||||
}
|
|
||||||
return b, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var zeroBytes = make([]byte, 0, 0)
|
|
||||||
|
|
||||||
func marshalAppend(buf []byte, m Message, deterministic bool) ([]byte, error) {
|
|
||||||
if m == nil {
|
|
||||||
return nil, ErrNil
|
|
||||||
}
|
|
||||||
mi := MessageV2(m)
|
|
||||||
nbuf, err := protoV2.MarshalOptions{
|
|
||||||
Deterministic: deterministic,
|
|
||||||
AllowPartial: true,
|
|
||||||
}.MarshalAppend(buf, mi)
|
|
||||||
if err != nil {
|
|
||||||
return buf, err
|
|
||||||
}
|
|
||||||
if len(buf) == len(nbuf) {
|
|
||||||
if !mi.ProtoReflect().IsValid() {
|
|
||||||
return buf, ErrNil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nbuf, checkRequiredNotSet(mi)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal parses a wire-format message in b and places the decoded results in m.
|
|
||||||
//
|
|
||||||
// Unmarshal resets m before starting to unmarshal, so any existing data in m is always
|
|
||||||
// removed. Use UnmarshalMerge to preserve and append to existing data.
|
|
||||||
func Unmarshal(b []byte, m Message) error {
|
|
||||||
m.Reset()
|
|
||||||
return UnmarshalMerge(b, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalMerge parses a wire-format message in b and places the decoded results in m.
|
|
||||||
func UnmarshalMerge(b []byte, m Message) error {
|
|
||||||
mi := MessageV2(m)
|
|
||||||
out, err := protoV2.UnmarshalOptions{
|
|
||||||
AllowPartial: true,
|
|
||||||
Merge: true,
|
|
||||||
}.UnmarshalState(protoiface.UnmarshalInput{
|
|
||||||
Buf: b,
|
|
||||||
Message: mi.ProtoReflect(),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if out.Flags&protoiface.UnmarshalInitialized > 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return checkRequiredNotSet(mi)
|
|
||||||
}
|
|
34
vendor/github.com/golang/protobuf/proto/wrappers.go
generated
vendored
34
vendor/github.com/golang/protobuf/proto/wrappers.go
generated
vendored
@ -1,34 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
// Bool stores v in a new bool value and returns a pointer to it.
|
|
||||||
func Bool(v bool) *bool { return &v }
|
|
||||||
|
|
||||||
// Int stores v in a new int32 value and returns a pointer to it.
|
|
||||||
//
|
|
||||||
// Deprecated: Use Int32 instead.
|
|
||||||
func Int(v int) *int32 { return Int32(int32(v)) }
|
|
||||||
|
|
||||||
// Int32 stores v in a new int32 value and returns a pointer to it.
|
|
||||||
func Int32(v int32) *int32 { return &v }
|
|
||||||
|
|
||||||
// Int64 stores v in a new int64 value and returns a pointer to it.
|
|
||||||
func Int64(v int64) *int64 { return &v }
|
|
||||||
|
|
||||||
// Uint32 stores v in a new uint32 value and returns a pointer to it.
|
|
||||||
func Uint32(v uint32) *uint32 { return &v }
|
|
||||||
|
|
||||||
// Uint64 stores v in a new uint64 value and returns a pointer to it.
|
|
||||||
func Uint64(v uint64) *uint64 { return &v }
|
|
||||||
|
|
||||||
// Float32 stores v in a new float32 value and returns a pointer to it.
|
|
||||||
func Float32(v float32) *float32 { return &v }
|
|
||||||
|
|
||||||
// Float64 stores v in a new float64 value and returns a pointer to it.
|
|
||||||
func Float64(v float64) *float64 { return &v }
|
|
||||||
|
|
||||||
// String stores v in a new string value and returns a pointer to it.
|
|
||||||
func String(v string) *string { return &v }
|
|
49
vendor/go.opentelemetry.io/otel/CHANGELOG.md
generated
vendored
49
vendor/go.opentelemetry.io/otel/CHANGELOG.md
generated
vendored
@ -8,9 +8,51 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [1.3.0] - 2021-12-10
|
||||||
|
|
||||||
|
### ⚠️ Notice ⚠️
|
||||||
|
|
||||||
|
We have updated the project minimum supported Go version to 1.16
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added an internal Logger.
|
||||||
|
This can be used by the SDK and API to provide users with feedback of the internal state.
|
||||||
|
To enable verbose logs configure the logger which will print V(1) logs. For debugging information configure to print V(5) logs. (#2343)
|
||||||
|
- Add the `WithRetry` `Option` and the `RetryConfig` type to the `go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetrichttp` package to specify retry behavior consistently. (#2425)
|
||||||
|
- Add `SpanStatusFromHTTPStatusCodeAndSpanKind` to all `semconv` packages to return a span status code similar to `SpanStatusFromHTTPStatusCode`, but exclude `4XX` HTTP errors as span errors if the span is of server kind. (#2296)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- The `"go.opentelemetry.io/otel/exporter/otel/otlptrace/otlptracegrpc".Client` now uses the underlying gRPC `ClientConn` to handle name resolution, TCP connection establishment (with retries and backoff) and TLS handshakes, and handling errors on established connections by re-resolving the name and reconnecting. (#2329)
|
||||||
|
- The `"go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetricgrpc".Client` now uses the underlying gRPC `ClientConn` to handle name resolution, TCP connection establishment (with retries and backoff) and TLS handshakes, and handling errors on established connections by re-resolving the name and reconnecting. (#2425)
|
||||||
|
- The `"go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetricgrpc".RetrySettings` type is renamed to `RetryConfig`. (#2425)
|
||||||
|
- The `go.opentelemetry.io/otel/exporter/otel/*` gRPC exporters now default to using the host's root CA set if none are provided by the user and `WithInsecure` is not specified. (#2432)
|
||||||
|
- Change `resource.Default` to be evaluated the first time it is called, rather than on import. This allows the caller the option to update `OTEL_RESOURCE_ATTRIBUTES` first, such as with `os.Setenv`. (#2371)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- The `go.opentelemetry.io/otel/exporter/otel/*` exporters are updated to handle per-signal and universal endpoints according to the OpenTelemetry specification.
|
||||||
|
Any per-signal endpoint set via an `OTEL_EXPORTER_OTLP_<signal>_ENDPOINT` environment variable is now used without modification of the path.
|
||||||
|
When `OTEL_EXPORTER_OTLP_ENDPOINT` is set, if it contains a path, that path is used as a base path which per-signal paths are appended to. (#2433)
|
||||||
|
- Basic metric controller updated to use sync.Map to avoid blocking calls (#2381)
|
||||||
|
- The `go.opentelemetry.io/otel/exporter/jaeger` correctly sets the `otel.status_code` value to be a string of `ERROR` or `OK` instead of an integer code. (#2439, #2440)
|
||||||
|
|
||||||
|
### Deprecated
|
||||||
|
|
||||||
|
- Deprecated the `"go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetrichttp".WithMaxAttempts` `Option`, use the new `WithRetry` `Option` instead. (#2425)
|
||||||
|
- Deprecated the `"go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetrichttp".WithBackoff` `Option`, use the new `WithRetry` `Option` instead. (#2425)
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Remove the metric Processor's ability to convert cumulative to delta aggregation temporality. (#2350)
|
||||||
|
- Remove the metric Bound Instruments interface and implementations. (#2399)
|
||||||
|
- Remove the metric MinMaxSumCount kind aggregation and the corresponding OTLP export path. (#2423)
|
||||||
|
- Metric SDK removes the "exact" aggregator for histogram instruments, as it performed a non-standard aggregation for OTLP export (creating repeated Gauge points) and worked its way into a number of confusing examples. (#2348)
|
||||||
|
|
||||||
## [1.2.0] - 2021-11-12
|
## [1.2.0] - 2021-11-12
|
||||||
|
|
||||||
## Changed
|
### Changed
|
||||||
|
|
||||||
- Metric SDK `export.ExportKind`, `export.ExportKindSelector` types have been renamed to `aggregation.Temporality` and `aggregation.TemporalitySelector` respectively to keep in line with current specification and protocol along with built-in selectors (e.g., `aggregation.CumulativeTemporalitySelector`, ...). (#2274)
|
- Metric SDK `export.ExportKind`, `export.ExportKindSelector` types have been renamed to `aggregation.Temporality` and `aggregation.TemporalitySelector` respectively to keep in line with current specification and protocol along with built-in selectors (e.g., `aggregation.CumulativeTemporalitySelector`, ...). (#2274)
|
||||||
- The Metric `Exporter` interface now requires a `TemporalitySelector` method instead of an `ExportKindSelector`. (#2274)
|
- The Metric `Exporter` interface now requires a `TemporalitySelector` method instead of an `ExportKindSelector`. (#2274)
|
||||||
@ -24,7 +66,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||||||
|
|
||||||
- Add the `"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc".WithGRPCConn` option so the exporter can reuse an existing gRPC connection. (#2002)
|
- Add the `"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc".WithGRPCConn` option so the exporter can reuse an existing gRPC connection. (#2002)
|
||||||
- Added a new `schema` module to help parse Schema Files in OTEP 0152 format. (#2267)
|
- Added a new `schema` module to help parse Schema Files in OTEP 0152 format. (#2267)
|
||||||
- Added a new `MapCarrier` to the `go.opentelemetry.io/otel/propagation` package to hold propagated coss-cutting concerns as a `map[string]string` held in memory. (#2334)
|
- Added a new `MapCarrier` to the `go.opentelemetry.io/otel/propagation` package to hold propagated cross-cutting concerns as a `map[string]string` held in memory. (#2334)
|
||||||
|
|
||||||
## [1.1.0] - 2021-10-27
|
## [1.1.0] - 2021-10-27
|
||||||
|
|
||||||
@ -1597,7 +1639,8 @@ It contains api and sdk for trace and meter.
|
|||||||
- CircleCI build CI manifest files.
|
- CircleCI build CI manifest files.
|
||||||
- CODEOWNERS file to track owners of this project.
|
- CODEOWNERS file to track owners of this project.
|
||||||
|
|
||||||
[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.2.0...HEAD
|
[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.3.0...HEAD
|
||||||
|
[1.3.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.3.0
|
||||||
[1.2.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.2.0
|
[1.2.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.2.0
|
||||||
[1.1.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.1.0
|
[1.1.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.1.0
|
||||||
[1.0.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.1
|
[1.0.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.1
|
||||||
|
2
vendor/go.opentelemetry.io/otel/CODEOWNERS
generated
vendored
2
vendor/go.opentelemetry.io/otel/CODEOWNERS
generated
vendored
@ -14,4 +14,4 @@
|
|||||||
|
|
||||||
* @jmacd @MrAlias @Aneurysm9 @evantorrie @XSAM @dashpole @paivagustavo @MadVikingGod @pellared
|
* @jmacd @MrAlias @Aneurysm9 @evantorrie @XSAM @dashpole @paivagustavo @MadVikingGod @pellared
|
||||||
|
|
||||||
CODEOWNERS @MrAlias @Aneurysm9
|
CODEOWNERS @MrAlias @Aneurysm9 @MadVikingGod
|
||||||
|
2
vendor/go.opentelemetry.io/otel/CONTRIBUTING.md
generated
vendored
2
vendor/go.opentelemetry.io/otel/CONTRIBUTING.md
generated
vendored
@ -481,11 +481,11 @@ Approvers:
|
|||||||
- [Sam Xie](https://github.com/XSAM)
|
- [Sam Xie](https://github.com/XSAM)
|
||||||
- [David Ashpole](https://github.com/dashpole), Google
|
- [David Ashpole](https://github.com/dashpole), Google
|
||||||
- [Gustavo Silva Paiva](https://github.com/paivagustavo), LightStep
|
- [Gustavo Silva Paiva](https://github.com/paivagustavo), LightStep
|
||||||
- [Aaron Clawson](https://github.com/MadVikingGod)
|
|
||||||
- [Robert Pająk](https://github.com/pellared), Splunk
|
- [Robert Pająk](https://github.com/pellared), Splunk
|
||||||
|
|
||||||
Maintainers:
|
Maintainers:
|
||||||
|
|
||||||
|
- [Aaron Clawson](https://github.com/MadVikingGod), LightStep
|
||||||
- [Anthony Mirabella](https://github.com/Aneurysm9), AWS
|
- [Anthony Mirabella](https://github.com/Aneurysm9), AWS
|
||||||
- [Tyler Yahn](https://github.com/MrAlias), Splunk
|
- [Tyler Yahn](https://github.com/MrAlias), Splunk
|
||||||
|
|
||||||
|
12
vendor/go.opentelemetry.io/otel/README.md
generated
vendored
12
vendor/go.opentelemetry.io/otel/README.md
generated
vendored
@ -30,25 +30,27 @@ Project versioning information and stability guarantees can be found in the
|
|||||||
|
|
||||||
### Compatibility
|
### Compatibility
|
||||||
|
|
||||||
|
OpenTelemetry-Go attempts to track the current supported versions of the
|
||||||
|
[Go language](https://golang.org/doc/devel/release#policy). The release
|
||||||
|
schedule after a new minor version of go is as follows:
|
||||||
|
|
||||||
|
- The first release or one month, which ever is sooner, will add build steps for the new go version.
|
||||||
|
- The first release after three months will remove support for the oldest go version.
|
||||||
|
|
||||||
This project is tested on the following systems.
|
This project is tested on the following systems.
|
||||||
|
|
||||||
| OS | Go Version | Architecture |
|
| OS | Go Version | Architecture |
|
||||||
| ------- | ---------- | ------------ |
|
| ------- | ---------- | ------------ |
|
||||||
| Ubuntu | 1.17 | amd64 |
|
| Ubuntu | 1.17 | amd64 |
|
||||||
| Ubuntu | 1.16 | amd64 |
|
| Ubuntu | 1.16 | amd64 |
|
||||||
| Ubuntu | 1.15 | amd64 |
|
|
||||||
| Ubuntu | 1.17 | 386 |
|
| Ubuntu | 1.17 | 386 |
|
||||||
| Ubuntu | 1.16 | 386 |
|
| Ubuntu | 1.16 | 386 |
|
||||||
| Ubuntu | 1.15 | 386 |
|
|
||||||
| MacOS | 1.17 | amd64 |
|
| MacOS | 1.17 | amd64 |
|
||||||
| MacOS | 1.16 | amd64 |
|
| MacOS | 1.16 | amd64 |
|
||||||
| MacOS | 1.15 | amd64 |
|
|
||||||
| Windows | 1.17 | amd64 |
|
| Windows | 1.17 | amd64 |
|
||||||
| Windows | 1.16 | amd64 |
|
| Windows | 1.16 | amd64 |
|
||||||
| Windows | 1.15 | amd64 |
|
|
||||||
| Windows | 1.17 | 386 |
|
| Windows | 1.17 | 386 |
|
||||||
| Windows | 1.16 | 386 |
|
| Windows | 1.16 | 386 |
|
||||||
| Windows | 1.15 | 386 |
|
|
||||||
|
|
||||||
While this project should work for other systems, no compatibility guarantees
|
While this project should work for other systems, no compatibility guarantees
|
||||||
are made for those systems currently.
|
are made for those systems currently.
|
||||||
|
22
vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/metric.go
generated
vendored
22
vendor/go.opentelemetry.io/otel/exporters/stdout/stdoutmetric/metric.go
generated
vendored
@ -37,8 +37,6 @@ var _ exportmetric.Exporter = &metricExporter{}
|
|||||||
|
|
||||||
type line struct {
|
type line struct {
|
||||||
Name string `json:"Name"`
|
Name string `json:"Name"`
|
||||||
Min interface{} `json:"Min,omitempty"`
|
|
||||||
Max interface{} `json:"Max,omitempty"`
|
|
||||||
Sum interface{} `json:"Sum,omitempty"`
|
Sum interface{} `json:"Sum,omitempty"`
|
||||||
Count interface{} `json:"Count,omitempty"`
|
Count interface{} `json:"Count,omitempty"`
|
||||||
LastValue interface{} `json:"Last,omitempty"`
|
LastValue interface{} `json:"Last,omitempty"`
|
||||||
@ -83,26 +81,6 @@ func (e *metricExporter) Export(_ context.Context, res *resource.Resource, reade
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
expose.Sum = value.AsInterface(kind)
|
expose.Sum = value.AsInterface(kind)
|
||||||
}
|
|
||||||
|
|
||||||
if mmsc, ok := agg.(aggregation.MinMaxSumCount); ok {
|
|
||||||
count, err := mmsc.Count()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
expose.Count = count
|
|
||||||
|
|
||||||
max, err := mmsc.Max()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
expose.Max = max.AsInterface(kind)
|
|
||||||
|
|
||||||
min, err := mmsc.Min()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
expose.Min = min.AsInterface(kind)
|
|
||||||
} else if lv, ok := agg.(aggregation.LastValue); ok {
|
} else if lv, ok := agg.(aggregation.LastValue); ok {
|
||||||
value, timestamp, err := lv.LastValue()
|
value, timestamp, err := lv.LastValue()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
65
vendor/go.opentelemetry.io/otel/handler.go
generated
vendored
65
vendor/go.opentelemetry.io/otel/handler.go
generated
vendored
@ -18,7 +18,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -28,44 +27,45 @@ var (
|
|||||||
// `Handle` and will be delegated to the registered ErrorHandler.
|
// `Handle` and will be delegated to the registered ErrorHandler.
|
||||||
globalErrorHandler = defaultErrorHandler()
|
globalErrorHandler = defaultErrorHandler()
|
||||||
|
|
||||||
// delegateErrorHandlerOnce ensures that a user provided ErrorHandler is
|
|
||||||
// only ever registered once.
|
|
||||||
delegateErrorHandlerOnce sync.Once
|
|
||||||
|
|
||||||
// Compile-time check that delegator implements ErrorHandler.
|
// Compile-time check that delegator implements ErrorHandler.
|
||||||
_ ErrorHandler = (*delegator)(nil)
|
_ ErrorHandler = (*delegator)(nil)
|
||||||
|
// Compile-time check that errLogger implements ErrorHandler.
|
||||||
|
_ ErrorHandler = (*errLogger)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
type holder struct {
|
type delegator struct {
|
||||||
|
lock *sync.RWMutex
|
||||||
eh ErrorHandler
|
eh ErrorHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultErrorHandler() *atomic.Value {
|
func (d *delegator) Handle(err error) {
|
||||||
v := &atomic.Value{}
|
d.lock.RLock()
|
||||||
v.Store(holder{eh: &delegator{l: log.New(os.Stderr, "", log.LstdFlags)}})
|
defer d.lock.RUnlock()
|
||||||
return v
|
d.eh.Handle(err)
|
||||||
}
|
|
||||||
|
|
||||||
// delegator logs errors if no delegate is set, otherwise they are delegated.
|
|
||||||
type delegator struct {
|
|
||||||
delegate atomic.Value
|
|
||||||
|
|
||||||
l *log.Logger
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// setDelegate sets the ErrorHandler delegate.
|
// setDelegate sets the ErrorHandler delegate.
|
||||||
func (h *delegator) setDelegate(d ErrorHandler) {
|
func (d *delegator) setDelegate(eh ErrorHandler) {
|
||||||
// It is critical this is guarded with delegateErrorHandlerOnce, if it is
|
d.lock.Lock()
|
||||||
// called again with a different concrete type it will panic.
|
defer d.lock.Unlock()
|
||||||
h.delegate.Store(d)
|
d.eh = eh
|
||||||
|
}
|
||||||
|
|
||||||
|
func defaultErrorHandler() *delegator {
|
||||||
|
return &delegator{
|
||||||
|
lock: &sync.RWMutex{},
|
||||||
|
eh: &errLogger{l: log.New(os.Stderr, "", log.LstdFlags)},
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// errLogger logs errors if no delegate is set, otherwise they are delegated.
|
||||||
|
type errLogger struct {
|
||||||
|
l *log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle logs err if no delegate is set, otherwise it is delegated.
|
// Handle logs err if no delegate is set, otherwise it is delegated.
|
||||||
func (h *delegator) Handle(err error) {
|
func (h *errLogger) Handle(err error) {
|
||||||
if d := h.delegate.Load(); d != nil {
|
|
||||||
d.(ErrorHandler).Handle(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
h.l.Print(err)
|
h.l.Print(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ func (h *delegator) Handle(err error) {
|
|||||||
// Subsequent calls to SetErrorHandler after the first will not forward errors
|
// Subsequent calls to SetErrorHandler after the first will not forward errors
|
||||||
// to the new ErrorHandler for prior returned instances.
|
// to the new ErrorHandler for prior returned instances.
|
||||||
func GetErrorHandler() ErrorHandler {
|
func GetErrorHandler() ErrorHandler {
|
||||||
return globalErrorHandler.Load().(holder).eh
|
return globalErrorHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetErrorHandler sets the global ErrorHandler to h.
|
// SetErrorHandler sets the global ErrorHandler to h.
|
||||||
@ -89,16 +89,7 @@ func GetErrorHandler() ErrorHandler {
|
|||||||
// ErrorHandler. Subsequent calls will set the global ErrorHandler, but not
|
// ErrorHandler. Subsequent calls will set the global ErrorHandler, but not
|
||||||
// delegate errors to h.
|
// delegate errors to h.
|
||||||
func SetErrorHandler(h ErrorHandler) {
|
func SetErrorHandler(h ErrorHandler) {
|
||||||
delegateErrorHandlerOnce.Do(func() {
|
globalErrorHandler.setDelegate(h)
|
||||||
current := GetErrorHandler()
|
|
||||||
if current == h {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if internalHandler, ok := current.(*delegator); ok {
|
|
||||||
internalHandler.setDelegate(h)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
globalErrorHandler.Store(holder{eh: h})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle is a convenience function for ErrorHandler().Handle(err)
|
// Handle is a convenience function for ErrorHandler().Handle(err)
|
||||||
|
63
vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go
generated
vendored
Normal file
63
vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Copyright The OpenTelemetry Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package global // import "go.opentelemetry.io/otel/internal/global"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/go-logr/logr"
|
||||||
|
"github.com/go-logr/stdr"
|
||||||
|
)
|
||||||
|
|
||||||
|
// globalLogger is the logging interface used within the otel api and sdk provide deatails of the internals.
|
||||||
|
//
|
||||||
|
// The default logger uses stdr which is backed by the standard `log.Logger`
|
||||||
|
// interface. This logger will only show messages at the Error Level.
|
||||||
|
var globalLogger logr.Logger = stdr.New(log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile))
|
||||||
|
var globalLoggerLock = &sync.RWMutex{}
|
||||||
|
|
||||||
|
// SetLogger overrides the globalLogger with l.
|
||||||
|
//
|
||||||
|
// To see Info messages use a logger with `l.V(1).Enabled() == true`
|
||||||
|
// To see Debug messages use a logger with `l.V(5).Enabled() == true`
|
||||||
|
func SetLogger(l logr.Logger) {
|
||||||
|
globalLoggerLock.Lock()
|
||||||
|
defer globalLoggerLock.Unlock()
|
||||||
|
globalLogger = l
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info prints messages about the general state of the API or SDK.
|
||||||
|
// This should usually be less then 5 messages a minute
|
||||||
|
func Info(msg string, keysAndValues ...interface{}) {
|
||||||
|
globalLoggerLock.RLock()
|
||||||
|
defer globalLoggerLock.RUnlock()
|
||||||
|
globalLogger.V(1).Info(msg, keysAndValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error prints messages about exceptional states of the API or SDK.
|
||||||
|
func Error(err error, msg string, keysAndValues ...interface{}) {
|
||||||
|
globalLoggerLock.RLock()
|
||||||
|
defer globalLoggerLock.RUnlock()
|
||||||
|
globalLogger.Error(err, msg, keysAndValues...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug prints messages about all internal changes in the API or SDK.
|
||||||
|
func Debug(msg string, keysAndValues ...interface{}) {
|
||||||
|
globalLoggerLock.RLock()
|
||||||
|
defer globalLoggerLock.RUnlock()
|
||||||
|
globalLogger.V(5).Info(msg, keysAndValues...)
|
||||||
|
}
|
62
vendor/go.opentelemetry.io/otel/internal/metric/global/meter.go
generated
vendored
62
vendor/go.opentelemetry.io/otel/internal/metric/global/meter.go
generated
vendored
@ -41,10 +41,6 @@ import (
|
|||||||
// in the MeterProvider and Meters ensure that each instrument has a delegate
|
// in the MeterProvider and Meters ensure that each instrument has a delegate
|
||||||
// before the global provider is set.
|
// before the global provider is set.
|
||||||
//
|
//
|
||||||
// Bound instrument operations are implemented by delegating to the
|
|
||||||
// instrument after it is registered, with a sync.Once initializer to
|
|
||||||
// protect against races with Release().
|
|
||||||
//
|
|
||||||
// Metric uniqueness checking is implemented by calling the exported
|
// Metric uniqueness checking is implemented by calling the exported
|
||||||
// methods of the api/metric/registry package.
|
// methods of the api/metric/registry package.
|
||||||
|
|
||||||
@ -108,19 +104,9 @@ type AsyncImpler interface {
|
|||||||
AsyncImpl() sdkapi.AsyncImpl
|
AsyncImpl() sdkapi.AsyncImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
type syncHandle struct {
|
|
||||||
delegate unsafe.Pointer // (*sdkapi.BoundInstrumentImpl)
|
|
||||||
|
|
||||||
inst *syncImpl
|
|
||||||
labels []attribute.KeyValue
|
|
||||||
|
|
||||||
initialize sync.Once
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ metric.MeterProvider = &meterProvider{}
|
var _ metric.MeterProvider = &meterProvider{}
|
||||||
var _ sdkapi.MeterImpl = &meterImpl{}
|
var _ sdkapi.MeterImpl = &meterImpl{}
|
||||||
var _ sdkapi.InstrumentImpl = &syncImpl{}
|
var _ sdkapi.InstrumentImpl = &syncImpl{}
|
||||||
var _ sdkapi.BoundSyncImpl = &syncHandle{}
|
|
||||||
var _ sdkapi.AsyncImpl = &asyncImpl{}
|
var _ sdkapi.AsyncImpl = &asyncImpl{}
|
||||||
|
|
||||||
func (inst *instrument) Descriptor() sdkapi.Descriptor {
|
func (inst *instrument) Descriptor() sdkapi.Descriptor {
|
||||||
@ -241,28 +227,6 @@ func (inst *syncImpl) Implementation() interface{} {
|
|||||||
return inst
|
return inst
|
||||||
}
|
}
|
||||||
|
|
||||||
func (inst *syncImpl) Bind(labels []attribute.KeyValue) sdkapi.BoundSyncImpl {
|
|
||||||
if implPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&inst.delegate)); implPtr != nil {
|
|
||||||
return (*implPtr).Bind(labels)
|
|
||||||
}
|
|
||||||
return &syncHandle{
|
|
||||||
inst: inst,
|
|
||||||
labels: labels,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (bound *syncHandle) Unbind() {
|
|
||||||
bound.initialize.Do(func() {})
|
|
||||||
|
|
||||||
implPtr := (*sdkapi.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate))
|
|
||||||
|
|
||||||
if implPtr == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
(*implPtr).Unbind()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Async delegation
|
// Async delegation
|
||||||
|
|
||||||
func (m *meterImpl) NewAsyncInstrument(
|
func (m *meterImpl) NewAsyncInstrument(
|
||||||
@ -325,37 +289,11 @@ func (inst *syncImpl) RecordOne(ctx context.Context, number number.Number, label
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bound instrument initialization
|
|
||||||
|
|
||||||
func (bound *syncHandle) RecordOne(ctx context.Context, number number.Number) {
|
|
||||||
instPtr := (*sdkapi.SyncImpl)(atomic.LoadPointer(&bound.inst.delegate))
|
|
||||||
if instPtr == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var implPtr *sdkapi.BoundSyncImpl
|
|
||||||
bound.initialize.Do(func() {
|
|
||||||
implPtr = new(sdkapi.BoundSyncImpl)
|
|
||||||
*implPtr = (*instPtr).Bind(bound.labels)
|
|
||||||
atomic.StorePointer(&bound.delegate, unsafe.Pointer(implPtr))
|
|
||||||
})
|
|
||||||
if implPtr == nil {
|
|
||||||
implPtr = (*sdkapi.BoundSyncImpl)(atomic.LoadPointer(&bound.delegate))
|
|
||||||
}
|
|
||||||
// This may still be nil if instrument was created and bound
|
|
||||||
// without a delegate, then the instrument was set to have a
|
|
||||||
// delegate and unbound.
|
|
||||||
if implPtr == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
(*implPtr).RecordOne(ctx, number)
|
|
||||||
}
|
|
||||||
|
|
||||||
func AtomicFieldOffsets() map[string]uintptr {
|
func AtomicFieldOffsets() map[string]uintptr {
|
||||||
return map[string]uintptr{
|
return map[string]uintptr{
|
||||||
"meterProvider.delegate": unsafe.Offsetof(meterProvider{}.delegate),
|
"meterProvider.delegate": unsafe.Offsetof(meterProvider{}.delegate),
|
||||||
"meterImpl.delegate": unsafe.Offsetof(meterImpl{}.delegate),
|
"meterImpl.delegate": unsafe.Offsetof(meterImpl{}.delegate),
|
||||||
"syncImpl.delegate": unsafe.Offsetof(syncImpl{}.delegate),
|
"syncImpl.delegate": unsafe.Offsetof(syncImpl{}.delegate),
|
||||||
"asyncImpl.delegate": unsafe.Offsetof(asyncImpl{}.delegate),
|
"asyncImpl.delegate": unsafe.Offsetof(asyncImpl{}.delegate),
|
||||||
"syncHandle.delegate": unsafe.Offsetof(syncHandle{}.delegate),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
26
vendor/go.opentelemetry.io/otel/internal_logging.go
generated
vendored
Normal file
26
vendor/go.opentelemetry.io/otel/internal_logging.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright The OpenTelemetry Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package otel // import "go.opentelemetry.io/otel"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/go-logr/logr"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel/internal/global"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetLogger configures the logger used internally to opentelemetry.
|
||||||
|
func SetLogger(logger logr.Logger) {
|
||||||
|
global.SetLogger(logger)
|
||||||
|
}
|
144
vendor/go.opentelemetry.io/otel/metric/metric_instrument.go
generated
vendored
144
vendor/go.opentelemetry.io/otel/metric/metric_instrument.go
generated
vendored
@ -260,11 +260,6 @@ type syncInstrument struct {
|
|||||||
instrument sdkapi.SyncImpl
|
instrument sdkapi.SyncImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
// syncBoundInstrument contains a BoundSyncImpl.
|
|
||||||
type syncBoundInstrument struct {
|
|
||||||
boundInstrument sdkapi.BoundSyncImpl
|
|
||||||
}
|
|
||||||
|
|
||||||
// asyncInstrument contains a AsyncImpl.
|
// asyncInstrument contains a AsyncImpl.
|
||||||
type asyncInstrument struct {
|
type asyncInstrument struct {
|
||||||
instrument sdkapi.AsyncImpl
|
instrument sdkapi.AsyncImpl
|
||||||
@ -280,10 +275,6 @@ func (s syncInstrument) SyncImpl() sdkapi.SyncImpl {
|
|||||||
return s.instrument
|
return s.instrument
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s syncInstrument) bind(labels []attribute.KeyValue) syncBoundInstrument {
|
|
||||||
return newSyncBoundInstrument(s.instrument.Bind(labels))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s syncInstrument) float64Measurement(value float64) Measurement {
|
func (s syncInstrument) float64Measurement(value float64) Measurement {
|
||||||
return sdkapi.NewMeasurement(s.instrument, number.NewFloat64Number(value))
|
return sdkapi.NewMeasurement(s.instrument, number.NewFloat64Number(value))
|
||||||
}
|
}
|
||||||
@ -296,15 +287,6 @@ func (s syncInstrument) directRecord(ctx context.Context, number number.Number,
|
|||||||
s.instrument.RecordOne(ctx, number, labels)
|
s.instrument.RecordOne(ctx, number, labels)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h syncBoundInstrument) directRecord(ctx context.Context, number number.Number) {
|
|
||||||
h.boundInstrument.RecordOne(ctx, number)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unbind calls SyncImpl.Unbind.
|
|
||||||
func (h syncBoundInstrument) Unbind() {
|
|
||||||
h.boundInstrument.Unbind()
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkNewAsync receives an AsyncImpl and potential
|
// checkNewAsync receives an AsyncImpl and potential
|
||||||
// error, and returns the same types, checking for and ensuring that
|
// error, and returns the same types, checking for and ensuring that
|
||||||
// the returned interface is not nil.
|
// the returned interface is not nil.
|
||||||
@ -340,12 +322,6 @@ func checkNewSync(instrument sdkapi.SyncImpl, err error) (syncInstrument, error)
|
|||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSyncBoundInstrument(boundInstrument sdkapi.BoundSyncImpl) syncBoundInstrument {
|
|
||||||
return syncBoundInstrument{
|
|
||||||
boundInstrument: boundInstrument,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// wrapInt64CounterInstrument converts a SyncImpl into Int64Counter.
|
// wrapInt64CounterInstrument converts a SyncImpl into Int64Counter.
|
||||||
func wrapInt64CounterInstrument(syncInst sdkapi.SyncImpl, err error) (Int64Counter, error) {
|
func wrapInt64CounterInstrument(syncInst sdkapi.SyncImpl, err error) (Int64Counter, error) {
|
||||||
common, err := checkNewSync(syncInst, err)
|
common, err := checkNewSync(syncInst, err)
|
||||||
@ -392,34 +368,6 @@ type Int64Counter struct {
|
|||||||
syncInstrument
|
syncInstrument
|
||||||
}
|
}
|
||||||
|
|
||||||
// BoundFloat64Counter is a bound instrument for Float64Counter.
|
|
||||||
//
|
|
||||||
// It inherits the Unbind function from syncBoundInstrument.
|
|
||||||
type BoundFloat64Counter struct {
|
|
||||||
syncBoundInstrument
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoundInt64Counter is a boundInstrument for Int64Counter.
|
|
||||||
//
|
|
||||||
// It inherits the Unbind function from syncBoundInstrument.
|
|
||||||
type BoundInt64Counter struct {
|
|
||||||
syncBoundInstrument
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind creates a bound instrument for this counter. The labels are
|
|
||||||
// associated with values recorded via subsequent calls to Record.
|
|
||||||
func (c Float64Counter) Bind(labels ...attribute.KeyValue) (h BoundFloat64Counter) {
|
|
||||||
h.syncBoundInstrument = c.bind(labels)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind creates a bound instrument for this counter. The labels are
|
|
||||||
// associated with values recorded via subsequent calls to Record.
|
|
||||||
func (c Int64Counter) Bind(labels ...attribute.KeyValue) (h BoundInt64Counter) {
|
|
||||||
h.syncBoundInstrument = c.bind(labels)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Measurement creates a Measurement object to use with batch
|
// Measurement creates a Measurement object to use with batch
|
||||||
// recording.
|
// recording.
|
||||||
func (c Float64Counter) Measurement(value float64) Measurement {
|
func (c Float64Counter) Measurement(value float64) Measurement {
|
||||||
@ -444,18 +392,6 @@ func (c Int64Counter) Add(ctx context.Context, value int64, labels ...attribute.
|
|||||||
c.directRecord(ctx, number.NewInt64Number(value), labels)
|
c.directRecord(ctx, number.NewInt64Number(value), labels)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add adds the value to the counter's sum using the labels
|
|
||||||
// previously bound to this counter via Bind()
|
|
||||||
func (b BoundFloat64Counter) Add(ctx context.Context, value float64) {
|
|
||||||
b.directRecord(ctx, number.NewFloat64Number(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add adds the value to the counter's sum using the labels
|
|
||||||
// previously bound to this counter via Bind()
|
|
||||||
func (b BoundInt64Counter) Add(ctx context.Context, value int64) {
|
|
||||||
b.directRecord(ctx, number.NewInt64Number(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64UpDownCounter is a metric instrument that sums floating
|
// Float64UpDownCounter is a metric instrument that sums floating
|
||||||
// point values.
|
// point values.
|
||||||
type Float64UpDownCounter struct {
|
type Float64UpDownCounter struct {
|
||||||
@ -467,34 +403,6 @@ type Int64UpDownCounter struct {
|
|||||||
syncInstrument
|
syncInstrument
|
||||||
}
|
}
|
||||||
|
|
||||||
// BoundFloat64UpDownCounter is a bound instrument for Float64UpDownCounter.
|
|
||||||
//
|
|
||||||
// It inherits the Unbind function from syncBoundInstrument.
|
|
||||||
type BoundFloat64UpDownCounter struct {
|
|
||||||
syncBoundInstrument
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoundInt64UpDownCounter is a boundInstrument for Int64UpDownCounter.
|
|
||||||
//
|
|
||||||
// It inherits the Unbind function from syncBoundInstrument.
|
|
||||||
type BoundInt64UpDownCounter struct {
|
|
||||||
syncBoundInstrument
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind creates a bound instrument for this counter. The labels are
|
|
||||||
// associated with values recorded via subsequent calls to Record.
|
|
||||||
func (c Float64UpDownCounter) Bind(labels ...attribute.KeyValue) (h BoundFloat64UpDownCounter) {
|
|
||||||
h.syncBoundInstrument = c.bind(labels)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind creates a bound instrument for this counter. The labels are
|
|
||||||
// associated with values recorded via subsequent calls to Record.
|
|
||||||
func (c Int64UpDownCounter) Bind(labels ...attribute.KeyValue) (h BoundInt64UpDownCounter) {
|
|
||||||
h.syncBoundInstrument = c.bind(labels)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Measurement creates a Measurement object to use with batch
|
// Measurement creates a Measurement object to use with batch
|
||||||
// recording.
|
// recording.
|
||||||
func (c Float64UpDownCounter) Measurement(value float64) Measurement {
|
func (c Float64UpDownCounter) Measurement(value float64) Measurement {
|
||||||
@ -519,18 +427,6 @@ func (c Int64UpDownCounter) Add(ctx context.Context, value int64, labels ...attr
|
|||||||
c.directRecord(ctx, number.NewInt64Number(value), labels)
|
c.directRecord(ctx, number.NewInt64Number(value), labels)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add adds the value to the counter's sum using the labels
|
|
||||||
// previously bound to this counter via Bind()
|
|
||||||
func (b BoundFloat64UpDownCounter) Add(ctx context.Context, value float64) {
|
|
||||||
b.directRecord(ctx, number.NewFloat64Number(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add adds the value to the counter's sum using the labels
|
|
||||||
// previously bound to this counter via Bind()
|
|
||||||
func (b BoundInt64UpDownCounter) Add(ctx context.Context, value int64) {
|
|
||||||
b.directRecord(ctx, number.NewInt64Number(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64Histogram is a metric that records float64 values.
|
// Float64Histogram is a metric that records float64 values.
|
||||||
type Float64Histogram struct {
|
type Float64Histogram struct {
|
||||||
syncInstrument
|
syncInstrument
|
||||||
@ -541,34 +437,6 @@ type Int64Histogram struct {
|
|||||||
syncInstrument
|
syncInstrument
|
||||||
}
|
}
|
||||||
|
|
||||||
// BoundFloat64Histogram is a bound instrument for Float64Histogram.
|
|
||||||
//
|
|
||||||
// It inherits the Unbind function from syncBoundInstrument.
|
|
||||||
type BoundFloat64Histogram struct {
|
|
||||||
syncBoundInstrument
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoundInt64Histogram is a bound instrument for Int64Histogram.
|
|
||||||
//
|
|
||||||
// It inherits the Unbind function from syncBoundInstrument.
|
|
||||||
type BoundInt64Histogram struct {
|
|
||||||
syncBoundInstrument
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind creates a bound instrument for this Histogram. The labels are
|
|
||||||
// associated with values recorded via subsequent calls to Record.
|
|
||||||
func (c Float64Histogram) Bind(labels ...attribute.KeyValue) (h BoundFloat64Histogram) {
|
|
||||||
h.syncBoundInstrument = c.bind(labels)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bind creates a bound instrument for this Histogram. The labels are
|
|
||||||
// associated with values recorded via subsequent calls to Record.
|
|
||||||
func (c Int64Histogram) Bind(labels ...attribute.KeyValue) (h BoundInt64Histogram) {
|
|
||||||
h.syncBoundInstrument = c.bind(labels)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Measurement creates a Measurement object to use with batch
|
// Measurement creates a Measurement object to use with batch
|
||||||
// recording.
|
// recording.
|
||||||
func (c Float64Histogram) Measurement(value float64) Measurement {
|
func (c Float64Histogram) Measurement(value float64) Measurement {
|
||||||
@ -594,15 +462,3 @@ func (c Float64Histogram) Record(ctx context.Context, value float64, labels ...a
|
|||||||
func (c Int64Histogram) Record(ctx context.Context, value int64, labels ...attribute.KeyValue) {
|
func (c Int64Histogram) Record(ctx context.Context, value int64, labels ...attribute.KeyValue) {
|
||||||
c.directRecord(ctx, number.NewInt64Number(value), labels)
|
c.directRecord(ctx, number.NewInt64Number(value), labels)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record adds a new value to the Histogram's distribution using the labels
|
|
||||||
// previously bound to the Histogram via Bind().
|
|
||||||
func (b BoundFloat64Histogram) Record(ctx context.Context, value float64) {
|
|
||||||
b.directRecord(ctx, number.NewFloat64Number(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Record adds a new value to the Histogram's distribution using the labels
|
|
||||||
// previously bound to the Histogram via Bind().
|
|
||||||
func (b BoundInt64Histogram) Record(ctx context.Context, value int64) {
|
|
||||||
b.directRecord(ctx, number.NewInt64Number(value))
|
|
||||||
}
|
|
||||||
|
12
vendor/go.opentelemetry.io/otel/metric/sdkapi/noop.go
generated
vendored
12
vendor/go.opentelemetry.io/otel/metric/sdkapi/noop.go
generated
vendored
@ -22,12 +22,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type noopInstrument struct{}
|
type noopInstrument struct{}
|
||||||
type noopBoundInstrument struct{}
|
|
||||||
type noopSyncInstrument struct{ noopInstrument }
|
type noopSyncInstrument struct{ noopInstrument }
|
||||||
type noopAsyncInstrument struct{ noopInstrument }
|
type noopAsyncInstrument struct{ noopInstrument }
|
||||||
|
|
||||||
var _ SyncImpl = noopSyncInstrument{}
|
var _ SyncImpl = noopSyncInstrument{}
|
||||||
var _ BoundSyncImpl = noopBoundInstrument{}
|
|
||||||
var _ AsyncImpl = noopAsyncInstrument{}
|
var _ AsyncImpl = noopAsyncInstrument{}
|
||||||
|
|
||||||
// NewNoopSyncInstrument returns a No-op implementation of the
|
// NewNoopSyncInstrument returns a No-op implementation of the
|
||||||
@ -50,15 +48,5 @@ func (noopInstrument) Descriptor() Descriptor {
|
|||||||
return Descriptor{}
|
return Descriptor{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (noopBoundInstrument) RecordOne(context.Context, number.Number) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (noopBoundInstrument) Unbind() {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (noopSyncInstrument) Bind([]attribute.KeyValue) BoundSyncImpl {
|
|
||||||
return noopBoundInstrument{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (noopSyncInstrument) RecordOne(context.Context, number.Number, []attribute.KeyValue) {
|
func (noopSyncInstrument) RecordOne(context.Context, number.Number, []attribute.KeyValue) {
|
||||||
}
|
}
|
||||||
|
16
vendor/go.opentelemetry.io/otel/metric/sdkapi/sdkapi.go
generated
vendored
16
vendor/go.opentelemetry.io/otel/metric/sdkapi/sdkapi.go
generated
vendored
@ -58,26 +58,10 @@ type InstrumentImpl interface {
|
|||||||
type SyncImpl interface {
|
type SyncImpl interface {
|
||||||
InstrumentImpl
|
InstrumentImpl
|
||||||
|
|
||||||
// Bind creates an implementation-level bound instrument,
|
|
||||||
// binding a label set with this instrument implementation.
|
|
||||||
Bind(labels []attribute.KeyValue) BoundSyncImpl
|
|
||||||
|
|
||||||
// RecordOne captures a single synchronous metric event.
|
// RecordOne captures a single synchronous metric event.
|
||||||
RecordOne(ctx context.Context, number number.Number, labels []attribute.KeyValue)
|
RecordOne(ctx context.Context, number number.Number, labels []attribute.KeyValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BoundSyncImpl is the implementation-level interface to a
|
|
||||||
// generic bound synchronous instrument
|
|
||||||
type BoundSyncImpl interface {
|
|
||||||
|
|
||||||
// RecordOne captures a single synchronous metric event.
|
|
||||||
RecordOne(ctx context.Context, number number.Number)
|
|
||||||
|
|
||||||
// Unbind frees the resources associated with this bound instrument. It
|
|
||||||
// does not affect the metric this bound instrument was created through.
|
|
||||||
Unbind()
|
|
||||||
}
|
|
||||||
|
|
||||||
// AsyncImpl is an implementation-level interface to an
|
// AsyncImpl is an implementation-level interface to an
|
||||||
// asynchronous instrument (e.g., Observer instruments).
|
// asynchronous instrument (e.g., Observer instruments).
|
||||||
type AsyncImpl interface {
|
type AsyncImpl interface {
|
||||||
|
2
vendor/go.opentelemetry.io/otel/propagation/baggage.go
generated
vendored
2
vendor/go.opentelemetry.io/otel/propagation/baggage.go
generated
vendored
@ -25,7 +25,7 @@ const baggageHeader = "baggage"
|
|||||||
// Baggage is a propagator that supports the W3C Baggage format.
|
// Baggage is a propagator that supports the W3C Baggage format.
|
||||||
//
|
//
|
||||||
// This propagates user-defined baggage associated with a trace. The complete
|
// This propagates user-defined baggage associated with a trace. The complete
|
||||||
// specification is defined at https://w3c.github.io/baggage/.
|
// specification is defined at https://www.w3.org/TR/baggage/.
|
||||||
type Baggage struct{}
|
type Baggage struct{}
|
||||||
|
|
||||||
var _ TextMapPropagator = Baggage{}
|
var _ TextMapPropagator = Baggage{}
|
||||||
|
2
vendor/go.opentelemetry.io/otel/propagation/doc.go
generated
vendored
2
vendor/go.opentelemetry.io/otel/propagation/doc.go
generated
vendored
@ -19,6 +19,6 @@ OpenTelemetry propagators are used to extract and inject context data from and
|
|||||||
into messages exchanged by applications. The propagator supported by this
|
into messages exchanged by applications. The propagator supported by this
|
||||||
package is the W3C Trace Context encoding
|
package is the W3C Trace Context encoding
|
||||||
(https://www.w3.org/TR/trace-context/), and W3C Baggage
|
(https://www.w3.org/TR/trace-context/), and W3C Baggage
|
||||||
(https://w3c.github.io/baggage/).
|
(https://www.w3.org/TR/baggage/).
|
||||||
*/
|
*/
|
||||||
package propagation // import "go.opentelemetry.io/otel/propagation"
|
package propagation // import "go.opentelemetry.io/otel/propagation"
|
||||||
|
35
vendor/go.opentelemetry.io/otel/sdk/export/metric/aggregation/aggregation.go
generated
vendored
35
vendor/go.opentelemetry.io/otel/sdk/export/metric/aggregation/aggregation.go
generated
vendored
@ -64,22 +64,6 @@ type (
|
|||||||
LastValue() (number.Number, time.Time, error)
|
LastValue() (number.Number, time.Time, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Points returns the raw values that were aggregated.
|
|
||||||
Points interface {
|
|
||||||
Aggregation
|
|
||||||
|
|
||||||
// Points returns points in the order they were
|
|
||||||
// recorded. Points are approximately ordered by
|
|
||||||
// timestamp, but this is not guaranteed.
|
|
||||||
Points() ([]Point, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Point is a raw data point, consisting of a number and value.
|
|
||||||
Point struct {
|
|
||||||
number.Number
|
|
||||||
time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// Buckets represents histogram buckets boundaries and counts.
|
// Buckets represents histogram buckets boundaries and counts.
|
||||||
//
|
//
|
||||||
// For a Histogram with N defined boundaries, e.g, [x, y, z].
|
// For a Histogram with N defined boundaries, e.g, [x, y, z].
|
||||||
@ -100,15 +84,6 @@ type (
|
|||||||
Sum() (number.Number, error)
|
Sum() (number.Number, error)
|
||||||
Histogram() (Buckets, error)
|
Histogram() (Buckets, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MinMaxSumCount supports the Min, Max, Sum, and Count interfaces.
|
|
||||||
MinMaxSumCount interface {
|
|
||||||
Aggregation
|
|
||||||
Min() (number.Number, error)
|
|
||||||
Max() (number.Number, error)
|
|
||||||
Sum() (number.Number, error)
|
|
||||||
Count() (uint64, error)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@ -122,8 +97,7 @@ type (
|
|||||||
// deciding how to expose metric data. This enables
|
// deciding how to expose metric data. This enables
|
||||||
// user-supplied Aggregators to replace builtin Aggregators.
|
// user-supplied Aggregators to replace builtin Aggregators.
|
||||||
//
|
//
|
||||||
// For example, test for a Distribution before testing for a
|
// For example, test for a Histogram before testing for a
|
||||||
// MinMaxSumCount, test for a Histogram before testing for a
|
|
||||||
// Sum, and so on.
|
// Sum, and so on.
|
||||||
Kind string
|
Kind string
|
||||||
)
|
)
|
||||||
@ -131,10 +105,8 @@ type (
|
|||||||
// Kind description constants.
|
// Kind description constants.
|
||||||
const (
|
const (
|
||||||
SumKind Kind = "Sum"
|
SumKind Kind = "Sum"
|
||||||
MinMaxSumCountKind Kind = "MinMaxSumCount"
|
|
||||||
HistogramKind Kind = "Histogram"
|
HistogramKind Kind = "Histogram"
|
||||||
LastValueKind Kind = "Lastvalue"
|
LastValueKind Kind = "Lastvalue"
|
||||||
ExactKind Kind = "Exact"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Sentinel errors for Aggregation interface.
|
// Sentinel errors for Aggregation interface.
|
||||||
@ -142,7 +114,10 @@ var (
|
|||||||
ErrNegativeInput = fmt.Errorf("negative value is out of range for this instrument")
|
ErrNegativeInput = fmt.Errorf("negative value is out of range for this instrument")
|
||||||
ErrNaNInput = fmt.Errorf("NaN value is an invalid input")
|
ErrNaNInput = fmt.Errorf("NaN value is an invalid input")
|
||||||
ErrInconsistentType = fmt.Errorf("inconsistent aggregator types")
|
ErrInconsistentType = fmt.Errorf("inconsistent aggregator types")
|
||||||
ErrNoSubtraction = fmt.Errorf("aggregator does not subtract")
|
|
||||||
|
// ErrNoCumulativeToDelta is returned when requesting delta
|
||||||
|
// export kind for a precomputed sum instrument.
|
||||||
|
ErrNoCumulativeToDelta = fmt.Errorf("cumulative to delta not implemented")
|
||||||
|
|
||||||
// ErrNoData is returned when (due to a race with collection)
|
// ErrNoData is returned when (due to a race with collection)
|
||||||
// the Aggregator is check-pointed before the first value is set.
|
// the Aggregator is check-pointed before the first value is set.
|
||||||
|
13
vendor/go.opentelemetry.io/otel/sdk/export/metric/metric.go
generated
vendored
13
vendor/go.opentelemetry.io/otel/sdk/export/metric/metric.go
generated
vendored
@ -139,8 +139,7 @@ type CheckpointerFactory interface {
|
|||||||
//
|
//
|
||||||
// Note that any Aggregator may be attached to any instrument--this is
|
// Note that any Aggregator may be attached to any instrument--this is
|
||||||
// the result of the OpenTelemetry API/SDK separation. It is possible
|
// the result of the OpenTelemetry API/SDK separation. It is possible
|
||||||
// to attach a Sum aggregator to a Histogram instrument or a
|
// to attach a Sum aggregator to a Histogram instrument.
|
||||||
// MinMaxSumCount aggregator to a Counter instrument.
|
|
||||||
type Aggregator interface {
|
type Aggregator interface {
|
||||||
// Aggregation returns an Aggregation interface to access the
|
// Aggregation returns an Aggregation interface to access the
|
||||||
// current state of this Aggregator. The caller is
|
// current state of this Aggregator. The caller is
|
||||||
@ -193,16 +192,6 @@ type Aggregator interface {
|
|||||||
Merge(aggregator Aggregator, descriptor *sdkapi.Descriptor) error
|
Merge(aggregator Aggregator, descriptor *sdkapi.Descriptor) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subtractor is an optional interface implemented by some
|
|
||||||
// Aggregators. An Aggregator must support `Subtract()` in order to
|
|
||||||
// be configured for a Precomputed-Sum instrument (CounterObserver,
|
|
||||||
// UpDownCounterObserver) using a DeltaExporter.
|
|
||||||
type Subtractor interface {
|
|
||||||
// Subtract subtracts the `operand` from this Aggregator and
|
|
||||||
// outputs the value in `result`.
|
|
||||||
Subtract(operand, result Aggregator, descriptor *sdkapi.Descriptor) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exporter handles presentation of the checkpoint of aggregate
|
// Exporter handles presentation of the checkpoint of aggregate
|
||||||
// metrics. This is the final stage of a metrics export pipeline,
|
// metrics. This is the final stage of a metrics export pipeline,
|
||||||
// where metric data are formatted for a specific system.
|
// where metric data are formatted for a specific system.
|
||||||
|
130
vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/exact/exact.go
generated
vendored
130
vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/exact/exact.go
generated
vendored
@ -1,130 +0,0 @@
|
|||||||
// Copyright The OpenTelemetry Authors
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package exact // import "go.opentelemetry.io/otel/sdk/metric/aggregator/exact"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/metric/number"
|
|
||||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
|
||||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
|
||||||
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
|
|
||||||
"go.opentelemetry.io/otel/sdk/metric/aggregator"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
// Aggregator aggregates events that form a distribution, keeping
|
|
||||||
// an array with the exact set of values.
|
|
||||||
Aggregator struct {
|
|
||||||
lock sync.Mutex
|
|
||||||
samples []aggregation.Point
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ export.Aggregator = &Aggregator{}
|
|
||||||
var _ aggregation.Points = &Aggregator{}
|
|
||||||
var _ aggregation.Count = &Aggregator{}
|
|
||||||
|
|
||||||
// New returns cnt many new exact aggregators, which aggregate recorded
|
|
||||||
// measurements by storing them in an array. This type uses a mutex
|
|
||||||
// for Update() and SynchronizedMove() concurrency.
|
|
||||||
func New(cnt int) []Aggregator {
|
|
||||||
return make([]Aggregator, cnt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aggregation returns an interface for reading the state of this aggregator.
|
|
||||||
func (c *Aggregator) Aggregation() aggregation.Aggregation {
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kind returns aggregation.ExactKind.
|
|
||||||
func (c *Aggregator) Kind() aggregation.Kind {
|
|
||||||
return aggregation.ExactKind
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count returns the number of values in the checkpoint.
|
|
||||||
func (c *Aggregator) Count() (uint64, error) {
|
|
||||||
return uint64(len(c.samples)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Points returns access to the raw data set.
|
|
||||||
func (c *Aggregator) Points() ([]aggregation.Point, error) {
|
|
||||||
return c.samples, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SynchronizedMove saves the current state to oa and resets the current state to
|
|
||||||
// the empty set, taking a lock to prevent concurrent Update() calls.
|
|
||||||
func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *sdkapi.Descriptor) error {
|
|
||||||
o, _ := oa.(*Aggregator)
|
|
||||||
|
|
||||||
if oa != nil && o == nil {
|
|
||||||
return aggregator.NewInconsistentAggregatorError(c, oa)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.lock.Lock()
|
|
||||||
defer c.lock.Unlock()
|
|
||||||
|
|
||||||
if o != nil {
|
|
||||||
o.samples = c.samples
|
|
||||||
}
|
|
||||||
c.samples = nil
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update adds the recorded measurement to the current data set.
|
|
||||||
// Update takes a lock to prevent concurrent Update() and SynchronizedMove()
|
|
||||||
// calls.
|
|
||||||
func (c *Aggregator) Update(_ context.Context, number number.Number, desc *sdkapi.Descriptor) error {
|
|
||||||
now := time.Now()
|
|
||||||
c.lock.Lock()
|
|
||||||
defer c.lock.Unlock()
|
|
||||||
c.samples = append(c.samples, aggregation.Point{
|
|
||||||
Number: number,
|
|
||||||
Time: now,
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Merge combines two data sets into one.
|
|
||||||
func (c *Aggregator) Merge(oa export.Aggregator, desc *sdkapi.Descriptor) error {
|
|
||||||
o, _ := oa.(*Aggregator)
|
|
||||||
if o == nil {
|
|
||||||
return aggregator.NewInconsistentAggregatorError(c, oa)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.samples = combine(c.samples, o.samples)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func combine(a, b []aggregation.Point) []aggregation.Point {
|
|
||||||
result := make([]aggregation.Point, 0, len(a)+len(b))
|
|
||||||
|
|
||||||
for len(a) != 0 && len(b) != 0 {
|
|
||||||
if a[0].Time.Before(b[0].Time) {
|
|
||||||
result = append(result, a[0])
|
|
||||||
a = a[1:]
|
|
||||||
} else {
|
|
||||||
result = append(result, b[0])
|
|
||||||
b = b[1:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result = append(result, a...)
|
|
||||||
result = append(result, b...)
|
|
||||||
return result
|
|
||||||
}
|
|
165
vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount/mmsc.go
generated
vendored
165
vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount/mmsc.go
generated
vendored
@ -1,165 +0,0 @@
|
|||||||
// Copyright The OpenTelemetry Authors
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package minmaxsumcount // import "go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/metric/number"
|
|
||||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
|
||||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
|
||||||
"go.opentelemetry.io/otel/sdk/export/metric/aggregation"
|
|
||||||
"go.opentelemetry.io/otel/sdk/metric/aggregator"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
// Aggregator aggregates events that form a distribution,
|
|
||||||
// keeping only the min, max, sum, and count.
|
|
||||||
Aggregator struct {
|
|
||||||
lock sync.Mutex
|
|
||||||
kind number.Kind
|
|
||||||
state
|
|
||||||
}
|
|
||||||
|
|
||||||
state struct {
|
|
||||||
sum number.Number
|
|
||||||
min number.Number
|
|
||||||
max number.Number
|
|
||||||
count uint64
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
var _ export.Aggregator = &Aggregator{}
|
|
||||||
var _ aggregation.MinMaxSumCount = &Aggregator{}
|
|
||||||
|
|
||||||
// New returns a new aggregator for computing the min, max, sum, and
|
|
||||||
// count.
|
|
||||||
//
|
|
||||||
// This type uses a mutex for Update() and SynchronizedMove() concurrency.
|
|
||||||
func New(cnt int, desc *sdkapi.Descriptor) []Aggregator {
|
|
||||||
kind := desc.NumberKind()
|
|
||||||
aggs := make([]Aggregator, cnt)
|
|
||||||
for i := range aggs {
|
|
||||||
aggs[i] = Aggregator{
|
|
||||||
kind: kind,
|
|
||||||
state: emptyState(kind),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return aggs
|
|
||||||
}
|
|
||||||
|
|
||||||
// Aggregation returns an interface for reading the state of this aggregator.
|
|
||||||
func (c *Aggregator) Aggregation() aggregation.Aggregation {
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kind returns aggregation.MinMaxSumCountKind.
|
|
||||||
func (c *Aggregator) Kind() aggregation.Kind {
|
|
||||||
return aggregation.MinMaxSumCountKind
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sum returns the sum of values in the checkpoint.
|
|
||||||
func (c *Aggregator) Sum() (number.Number, error) {
|
|
||||||
return c.sum, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count returns the number of values in the checkpoint.
|
|
||||||
func (c *Aggregator) Count() (uint64, error) {
|
|
||||||
return c.count, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Min returns the minimum value in the checkpoint.
|
|
||||||
// The error value aggregation.ErrNoData will be returned
|
|
||||||
// if there were no measurements recorded during the checkpoint.
|
|
||||||
func (c *Aggregator) Min() (number.Number, error) {
|
|
||||||
if c.count == 0 {
|
|
||||||
return 0, aggregation.ErrNoData
|
|
||||||
}
|
|
||||||
return c.min, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Max returns the maximum value in the checkpoint.
|
|
||||||
// The error value aggregation.ErrNoData will be returned
|
|
||||||
// if there were no measurements recorded during the checkpoint.
|
|
||||||
func (c *Aggregator) Max() (number.Number, error) {
|
|
||||||
if c.count == 0 {
|
|
||||||
return 0, aggregation.ErrNoData
|
|
||||||
}
|
|
||||||
return c.max, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SynchronizedMove saves the current state into oa and resets the current state to
|
|
||||||
// the empty set.
|
|
||||||
func (c *Aggregator) SynchronizedMove(oa export.Aggregator, desc *sdkapi.Descriptor) error {
|
|
||||||
o, _ := oa.(*Aggregator)
|
|
||||||
|
|
||||||
if oa != nil && o == nil {
|
|
||||||
return aggregator.NewInconsistentAggregatorError(c, oa)
|
|
||||||
}
|
|
||||||
c.lock.Lock()
|
|
||||||
if o != nil {
|
|
||||||
o.state = c.state
|
|
||||||
}
|
|
||||||
c.state = emptyState(c.kind)
|
|
||||||
c.lock.Unlock()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func emptyState(kind number.Kind) state {
|
|
||||||
return state{
|
|
||||||
count: 0,
|
|
||||||
sum: 0,
|
|
||||||
min: kind.Maximum(),
|
|
||||||
max: kind.Minimum(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update adds the recorded measurement to the current data set.
|
|
||||||
func (c *Aggregator) Update(_ context.Context, number number.Number, desc *sdkapi.Descriptor) error {
|
|
||||||
kind := desc.NumberKind()
|
|
||||||
|
|
||||||
c.lock.Lock()
|
|
||||||
defer c.lock.Unlock()
|
|
||||||
c.count++
|
|
||||||
c.sum.AddNumber(kind, number)
|
|
||||||
if number.CompareNumber(kind, c.min) < 0 {
|
|
||||||
c.min = number
|
|
||||||
}
|
|
||||||
if number.CompareNumber(kind, c.max) > 0 {
|
|
||||||
c.max = number
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Merge combines two data sets into one.
|
|
||||||
func (c *Aggregator) Merge(oa export.Aggregator, desc *sdkapi.Descriptor) error {
|
|
||||||
o, _ := oa.(*Aggregator)
|
|
||||||
if o == nil {
|
|
||||||
return aggregator.NewInconsistentAggregatorError(c, oa)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.count += o.count
|
|
||||||
c.sum.AddNumber(desc.NumberKind(), o.sum)
|
|
||||||
|
|
||||||
if c.min.CompareNumber(desc.NumberKind(), o.min) > 0 {
|
|
||||||
c.min.SetNumber(o.min)
|
|
||||||
}
|
|
||||||
if c.max.CompareNumber(desc.NumberKind(), o.max) < 0 {
|
|
||||||
c.max.SetNumber(o.max)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
17
vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/sum/sum.go
generated
vendored
17
vendor/go.opentelemetry.io/otel/sdk/metric/aggregator/sum/sum.go
generated
vendored
@ -32,7 +32,6 @@ type Aggregator struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var _ export.Aggregator = &Aggregator{}
|
var _ export.Aggregator = &Aggregator{}
|
||||||
var _ export.Subtractor = &Aggregator{}
|
|
||||||
var _ aggregation.Sum = &Aggregator{}
|
var _ aggregation.Sum = &Aggregator{}
|
||||||
|
|
||||||
// New returns a new counter aggregator implemented by atomic
|
// New returns a new counter aggregator implemented by atomic
|
||||||
@ -88,19 +87,3 @@ func (c *Aggregator) Merge(oa export.Aggregator, desc *sdkapi.Descriptor) error
|
|||||||
c.value.AddNumber(desc.NumberKind(), o.value)
|
c.value.AddNumber(desc.NumberKind(), o.value)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Aggregator) Subtract(opAgg, resAgg export.Aggregator, descriptor *sdkapi.Descriptor) error {
|
|
||||||
op, _ := opAgg.(*Aggregator)
|
|
||||||
if op == nil {
|
|
||||||
return aggregator.NewInconsistentAggregatorError(c, opAgg)
|
|
||||||
}
|
|
||||||
|
|
||||||
res, _ := resAgg.(*Aggregator)
|
|
||||||
if res == nil {
|
|
||||||
return aggregator.NewInconsistentAggregatorError(c, resAgg)
|
|
||||||
}
|
|
||||||
|
|
||||||
res.value = c.value
|
|
||||||
res.value.AddNumber(descriptor.NumberKind(), number.NewNumberSignChange(descriptor.NumberKind(), op.value))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
37
vendor/go.opentelemetry.io/otel/sdk/metric/controller/basic/controller.go
generated
vendored
37
vendor/go.opentelemetry.io/otel/sdk/metric/controller/basic/controller.go
generated
vendored
@ -56,14 +56,9 @@ var ErrControllerStarted = fmt.Errorf("controller already started")
|
|||||||
// using the export.Reader RWLock interface. Collection will
|
// using the export.Reader RWLock interface. Collection will
|
||||||
// be blocked by a pull request in the basic controller.
|
// be blocked by a pull request in the basic controller.
|
||||||
type Controller struct {
|
type Controller struct {
|
||||||
// lock protects libraries and synchronizes Start() and Stop().
|
// lock synchronizes Start() and Stop().
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
// TODO: libraries is synchronized by lock, but could be
|
libraries sync.Map
|
||||||
// accomplished using a sync.Map. The SDK specification will
|
|
||||||
// probably require this, as the draft already states that
|
|
||||||
// Stop() and MeterProvider.Meter() should not block each
|
|
||||||
// other.
|
|
||||||
libraries map[instrumentation.Library]*registry.UniqueInstrumentMeterImpl
|
|
||||||
checkpointerFactory export.CheckpointerFactory
|
checkpointerFactory export.CheckpointerFactory
|
||||||
|
|
||||||
resource *resource.Resource
|
resource *resource.Resource
|
||||||
@ -93,21 +88,18 @@ func (c *Controller) Meter(instrumentationName string, opts ...metric.MeterOptio
|
|||||||
SchemaURL: cfg.SchemaURL(),
|
SchemaURL: cfg.SchemaURL(),
|
||||||
}
|
}
|
||||||
|
|
||||||
c.lock.Lock()
|
m, ok := c.libraries.Load(library)
|
||||||
defer c.lock.Unlock()
|
|
||||||
m, ok := c.libraries[library]
|
|
||||||
if !ok {
|
if !ok {
|
||||||
checkpointer := c.checkpointerFactory.NewCheckpointer()
|
checkpointer := c.checkpointerFactory.NewCheckpointer()
|
||||||
accumulator := sdk.NewAccumulator(checkpointer)
|
m, _ = c.libraries.LoadOrStore(
|
||||||
m = registry.NewUniqueInstrumentMeterImpl(&accumulatorCheckpointer{
|
library,
|
||||||
Accumulator: accumulator,
|
registry.NewUniqueInstrumentMeterImpl(&accumulatorCheckpointer{
|
||||||
|
Accumulator: sdk.NewAccumulator(checkpointer),
|
||||||
checkpointer: checkpointer,
|
checkpointer: checkpointer,
|
||||||
library: library,
|
library: library,
|
||||||
})
|
}))
|
||||||
|
|
||||||
c.libraries[library] = m
|
|
||||||
}
|
}
|
||||||
return metric.WrapMeterImpl(m)
|
return metric.WrapMeterImpl(m.(*registry.UniqueInstrumentMeterImpl))
|
||||||
}
|
}
|
||||||
|
|
||||||
type accumulatorCheckpointer struct {
|
type accumulatorCheckpointer struct {
|
||||||
@ -138,7 +130,6 @@ func New(checkpointerFactory export.CheckpointerFactory, opts ...Option) *Contro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &Controller{
|
return &Controller{
|
||||||
libraries: map[instrumentation.Library]*registry.UniqueInstrumentMeterImpl{},
|
|
||||||
checkpointerFactory: checkpointerFactory,
|
checkpointerFactory: checkpointerFactory,
|
||||||
exporter: c.Exporter,
|
exporter: c.Exporter,
|
||||||
resource: c.Resource,
|
resource: c.Resource,
|
||||||
@ -251,16 +242,14 @@ func (c *Controller) collect(ctx context.Context) error {
|
|||||||
// accumulatorList returns a snapshot of current accumulators
|
// accumulatorList returns a snapshot of current accumulators
|
||||||
// registered to this controller. This briefly locks the controller.
|
// registered to this controller. This briefly locks the controller.
|
||||||
func (c *Controller) accumulatorList() []*accumulatorCheckpointer {
|
func (c *Controller) accumulatorList() []*accumulatorCheckpointer {
|
||||||
c.lock.Lock()
|
|
||||||
defer c.lock.Unlock()
|
|
||||||
|
|
||||||
var r []*accumulatorCheckpointer
|
var r []*accumulatorCheckpointer
|
||||||
for _, entry := range c.libraries {
|
c.libraries.Range(func(key, value interface{}) bool {
|
||||||
acc, ok := entry.MeterImpl().(*accumulatorCheckpointer)
|
acc, ok := value.(*registry.UniqueInstrumentMeterImpl).MeterImpl().(*accumulatorCheckpointer)
|
||||||
if ok {
|
if ok {
|
||||||
r = append(r, acc)
|
r = append(r, acc)
|
||||||
}
|
}
|
||||||
}
|
return true
|
||||||
|
})
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
vendor/go.opentelemetry.io/otel/sdk/metric/doc.go
generated
vendored
6
vendor/go.opentelemetry.io/otel/sdk/metric/doc.go
generated
vendored
@ -28,9 +28,7 @@ and asynchronous instruments. There are two constructors per instrument for
|
|||||||
the two kinds of number (int64, float64).
|
the two kinds of number (int64, float64).
|
||||||
|
|
||||||
Synchronous instruments are managed by a sync.Map containing a *record
|
Synchronous instruments are managed by a sync.Map containing a *record
|
||||||
with the current state for each synchronous instrument. A bound
|
with the current state for each synchronous instrument. A lock-free
|
||||||
instrument encapsulates a direct pointer to the record, allowing
|
|
||||||
bound metric events to bypass a sync.Map lookup. A lock-free
|
|
||||||
algorithm is used to protect against races when adding and removing
|
algorithm is used to protect against races when adding and removing
|
||||||
items from the sync.Map.
|
items from the sync.Map.
|
||||||
|
|
||||||
@ -45,7 +43,7 @@ record contains a set of recorders for every specific label set used in the
|
|||||||
callback.
|
callback.
|
||||||
|
|
||||||
A sync.Map maintains the mapping of current instruments and label sets to
|
A sync.Map maintains the mapping of current instruments and label sets to
|
||||||
internal records. To create a new bound instrument, the SDK consults the Map to
|
internal records. To find a record, the SDK consults the Map to
|
||||||
locate an existing record, otherwise it constructs a new record. The SDK
|
locate an existing record, otherwise it constructs a new record. The SDK
|
||||||
maintains a count of the number of references to each record, ensuring
|
maintains a count of the number of references to each record, ensuring
|
||||||
that records are not reclaimed from the Map while they are still active
|
that records are not reclaimed from the Map while they are still active
|
||||||
|
75
vendor/go.opentelemetry.io/otel/sdk/metric/processor/basic/basic.go
generated
vendored
75
vendor/go.opentelemetry.io/otel/sdk/metric/processor/basic/basic.go
generated
vendored
@ -76,11 +76,6 @@ type (
|
|||||||
// values in a single collection round.
|
// values in a single collection round.
|
||||||
current export.Aggregator
|
current export.Aggregator
|
||||||
|
|
||||||
// delta, if non-nil, refers to an Aggregator owned by
|
|
||||||
// the processor used to compute deltas between
|
|
||||||
// precomputed sums.
|
|
||||||
delta export.Aggregator
|
|
||||||
|
|
||||||
// cumulative, if non-nil, refers to an Aggregator owned
|
// cumulative, if non-nil, refers to an Aggregator owned
|
||||||
// by the processor used to store the last cumulative
|
// by the processor used to store the last cumulative
|
||||||
// value.
|
// value.
|
||||||
@ -94,9 +89,6 @@ type (
|
|||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
values map[stateKey]*stateValue
|
values map[stateKey]*stateValue
|
||||||
|
|
||||||
// Note: the timestamp logic currently assumes all
|
|
||||||
// exports are deltas.
|
|
||||||
|
|
||||||
processStart time.Time
|
processStart time.Time
|
||||||
intervalStart time.Time
|
intervalStart time.Time
|
||||||
intervalEnd time.Time
|
intervalEnd time.Time
|
||||||
@ -124,8 +116,8 @@ var ErrInvalidTemporality = fmt.Errorf("invalid aggregation temporality")
|
|||||||
// New returns a basic Processor that is also a Checkpointer using the provided
|
// New returns a basic Processor that is also a Checkpointer using the provided
|
||||||
// AggregatorSelector to select Aggregators. The TemporalitySelector
|
// AggregatorSelector to select Aggregators. The TemporalitySelector
|
||||||
// is consulted to determine the kind(s) of exporter that will consume
|
// is consulted to determine the kind(s) of exporter that will consume
|
||||||
// data, so that this Processor can prepare to compute Delta or
|
// data, so that this Processor can prepare to compute Cumulative Aggregations
|
||||||
// Cumulative Aggregations as needed.
|
// as needed.
|
||||||
func New(aselector export.AggregatorSelector, tselector aggregation.TemporalitySelector, opts ...Option) *Processor {
|
func New(aselector export.AggregatorSelector, tselector aggregation.TemporalitySelector, opts ...Option) *Processor {
|
||||||
return NewFactory(aselector, tselector, opts...).NewCheckpointer().(*Processor)
|
return NewFactory(aselector, tselector, opts...).NewCheckpointer().(*Processor)
|
||||||
}
|
}
|
||||||
@ -191,13 +183,17 @@ func (b *Processor) Process(accum export.Accumulation) error {
|
|||||||
}
|
}
|
||||||
if stateful {
|
if stateful {
|
||||||
if desc.InstrumentKind().PrecomputedSum() {
|
if desc.InstrumentKind().PrecomputedSum() {
|
||||||
// If we know we need to compute deltas, allocate two aggregators.
|
// To convert precomputed sums to
|
||||||
b.AggregatorFor(desc, &newValue.cumulative, &newValue.delta)
|
// deltas requires two aggregators to
|
||||||
} else {
|
// be allocated, one for the prior
|
||||||
// In this case we are certain not to need a delta, only allocate
|
// value and one for the output delta.
|
||||||
// a cumulative aggregator.
|
// This functionality was removed from
|
||||||
b.AggregatorFor(desc, &newValue.cumulative)
|
// the basic processor in PR #2350.
|
||||||
|
return aggregation.ErrNoCumulativeToDelta
|
||||||
}
|
}
|
||||||
|
// In this case allocate one aggregator to
|
||||||
|
// save the current state.
|
||||||
|
b.AggregatorFor(desc, &newValue.cumulative)
|
||||||
}
|
}
|
||||||
b.state.values[key] = newValue
|
b.state.values[key] = newValue
|
||||||
return nil
|
return nil
|
||||||
@ -310,30 +306,17 @@ func (b *Processor) FinishCollection() error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Aggregator state to support exporting either a
|
// The only kind of aggregators that are not stateless
|
||||||
// delta or a cumulative aggregation.
|
// are the ones needing delta to cumulative
|
||||||
var err error
|
// conversion. Merge aggregator state in this case.
|
||||||
if mkind.PrecomputedSum() {
|
if !mkind.PrecomputedSum() {
|
||||||
if currentSubtractor, ok := value.current.(export.Subtractor); ok {
|
|
||||||
// This line is equivalent to:
|
// This line is equivalent to:
|
||||||
// value.delta = currentSubtractor - value.cumulative
|
// value.cumulative = value.cumulative + value.current
|
||||||
err = currentSubtractor.Subtract(value.cumulative, value.delta, key.descriptor)
|
if err := value.cumulative.Merge(value.current, key.descriptor); err != nil {
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
err = value.current.SynchronizedMove(value.cumulative, key.descriptor)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = aggregation.ErrNoSubtraction
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// This line is equivalent to:
|
|
||||||
// value.cumulative = value.cumulative + value.delta
|
|
||||||
err = value.cumulative.Merge(value.current, key.descriptor)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,13 +333,8 @@ func (b *state) ForEach(exporter aggregation.TemporalitySelector, f func(export.
|
|||||||
var agg aggregation.Aggregation
|
var agg aggregation.Aggregation
|
||||||
var start time.Time
|
var start time.Time
|
||||||
|
|
||||||
// If the processor does not have Config.Memory and it was not updated
|
|
||||||
// in the prior round, do not visit this value.
|
|
||||||
if !b.config.Memory && value.updated != (b.finishedCollection-1) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
aggTemp := exporter.TemporalityFor(key.descriptor, value.current.Aggregation().Kind())
|
aggTemp := exporter.TemporalityFor(key.descriptor, value.current.Aggregation().Kind())
|
||||||
|
|
||||||
switch aggTemp {
|
switch aggTemp {
|
||||||
case aggregation.CumulativeTemporality:
|
case aggregation.CumulativeTemporality:
|
||||||
// If stateful, the sum has been computed. If stateless, the
|
// If stateful, the sum has been computed. If stateless, the
|
||||||
@ -372,16 +350,23 @@ func (b *state) ForEach(exporter aggregation.TemporalitySelector, f func(export.
|
|||||||
case aggregation.DeltaTemporality:
|
case aggregation.DeltaTemporality:
|
||||||
// Precomputed sums are a special case.
|
// Precomputed sums are a special case.
|
||||||
if mkind.PrecomputedSum() {
|
if mkind.PrecomputedSum() {
|
||||||
agg = value.delta.Aggregation()
|
// This functionality was removed from
|
||||||
} else {
|
// the basic processor in PR #2350.
|
||||||
agg = value.current.Aggregation()
|
return aggregation.ErrNoCumulativeToDelta
|
||||||
}
|
}
|
||||||
|
agg = value.current.Aggregation()
|
||||||
start = b.intervalStart
|
start = b.intervalStart
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("%v: %w", aggTemp, ErrInvalidTemporality)
|
return fmt.Errorf("%v: %w", aggTemp, ErrInvalidTemporality)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the processor does not have Config.Memory and it was not updated
|
||||||
|
// in the prior round, do not visit this value.
|
||||||
|
if !b.config.Memory && value.updated != (b.finishedCollection-1) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if err := f(export.NewRecord(
|
if err := f(export.NewRecord(
|
||||||
key.descriptor,
|
key.descriptor,
|
||||||
value.labels,
|
value.labels,
|
||||||
|
13
vendor/go.opentelemetry.io/otel/sdk/metric/sdk.go
generated
vendored
13
vendor/go.opentelemetry.io/otel/sdk/metric/sdk.go
generated
vendored
@ -141,7 +141,6 @@ var (
|
|||||||
_ sdkapi.MeterImpl = &Accumulator{}
|
_ sdkapi.MeterImpl = &Accumulator{}
|
||||||
_ sdkapi.AsyncImpl = &asyncInstrument{}
|
_ sdkapi.AsyncImpl = &asyncInstrument{}
|
||||||
_ sdkapi.SyncImpl = &syncInstrument{}
|
_ sdkapi.SyncImpl = &syncInstrument{}
|
||||||
_ sdkapi.BoundSyncImpl = &record{}
|
|
||||||
|
|
||||||
// ErrUninitializedInstrument is returned when an instrument is used when uninitialized.
|
// ErrUninitializedInstrument is returned when an instrument is used when uninitialized.
|
||||||
ErrUninitializedInstrument = fmt.Errorf("use of an uninitialized instrument")
|
ErrUninitializedInstrument = fmt.Errorf("use of an uninitialized instrument")
|
||||||
@ -279,15 +278,10 @@ func (s *syncInstrument) acquireHandle(kvs []attribute.KeyValue, labelPtr *attri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The order of the input array `kvs` may be sorted after the function is called.
|
|
||||||
func (s *syncInstrument) Bind(kvs []attribute.KeyValue) sdkapi.BoundSyncImpl {
|
|
||||||
return s.acquireHandle(kvs, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The order of the input array `kvs` may be sorted after the function is called.
|
// The order of the input array `kvs` may be sorted after the function is called.
|
||||||
func (s *syncInstrument) RecordOne(ctx context.Context, num number.Number, kvs []attribute.KeyValue) {
|
func (s *syncInstrument) RecordOne(ctx context.Context, num number.Number, kvs []attribute.KeyValue) {
|
||||||
h := s.acquireHandle(kvs, nil)
|
h := s.acquireHandle(kvs, nil)
|
||||||
defer h.Unbind()
|
defer h.unbind()
|
||||||
h.RecordOne(ctx, num)
|
h.RecordOne(ctx, num)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,7 +484,7 @@ func (m *Accumulator) RecordBatch(ctx context.Context, kvs []attribute.KeyValue,
|
|||||||
labelsPtr = h.labels
|
labelsPtr = h.labels
|
||||||
}
|
}
|
||||||
|
|
||||||
defer h.Unbind()
|
defer h.unbind()
|
||||||
h.RecordOne(ctx, meas.Number())
|
h.RecordOne(ctx, meas.Number())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -514,8 +508,7 @@ func (r *record) RecordOne(ctx context.Context, num number.Number) {
|
|||||||
atomic.AddInt64(&r.updateCount, 1)
|
atomic.AddInt64(&r.updateCount, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unbind implements sdkapi.SyncImpl.
|
func (r *record) unbind() {
|
||||||
func (r *record) Unbind() {
|
|
||||||
r.refMapped.unref()
|
r.refMapped.unref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
29
vendor/go.opentelemetry.io/otel/sdk/metric/selector/simple/simple.go
generated
vendored
29
vendor/go.opentelemetry.io/otel/sdk/metric/selector/simple/simple.go
generated
vendored
@ -17,16 +17,13 @@ package simple // import "go.opentelemetry.io/otel/sdk/metric/selector/simple"
|
|||||||
import (
|
import (
|
||||||
"go.opentelemetry.io/otel/metric/sdkapi"
|
"go.opentelemetry.io/otel/metric/sdkapi"
|
||||||
export "go.opentelemetry.io/otel/sdk/export/metric"
|
export "go.opentelemetry.io/otel/sdk/export/metric"
|
||||||
"go.opentelemetry.io/otel/sdk/metric/aggregator/exact"
|
|
||||||
"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
|
"go.opentelemetry.io/otel/sdk/metric/aggregator/histogram"
|
||||||
"go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue"
|
"go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue"
|
||||||
"go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount"
|
|
||||||
"go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
|
"go.opentelemetry.io/otel/sdk/metric/aggregator/sum"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
selectorInexpensive struct{}
|
selectorInexpensive struct{}
|
||||||
selectorExact struct{}
|
|
||||||
selectorHistogram struct {
|
selectorHistogram struct {
|
||||||
options []histogram.Option
|
options []histogram.Option
|
||||||
}
|
}
|
||||||
@ -34,7 +31,6 @@ type (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
_ export.AggregatorSelector = selectorInexpensive{}
|
_ export.AggregatorSelector = selectorInexpensive{}
|
||||||
_ export.AggregatorSelector = selectorExact{}
|
|
||||||
_ export.AggregatorSelector = selectorHistogram{}
|
_ export.AggregatorSelector = selectorHistogram{}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -47,15 +43,6 @@ func NewWithInexpensiveDistribution() export.AggregatorSelector {
|
|||||||
return selectorInexpensive{}
|
return selectorInexpensive{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewWithExactDistribution returns a simple aggregator selector that
|
|
||||||
// uses exact aggregators for `Histogram` instruments. This
|
|
||||||
// selector uses more memory than the others in this package because
|
|
||||||
// exact aggregators maintain the most information about the
|
|
||||||
// distribution among these choices.
|
|
||||||
func NewWithExactDistribution() export.AggregatorSelector {
|
|
||||||
return selectorExact{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewWithHistogramDistribution returns a simple aggregator selector
|
// NewWithHistogramDistribution returns a simple aggregator selector
|
||||||
// that uses histogram aggregators for `Histogram` instruments.
|
// that uses histogram aggregators for `Histogram` instruments.
|
||||||
// This selector is a good default choice for most metric exporters.
|
// This selector is a good default choice for most metric exporters.
|
||||||
@ -82,21 +69,7 @@ func (selectorInexpensive) AggregatorFor(descriptor *sdkapi.Descriptor, aggPtrs
|
|||||||
case sdkapi.GaugeObserverInstrumentKind:
|
case sdkapi.GaugeObserverInstrumentKind:
|
||||||
lastValueAggs(aggPtrs)
|
lastValueAggs(aggPtrs)
|
||||||
case sdkapi.HistogramInstrumentKind:
|
case sdkapi.HistogramInstrumentKind:
|
||||||
aggs := minmaxsumcount.New(len(aggPtrs), descriptor)
|
aggs := sum.New(len(aggPtrs))
|
||||||
for i := range aggPtrs {
|
|
||||||
*aggPtrs[i] = &aggs[i]
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
sumAggs(aggPtrs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (selectorExact) AggregatorFor(descriptor *sdkapi.Descriptor, aggPtrs ...*export.Aggregator) {
|
|
||||||
switch descriptor.InstrumentKind() {
|
|
||||||
case sdkapi.GaugeObserverInstrumentKind:
|
|
||||||
lastValueAggs(aggPtrs)
|
|
||||||
case sdkapi.HistogramInstrumentKind:
|
|
||||||
aggs := exact.New(len(aggPtrs))
|
|
||||||
for i := range aggPtrs {
|
for i := range aggPtrs {
|
||||||
*aggPtrs[i] = &aggs[i]
|
*aggPtrs[i] = &aggs[i]
|
||||||
}
|
}
|
||||||
|
37
vendor/go.opentelemetry.io/otel/sdk/resource/resource.go
generated
vendored
37
vendor/go.opentelemetry.io/otel/sdk/resource/resource.go
generated
vendored
@ -18,6 +18,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"go.opentelemetry.io/otel"
|
"go.opentelemetry.io/otel"
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
@ -37,25 +38,11 @@ type Resource struct {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
emptyResource Resource
|
emptyResource Resource
|
||||||
|
defaultResource *Resource
|
||||||
defaultResource = func(r *Resource, err error) *Resource {
|
defaultResourceOnce sync.Once
|
||||||
if err != nil {
|
|
||||||
otel.Handle(err)
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}(
|
|
||||||
Detect(
|
|
||||||
context.Background(),
|
|
||||||
defaultServiceNameDetector{},
|
|
||||||
fromEnv{},
|
|
||||||
telemetrySDK{},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var errMergeConflictSchemaURL = errors.New("cannot merge resource due to conflicting Schema URL")
|
||||||
errMergeConflictSchemaURL = errors.New("cannot merge resource due to conflicting Schema URL")
|
|
||||||
)
|
|
||||||
|
|
||||||
// New returns a Resource combined from the user-provided detectors.
|
// New returns a Resource combined from the user-provided detectors.
|
||||||
func New(ctx context.Context, opts ...Option) (*Resource, error) {
|
func New(ctx context.Context, opts ...Option) (*Resource, error) {
|
||||||
@ -211,6 +198,22 @@ func Empty() *Resource {
|
|||||||
// Default returns an instance of Resource with a default
|
// Default returns an instance of Resource with a default
|
||||||
// "service.name" and OpenTelemetrySDK attributes.
|
// "service.name" and OpenTelemetrySDK attributes.
|
||||||
func Default() *Resource {
|
func Default() *Resource {
|
||||||
|
defaultResourceOnce.Do(func() {
|
||||||
|
var err error
|
||||||
|
defaultResource, err = Detect(
|
||||||
|
context.Background(),
|
||||||
|
defaultServiceNameDetector{},
|
||||||
|
fromEnv{},
|
||||||
|
telemetrySDK{},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
otel.Handle(err)
|
||||||
|
}
|
||||||
|
// If Detect did not return a valid resource, fall back to emptyResource.
|
||||||
|
if defaultResource == nil {
|
||||||
|
defaultResource = &emptyResource
|
||||||
|
}
|
||||||
|
})
|
||||||
return defaultResource
|
return defaultResource
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
vendor/go.opentelemetry.io/otel/semconv/v1.7.0/http.go
generated
vendored
17
vendor/go.opentelemetry.io/otel/semconv/v1.7.0/http.go
generated
vendored
@ -21,6 +21,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"go.opentelemetry.io/otel/attribute"
|
||||||
"go.opentelemetry.io/otel/codes"
|
"go.opentelemetry.io/otel/codes"
|
||||||
)
|
)
|
||||||
@ -269,6 +271,21 @@ func SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) {
|
|||||||
return spanCode, ""
|
return spanCode, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SpanStatusFromHTTPStatusCodeAndSpanKind generates a status code and a message
|
||||||
|
// as specified by the OpenTelemetry specification for a span.
|
||||||
|
// Exclude 4xx for SERVER to set the appropriate status.
|
||||||
|
func SpanStatusFromHTTPStatusCodeAndSpanKind(code int, spanKind trace.SpanKind) (codes.Code, string) {
|
||||||
|
spanCode, valid := validateHTTPStatusCode(code)
|
||||||
|
if !valid {
|
||||||
|
return spanCode, fmt.Sprintf("Invalid HTTP status code %d", code)
|
||||||
|
}
|
||||||
|
category := code / 100
|
||||||
|
if spanKind == trace.SpanKindServer && category == 4 {
|
||||||
|
return codes.Unset, ""
|
||||||
|
}
|
||||||
|
return spanCode, ""
|
||||||
|
}
|
||||||
|
|
||||||
// Validates the HTTP status code and returns corresponding span status code.
|
// Validates the HTTP status code and returns corresponding span status code.
|
||||||
// If the `code` is not a valid HTTP status code, returns span status Error
|
// If the `code` is not a valid HTTP status code, returns span status Error
|
||||||
// and false.
|
// and false.
|
||||||
|
2
vendor/go.opentelemetry.io/otel/version.go
generated
vendored
2
vendor/go.opentelemetry.io/otel/version.go
generated
vendored
@ -16,5 +16,5 @@ package otel // import "go.opentelemetry.io/otel"
|
|||||||
|
|
||||||
// Version is the current release version of OpenTelemetry in use.
|
// Version is the current release version of OpenTelemetry in use.
|
||||||
func Version() string {
|
func Version() string {
|
||||||
return "1.2.0"
|
return "1.3.0"
|
||||||
}
|
}
|
||||||
|
7
vendor/go.opentelemetry.io/otel/versions.yaml
generated
vendored
7
vendor/go.opentelemetry.io/otel/versions.yaml
generated
vendored
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
module-sets:
|
module-sets:
|
||||||
stable-v1:
|
stable-v1:
|
||||||
version: v1.2.0
|
version: v1.3.0
|
||||||
modules:
|
modules:
|
||||||
- go.opentelemetry.io/otel
|
- go.opentelemetry.io/otel
|
||||||
- go.opentelemetry.io/otel/bridge/opentracing
|
- go.opentelemetry.io/otel/bridge/opentracing
|
||||||
@ -29,11 +29,12 @@ module-sets:
|
|||||||
- go.opentelemetry.io/otel/exporters/otlp/otlptrace
|
- go.opentelemetry.io/otel/exporters/otlp/otlptrace
|
||||||
- go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
|
- go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
|
||||||
- go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp
|
- go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp
|
||||||
|
- go.opentelemetry.io/otel/exporters/otlp/internal/retry
|
||||||
- go.opentelemetry.io/otel/exporters/stdout/stdouttrace
|
- go.opentelemetry.io/otel/exporters/stdout/stdouttrace
|
||||||
- go.opentelemetry.io/otel/trace
|
- go.opentelemetry.io/otel/trace
|
||||||
- go.opentelemetry.io/otel/sdk
|
- go.opentelemetry.io/otel/sdk
|
||||||
experimental-metrics:
|
experimental-metrics:
|
||||||
version: v0.25.0
|
version: v0.26.0
|
||||||
modules:
|
modules:
|
||||||
- go.opentelemetry.io/otel/example/prometheus
|
- go.opentelemetry.io/otel/example/prometheus
|
||||||
- go.opentelemetry.io/otel/exporters/otlp/otlpmetric
|
- go.opentelemetry.io/otel/exporters/otlp/otlpmetric
|
||||||
@ -50,7 +51,7 @@ module-sets:
|
|||||||
modules:
|
modules:
|
||||||
- go.opentelemetry.io/otel/schema
|
- go.opentelemetry.io/otel/schema
|
||||||
bridge:
|
bridge:
|
||||||
version: v0.25.0
|
version: v0.26.0
|
||||||
modules:
|
modules:
|
||||||
- go.opentelemetry.io/otel/bridge/opencensus
|
- go.opentelemetry.io/otel/bridge/opencensus
|
||||||
- go.opentelemetry.io/otel/bridge/opencensus/test
|
- go.opentelemetry.io/otel/bridge/opencensus/test
|
||||||
|
3
vendor/google.golang.org/protobuf/encoding/prototext/decode.go
generated
vendored
3
vendor/google.golang.org/protobuf/encoding/prototext/decode.go
generated
vendored
@ -744,9 +744,6 @@ func (d decoder) skipValue() error {
|
|||||||
// Skip items. This will not validate whether skipped values are
|
// Skip items. This will not validate whether skipped values are
|
||||||
// of the same type or not, same behavior as C++
|
// of the same type or not, same behavior as C++
|
||||||
// TextFormat::Parser::AllowUnknownField(true) version 3.8.0.
|
// TextFormat::Parser::AllowUnknownField(true) version 3.8.0.
|
||||||
if err := d.skipValue(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
5
vendor/google.golang.org/protobuf/internal/encoding/text/encode.go
generated
vendored
5
vendor/google.golang.org/protobuf/internal/encoding/text/encode.go
generated
vendored
@ -263,3 +263,8 @@ func (e *Encoder) Snapshot() encoderState {
|
|||||||
func (e *Encoder) Reset(es encoderState) {
|
func (e *Encoder) Reset(es encoderState) {
|
||||||
e.encoderState = es
|
e.encoderState = es
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AppendString appends the escaped form of the input string to b.
|
||||||
|
func AppendString(b []byte, s string) []byte {
|
||||||
|
return appendString(b, s, false)
|
||||||
|
}
|
||||||
|
7
vendor/google.golang.org/protobuf/internal/impl/legacy_message.go
generated
vendored
7
vendor/google.golang.org/protobuf/internal/impl/legacy_message.go
generated
vendored
@ -440,6 +440,13 @@ func legacyMerge(in piface.MergeInput) piface.MergeOutput {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return piface.MergeOutput{}
|
return piface.MergeOutput{}
|
||||||
}
|
}
|
||||||
|
if !in.Source.IsValid() {
|
||||||
|
// Legacy Marshal methods may not function on nil messages.
|
||||||
|
// Check for a typed nil source only after we confirm that
|
||||||
|
// legacy Marshal/Unmarshal methods are present, for
|
||||||
|
// consistency.
|
||||||
|
return piface.MergeOutput{Flags: piface.MergeComplete}
|
||||||
|
}
|
||||||
b, err := marshaler.Marshal()
|
b, err := marshaler.Marshal()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return piface.MergeOutput{}
|
return piface.MergeOutput{}
|
||||||
|
4
vendor/google.golang.org/protobuf/internal/version/version.go
generated
vendored
4
vendor/google.golang.org/protobuf/internal/version/version.go
generated
vendored
@ -52,8 +52,8 @@ import (
|
|||||||
// 10. Send out the CL for review and submit it.
|
// 10. Send out the CL for review and submit it.
|
||||||
const (
|
const (
|
||||||
Major = 1
|
Major = 1
|
||||||
Minor = 26
|
Minor = 27
|
||||||
Patch = 0
|
Patch = 1
|
||||||
PreRelease = ""
|
PreRelease = ""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
276
vendor/google.golang.org/protobuf/reflect/protodesc/desc.go
generated
vendored
276
vendor/google.golang.org/protobuf/reflect/protodesc/desc.go
generated
vendored
@ -1,276 +0,0 @@
|
|||||||
// Copyright 2018 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// Package protodesc provides functionality for converting
|
|
||||||
// FileDescriptorProto messages to/from protoreflect.FileDescriptor values.
|
|
||||||
//
|
|
||||||
// The google.protobuf.FileDescriptorProto is a protobuf message that describes
|
|
||||||
// the type information for a .proto file in a form that is easily serializable.
|
|
||||||
// The protoreflect.FileDescriptor is a more structured representation of
|
|
||||||
// the FileDescriptorProto message where references and remote dependencies
|
|
||||||
// can be directly followed.
|
|
||||||
package protodesc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"google.golang.org/protobuf/internal/errors"
|
|
||||||
"google.golang.org/protobuf/internal/filedesc"
|
|
||||||
"google.golang.org/protobuf/internal/pragma"
|
|
||||||
"google.golang.org/protobuf/internal/strs"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
"google.golang.org/protobuf/reflect/protoregistry"
|
|
||||||
|
|
||||||
"google.golang.org/protobuf/types/descriptorpb"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Resolver is the resolver used by NewFile to resolve dependencies.
|
|
||||||
// The enums and messages provided must belong to some parent file,
|
|
||||||
// which is also registered.
|
|
||||||
//
|
|
||||||
// It is implemented by protoregistry.Files.
|
|
||||||
type Resolver interface {
|
|
||||||
FindFileByPath(string) (protoreflect.FileDescriptor, error)
|
|
||||||
FindDescriptorByName(protoreflect.FullName) (protoreflect.Descriptor, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileOptions configures the construction of file descriptors.
|
|
||||||
type FileOptions struct {
|
|
||||||
pragma.NoUnkeyedLiterals
|
|
||||||
|
|
||||||
// AllowUnresolvable configures New to permissively allow unresolvable
|
|
||||||
// file, enum, or message dependencies. Unresolved dependencies are replaced
|
|
||||||
// by placeholder equivalents.
|
|
||||||
//
|
|
||||||
// The following dependencies may be left unresolved:
|
|
||||||
// • Resolving an imported file.
|
|
||||||
// • Resolving the type for a message field or extension field.
|
|
||||||
// If the kind of the field is unknown, then a placeholder is used for both
|
|
||||||
// the Enum and Message accessors on the protoreflect.FieldDescriptor.
|
|
||||||
// • Resolving an enum value set as the default for an optional enum field.
|
|
||||||
// If unresolvable, the protoreflect.FieldDescriptor.Default is set to the
|
|
||||||
// first value in the associated enum (or zero if the also enum dependency
|
|
||||||
// is also unresolvable). The protoreflect.FieldDescriptor.DefaultEnumValue
|
|
||||||
// is populated with a placeholder.
|
|
||||||
// • Resolving the extended message type for an extension field.
|
|
||||||
// • Resolving the input or output message type for a service method.
|
|
||||||
//
|
|
||||||
// If the unresolved dependency uses a relative name,
|
|
||||||
// then the placeholder will contain an invalid FullName with a "*." prefix,
|
|
||||||
// indicating that the starting prefix of the full name is unknown.
|
|
||||||
AllowUnresolvable bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFile creates a new protoreflect.FileDescriptor from the provided
|
|
||||||
// file descriptor message. See FileOptions.New for more information.
|
|
||||||
func NewFile(fd *descriptorpb.FileDescriptorProto, r Resolver) (protoreflect.FileDescriptor, error) {
|
|
||||||
return FileOptions{}.New(fd, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFiles creates a new protoregistry.Files from the provided
|
|
||||||
// FileDescriptorSet message. See FileOptions.NewFiles for more information.
|
|
||||||
func NewFiles(fd *descriptorpb.FileDescriptorSet) (*protoregistry.Files, error) {
|
|
||||||
return FileOptions{}.NewFiles(fd)
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new protoreflect.FileDescriptor from the provided
|
|
||||||
// file descriptor message. The file must represent a valid proto file according
|
|
||||||
// to protobuf semantics. The returned descriptor is a deep copy of the input.
|
|
||||||
//
|
|
||||||
// Any imported files, enum types, or message types referenced in the file are
|
|
||||||
// resolved using the provided registry. When looking up an import file path,
|
|
||||||
// the path must be unique. The newly created file descriptor is not registered
|
|
||||||
// back into the provided file registry.
|
|
||||||
func (o FileOptions) New(fd *descriptorpb.FileDescriptorProto, r Resolver) (protoreflect.FileDescriptor, error) {
|
|
||||||
if r == nil {
|
|
||||||
r = (*protoregistry.Files)(nil) // empty resolver
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle the file descriptor content.
|
|
||||||
f := &filedesc.File{L2: &filedesc.FileL2{}}
|
|
||||||
switch fd.GetSyntax() {
|
|
||||||
case "proto2", "":
|
|
||||||
f.L1.Syntax = protoreflect.Proto2
|
|
||||||
case "proto3":
|
|
||||||
f.L1.Syntax = protoreflect.Proto3
|
|
||||||
default:
|
|
||||||
return nil, errors.New("invalid syntax: %q", fd.GetSyntax())
|
|
||||||
}
|
|
||||||
f.L1.Path = fd.GetName()
|
|
||||||
if f.L1.Path == "" {
|
|
||||||
return nil, errors.New("file path must be populated")
|
|
||||||
}
|
|
||||||
f.L1.Package = protoreflect.FullName(fd.GetPackage())
|
|
||||||
if !f.L1.Package.IsValid() && f.L1.Package != "" {
|
|
||||||
return nil, errors.New("invalid package: %q", f.L1.Package)
|
|
||||||
}
|
|
||||||
if opts := fd.GetOptions(); opts != nil {
|
|
||||||
opts = proto.Clone(opts).(*descriptorpb.FileOptions)
|
|
||||||
f.L2.Options = func() protoreflect.ProtoMessage { return opts }
|
|
||||||
}
|
|
||||||
|
|
||||||
f.L2.Imports = make(filedesc.FileImports, len(fd.GetDependency()))
|
|
||||||
for _, i := range fd.GetPublicDependency() {
|
|
||||||
if !(0 <= i && int(i) < len(f.L2.Imports)) || f.L2.Imports[i].IsPublic {
|
|
||||||
return nil, errors.New("invalid or duplicate public import index: %d", i)
|
|
||||||
}
|
|
||||||
f.L2.Imports[i].IsPublic = true
|
|
||||||
}
|
|
||||||
for _, i := range fd.GetWeakDependency() {
|
|
||||||
if !(0 <= i && int(i) < len(f.L2.Imports)) || f.L2.Imports[i].IsWeak {
|
|
||||||
return nil, errors.New("invalid or duplicate weak import index: %d", i)
|
|
||||||
}
|
|
||||||
f.L2.Imports[i].IsWeak = true
|
|
||||||
}
|
|
||||||
imps := importSet{f.Path(): true}
|
|
||||||
for i, path := range fd.GetDependency() {
|
|
||||||
imp := &f.L2.Imports[i]
|
|
||||||
f, err := r.FindFileByPath(path)
|
|
||||||
if err == protoregistry.NotFound && (o.AllowUnresolvable || imp.IsWeak) {
|
|
||||||
f = filedesc.PlaceholderFile(path)
|
|
||||||
} else if err != nil {
|
|
||||||
return nil, errors.New("could not resolve import %q: %v", path, err)
|
|
||||||
}
|
|
||||||
imp.FileDescriptor = f
|
|
||||||
|
|
||||||
if imps[imp.Path()] {
|
|
||||||
return nil, errors.New("already imported %q", path)
|
|
||||||
}
|
|
||||||
imps[imp.Path()] = true
|
|
||||||
}
|
|
||||||
for i := range fd.GetDependency() {
|
|
||||||
imp := &f.L2.Imports[i]
|
|
||||||
imps.importPublic(imp.Imports())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle source locations.
|
|
||||||
f.L2.Locations.File = f
|
|
||||||
for _, loc := range fd.GetSourceCodeInfo().GetLocation() {
|
|
||||||
var l protoreflect.SourceLocation
|
|
||||||
// TODO: Validate that the path points to an actual declaration?
|
|
||||||
l.Path = protoreflect.SourcePath(loc.GetPath())
|
|
||||||
s := loc.GetSpan()
|
|
||||||
switch len(s) {
|
|
||||||
case 3:
|
|
||||||
l.StartLine, l.StartColumn, l.EndLine, l.EndColumn = int(s[0]), int(s[1]), int(s[0]), int(s[2])
|
|
||||||
case 4:
|
|
||||||
l.StartLine, l.StartColumn, l.EndLine, l.EndColumn = int(s[0]), int(s[1]), int(s[2]), int(s[3])
|
|
||||||
default:
|
|
||||||
return nil, errors.New("invalid span: %v", s)
|
|
||||||
}
|
|
||||||
// TODO: Validate that the span information is sensible?
|
|
||||||
// See https://github.com/protocolbuffers/protobuf/issues/6378.
|
|
||||||
if false && (l.EndLine < l.StartLine || l.StartLine < 0 || l.StartColumn < 0 || l.EndColumn < 0 ||
|
|
||||||
(l.StartLine == l.EndLine && l.EndColumn <= l.StartColumn)) {
|
|
||||||
return nil, errors.New("invalid span: %v", s)
|
|
||||||
}
|
|
||||||
l.LeadingDetachedComments = loc.GetLeadingDetachedComments()
|
|
||||||
l.LeadingComments = loc.GetLeadingComments()
|
|
||||||
l.TrailingComments = loc.GetTrailingComments()
|
|
||||||
f.L2.Locations.List = append(f.L2.Locations.List, l)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 1: Allocate and derive the names for all declarations.
|
|
||||||
// This copies all fields from the descriptor proto except:
|
|
||||||
// google.protobuf.FieldDescriptorProto.type_name
|
|
||||||
// google.protobuf.FieldDescriptorProto.default_value
|
|
||||||
// google.protobuf.FieldDescriptorProto.oneof_index
|
|
||||||
// google.protobuf.FieldDescriptorProto.extendee
|
|
||||||
// google.protobuf.MethodDescriptorProto.input
|
|
||||||
// google.protobuf.MethodDescriptorProto.output
|
|
||||||
var err error
|
|
||||||
sb := new(strs.Builder)
|
|
||||||
r1 := make(descsByName)
|
|
||||||
if f.L1.Enums.List, err = r1.initEnumDeclarations(fd.GetEnumType(), f, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if f.L1.Messages.List, err = r1.initMessagesDeclarations(fd.GetMessageType(), f, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if f.L1.Extensions.List, err = r1.initExtensionDeclarations(fd.GetExtension(), f, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if f.L1.Services.List, err = r1.initServiceDeclarations(fd.GetService(), f, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 2: Resolve every dependency reference not handled by step 1.
|
|
||||||
r2 := &resolver{local: r1, remote: r, imports: imps, allowUnresolvable: o.AllowUnresolvable}
|
|
||||||
if err := r2.resolveMessageDependencies(f.L1.Messages.List, fd.GetMessageType()); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := r2.resolveExtensionDependencies(f.L1.Extensions.List, fd.GetExtension()); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := r2.resolveServiceDependencies(f.L1.Services.List, fd.GetService()); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3: Validate every enum, message, and extension declaration.
|
|
||||||
if err := validateEnumDeclarations(f.L1.Enums.List, fd.GetEnumType()); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := validateMessageDeclarations(f.L1.Messages.List, fd.GetMessageType()); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := validateExtensionDeclarations(f.L1.Extensions.List, fd.GetExtension()); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type importSet map[string]bool
|
|
||||||
|
|
||||||
func (is importSet) importPublic(imps protoreflect.FileImports) {
|
|
||||||
for i := 0; i < imps.Len(); i++ {
|
|
||||||
if imp := imps.Get(i); imp.IsPublic {
|
|
||||||
is[imp.Path()] = true
|
|
||||||
is.importPublic(imp.Imports())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFiles creates a new protoregistry.Files from the provided
|
|
||||||
// FileDescriptorSet message. The descriptor set must include only
|
|
||||||
// valid files according to protobuf semantics. The returned descriptors
|
|
||||||
// are a deep copy of the input.
|
|
||||||
func (o FileOptions) NewFiles(fds *descriptorpb.FileDescriptorSet) (*protoregistry.Files, error) {
|
|
||||||
files := make(map[string]*descriptorpb.FileDescriptorProto)
|
|
||||||
for _, fd := range fds.File {
|
|
||||||
if _, ok := files[fd.GetName()]; ok {
|
|
||||||
return nil, errors.New("file appears multiple times: %q", fd.GetName())
|
|
||||||
}
|
|
||||||
files[fd.GetName()] = fd
|
|
||||||
}
|
|
||||||
r := &protoregistry.Files{}
|
|
||||||
for _, fd := range files {
|
|
||||||
if err := o.addFileDeps(r, fd, files); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r, nil
|
|
||||||
}
|
|
||||||
func (o FileOptions) addFileDeps(r *protoregistry.Files, fd *descriptorpb.FileDescriptorProto, files map[string]*descriptorpb.FileDescriptorProto) error {
|
|
||||||
// Set the entry to nil while descending into a file's dependencies to detect cycles.
|
|
||||||
files[fd.GetName()] = nil
|
|
||||||
for _, dep := range fd.Dependency {
|
|
||||||
depfd, ok := files[dep]
|
|
||||||
if depfd == nil {
|
|
||||||
if ok {
|
|
||||||
return errors.New("import cycle in file: %q", dep)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := o.addFileDeps(r, depfd, files); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Delete the entry once dependencies are processed.
|
|
||||||
delete(files, fd.GetName())
|
|
||||||
f, err := o.New(fd, r)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return r.RegisterFile(f)
|
|
||||||
}
|
|
248
vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go
generated
vendored
248
vendor/google.golang.org/protobuf/reflect/protodesc/desc_init.go
generated
vendored
@ -1,248 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package protodesc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"google.golang.org/protobuf/internal/errors"
|
|
||||||
"google.golang.org/protobuf/internal/filedesc"
|
|
||||||
"google.golang.org/protobuf/internal/strs"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
|
|
||||||
"google.golang.org/protobuf/types/descriptorpb"
|
|
||||||
)
|
|
||||||
|
|
||||||
type descsByName map[protoreflect.FullName]protoreflect.Descriptor
|
|
||||||
|
|
||||||
func (r descsByName) initEnumDeclarations(eds []*descriptorpb.EnumDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (es []filedesc.Enum, err error) {
|
|
||||||
es = make([]filedesc.Enum, len(eds)) // allocate up-front to ensure stable pointers
|
|
||||||
for i, ed := range eds {
|
|
||||||
e := &es[i]
|
|
||||||
e.L2 = new(filedesc.EnumL2)
|
|
||||||
if e.L0, err = r.makeBase(e, parent, ed.GetName(), i, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if opts := ed.GetOptions(); opts != nil {
|
|
||||||
opts = proto.Clone(opts).(*descriptorpb.EnumOptions)
|
|
||||||
e.L2.Options = func() protoreflect.ProtoMessage { return opts }
|
|
||||||
}
|
|
||||||
for _, s := range ed.GetReservedName() {
|
|
||||||
e.L2.ReservedNames.List = append(e.L2.ReservedNames.List, protoreflect.Name(s))
|
|
||||||
}
|
|
||||||
for _, rr := range ed.GetReservedRange() {
|
|
||||||
e.L2.ReservedRanges.List = append(e.L2.ReservedRanges.List, [2]protoreflect.EnumNumber{
|
|
||||||
protoreflect.EnumNumber(rr.GetStart()),
|
|
||||||
protoreflect.EnumNumber(rr.GetEnd()),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if e.L2.Values.List, err = r.initEnumValuesFromDescriptorProto(ed.GetValue(), e, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return es, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r descsByName) initEnumValuesFromDescriptorProto(vds []*descriptorpb.EnumValueDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (vs []filedesc.EnumValue, err error) {
|
|
||||||
vs = make([]filedesc.EnumValue, len(vds)) // allocate up-front to ensure stable pointers
|
|
||||||
for i, vd := range vds {
|
|
||||||
v := &vs[i]
|
|
||||||
if v.L0, err = r.makeBase(v, parent, vd.GetName(), i, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if opts := vd.GetOptions(); opts != nil {
|
|
||||||
opts = proto.Clone(opts).(*descriptorpb.EnumValueOptions)
|
|
||||||
v.L1.Options = func() protoreflect.ProtoMessage { return opts }
|
|
||||||
}
|
|
||||||
v.L1.Number = protoreflect.EnumNumber(vd.GetNumber())
|
|
||||||
}
|
|
||||||
return vs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r descsByName) initMessagesDeclarations(mds []*descriptorpb.DescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (ms []filedesc.Message, err error) {
|
|
||||||
ms = make([]filedesc.Message, len(mds)) // allocate up-front to ensure stable pointers
|
|
||||||
for i, md := range mds {
|
|
||||||
m := &ms[i]
|
|
||||||
m.L2 = new(filedesc.MessageL2)
|
|
||||||
if m.L0, err = r.makeBase(m, parent, md.GetName(), i, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if opts := md.GetOptions(); opts != nil {
|
|
||||||
opts = proto.Clone(opts).(*descriptorpb.MessageOptions)
|
|
||||||
m.L2.Options = func() protoreflect.ProtoMessage { return opts }
|
|
||||||
m.L1.IsMapEntry = opts.GetMapEntry()
|
|
||||||
m.L1.IsMessageSet = opts.GetMessageSetWireFormat()
|
|
||||||
}
|
|
||||||
for _, s := range md.GetReservedName() {
|
|
||||||
m.L2.ReservedNames.List = append(m.L2.ReservedNames.List, protoreflect.Name(s))
|
|
||||||
}
|
|
||||||
for _, rr := range md.GetReservedRange() {
|
|
||||||
m.L2.ReservedRanges.List = append(m.L2.ReservedRanges.List, [2]protoreflect.FieldNumber{
|
|
||||||
protoreflect.FieldNumber(rr.GetStart()),
|
|
||||||
protoreflect.FieldNumber(rr.GetEnd()),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
for _, xr := range md.GetExtensionRange() {
|
|
||||||
m.L2.ExtensionRanges.List = append(m.L2.ExtensionRanges.List, [2]protoreflect.FieldNumber{
|
|
||||||
protoreflect.FieldNumber(xr.GetStart()),
|
|
||||||
protoreflect.FieldNumber(xr.GetEnd()),
|
|
||||||
})
|
|
||||||
var optsFunc func() protoreflect.ProtoMessage
|
|
||||||
if opts := xr.GetOptions(); opts != nil {
|
|
||||||
opts = proto.Clone(opts).(*descriptorpb.ExtensionRangeOptions)
|
|
||||||
optsFunc = func() protoreflect.ProtoMessage { return opts }
|
|
||||||
}
|
|
||||||
m.L2.ExtensionRangeOptions = append(m.L2.ExtensionRangeOptions, optsFunc)
|
|
||||||
}
|
|
||||||
if m.L2.Fields.List, err = r.initFieldsFromDescriptorProto(md.GetField(), m, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if m.L2.Oneofs.List, err = r.initOneofsFromDescriptorProto(md.GetOneofDecl(), m, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if m.L1.Enums.List, err = r.initEnumDeclarations(md.GetEnumType(), m, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if m.L1.Messages.List, err = r.initMessagesDeclarations(md.GetNestedType(), m, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if m.L1.Extensions.List, err = r.initExtensionDeclarations(md.GetExtension(), m, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ms, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r descsByName) initFieldsFromDescriptorProto(fds []*descriptorpb.FieldDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (fs []filedesc.Field, err error) {
|
|
||||||
fs = make([]filedesc.Field, len(fds)) // allocate up-front to ensure stable pointers
|
|
||||||
for i, fd := range fds {
|
|
||||||
f := &fs[i]
|
|
||||||
if f.L0, err = r.makeBase(f, parent, fd.GetName(), i, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
f.L1.IsProto3Optional = fd.GetProto3Optional()
|
|
||||||
if opts := fd.GetOptions(); opts != nil {
|
|
||||||
opts = proto.Clone(opts).(*descriptorpb.FieldOptions)
|
|
||||||
f.L1.Options = func() protoreflect.ProtoMessage { return opts }
|
|
||||||
f.L1.IsWeak = opts.GetWeak()
|
|
||||||
f.L1.HasPacked = opts.Packed != nil
|
|
||||||
f.L1.IsPacked = opts.GetPacked()
|
|
||||||
}
|
|
||||||
f.L1.Number = protoreflect.FieldNumber(fd.GetNumber())
|
|
||||||
f.L1.Cardinality = protoreflect.Cardinality(fd.GetLabel())
|
|
||||||
if fd.Type != nil {
|
|
||||||
f.L1.Kind = protoreflect.Kind(fd.GetType())
|
|
||||||
}
|
|
||||||
if fd.JsonName != nil {
|
|
||||||
f.L1.StringName.InitJSON(fd.GetJsonName())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r descsByName) initOneofsFromDescriptorProto(ods []*descriptorpb.OneofDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (os []filedesc.Oneof, err error) {
|
|
||||||
os = make([]filedesc.Oneof, len(ods)) // allocate up-front to ensure stable pointers
|
|
||||||
for i, od := range ods {
|
|
||||||
o := &os[i]
|
|
||||||
if o.L0, err = r.makeBase(o, parent, od.GetName(), i, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if opts := od.GetOptions(); opts != nil {
|
|
||||||
opts = proto.Clone(opts).(*descriptorpb.OneofOptions)
|
|
||||||
o.L1.Options = func() protoreflect.ProtoMessage { return opts }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return os, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r descsByName) initExtensionDeclarations(xds []*descriptorpb.FieldDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (xs []filedesc.Extension, err error) {
|
|
||||||
xs = make([]filedesc.Extension, len(xds)) // allocate up-front to ensure stable pointers
|
|
||||||
for i, xd := range xds {
|
|
||||||
x := &xs[i]
|
|
||||||
x.L2 = new(filedesc.ExtensionL2)
|
|
||||||
if x.L0, err = r.makeBase(x, parent, xd.GetName(), i, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if opts := xd.GetOptions(); opts != nil {
|
|
||||||
opts = proto.Clone(opts).(*descriptorpb.FieldOptions)
|
|
||||||
x.L2.Options = func() protoreflect.ProtoMessage { return opts }
|
|
||||||
x.L2.IsPacked = opts.GetPacked()
|
|
||||||
}
|
|
||||||
x.L1.Number = protoreflect.FieldNumber(xd.GetNumber())
|
|
||||||
x.L1.Cardinality = protoreflect.Cardinality(xd.GetLabel())
|
|
||||||
if xd.Type != nil {
|
|
||||||
x.L1.Kind = protoreflect.Kind(xd.GetType())
|
|
||||||
}
|
|
||||||
if xd.JsonName != nil {
|
|
||||||
x.L2.StringName.InitJSON(xd.GetJsonName())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return xs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r descsByName) initServiceDeclarations(sds []*descriptorpb.ServiceDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (ss []filedesc.Service, err error) {
|
|
||||||
ss = make([]filedesc.Service, len(sds)) // allocate up-front to ensure stable pointers
|
|
||||||
for i, sd := range sds {
|
|
||||||
s := &ss[i]
|
|
||||||
s.L2 = new(filedesc.ServiceL2)
|
|
||||||
if s.L0, err = r.makeBase(s, parent, sd.GetName(), i, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if opts := sd.GetOptions(); opts != nil {
|
|
||||||
opts = proto.Clone(opts).(*descriptorpb.ServiceOptions)
|
|
||||||
s.L2.Options = func() protoreflect.ProtoMessage { return opts }
|
|
||||||
}
|
|
||||||
if s.L2.Methods.List, err = r.initMethodsFromDescriptorProto(sd.GetMethod(), s, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ss, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r descsByName) initMethodsFromDescriptorProto(mds []*descriptorpb.MethodDescriptorProto, parent protoreflect.Descriptor, sb *strs.Builder) (ms []filedesc.Method, err error) {
|
|
||||||
ms = make([]filedesc.Method, len(mds)) // allocate up-front to ensure stable pointers
|
|
||||||
for i, md := range mds {
|
|
||||||
m := &ms[i]
|
|
||||||
if m.L0, err = r.makeBase(m, parent, md.GetName(), i, sb); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if opts := md.GetOptions(); opts != nil {
|
|
||||||
opts = proto.Clone(opts).(*descriptorpb.MethodOptions)
|
|
||||||
m.L1.Options = func() protoreflect.ProtoMessage { return opts }
|
|
||||||
}
|
|
||||||
m.L1.IsStreamingClient = md.GetClientStreaming()
|
|
||||||
m.L1.IsStreamingServer = md.GetServerStreaming()
|
|
||||||
}
|
|
||||||
return ms, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r descsByName) makeBase(child, parent protoreflect.Descriptor, name string, idx int, sb *strs.Builder) (filedesc.BaseL0, error) {
|
|
||||||
if !protoreflect.Name(name).IsValid() {
|
|
||||||
return filedesc.BaseL0{}, errors.New("descriptor %q has an invalid nested name: %q", parent.FullName(), name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Derive the full name of the child.
|
|
||||||
// Note that enum values are a sibling to the enum parent in the namespace.
|
|
||||||
var fullName protoreflect.FullName
|
|
||||||
if _, ok := parent.(protoreflect.EnumDescriptor); ok {
|
|
||||||
fullName = sb.AppendFullName(parent.FullName().Parent(), protoreflect.Name(name))
|
|
||||||
} else {
|
|
||||||
fullName = sb.AppendFullName(parent.FullName(), protoreflect.Name(name))
|
|
||||||
}
|
|
||||||
if _, ok := r[fullName]; ok {
|
|
||||||
return filedesc.BaseL0{}, errors.New("descriptor %q already declared", fullName)
|
|
||||||
}
|
|
||||||
r[fullName] = child
|
|
||||||
|
|
||||||
// TODO: Verify that the full name does not already exist in the resolver?
|
|
||||||
// This is not as critical since most usages of NewFile will register
|
|
||||||
// the created file back into the registry, which will perform this check.
|
|
||||||
|
|
||||||
return filedesc.BaseL0{
|
|
||||||
FullName: fullName,
|
|
||||||
ParentFile: parent.ParentFile().(*filedesc.File),
|
|
||||||
Parent: parent,
|
|
||||||
Index: idx,
|
|
||||||
}, nil
|
|
||||||
}
|
|
286
vendor/google.golang.org/protobuf/reflect/protodesc/desc_resolve.go
generated
vendored
286
vendor/google.golang.org/protobuf/reflect/protodesc/desc_resolve.go
generated
vendored
@ -1,286 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package protodesc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"google.golang.org/protobuf/internal/encoding/defval"
|
|
||||||
"google.golang.org/protobuf/internal/errors"
|
|
||||||
"google.golang.org/protobuf/internal/filedesc"
|
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
"google.golang.org/protobuf/reflect/protoregistry"
|
|
||||||
|
|
||||||
"google.golang.org/protobuf/types/descriptorpb"
|
|
||||||
)
|
|
||||||
|
|
||||||
// resolver is a wrapper around a local registry of declarations within the file
|
|
||||||
// and the remote resolver. The remote resolver is restricted to only return
|
|
||||||
// descriptors that have been imported.
|
|
||||||
type resolver struct {
|
|
||||||
local descsByName
|
|
||||||
remote Resolver
|
|
||||||
imports importSet
|
|
||||||
|
|
||||||
allowUnresolvable bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *resolver) resolveMessageDependencies(ms []filedesc.Message, mds []*descriptorpb.DescriptorProto) (err error) {
|
|
||||||
for i, md := range mds {
|
|
||||||
m := &ms[i]
|
|
||||||
for j, fd := range md.GetField() {
|
|
||||||
f := &m.L2.Fields.List[j]
|
|
||||||
if f.L1.Cardinality == protoreflect.Required {
|
|
||||||
m.L2.RequiredNumbers.List = append(m.L2.RequiredNumbers.List, f.L1.Number)
|
|
||||||
}
|
|
||||||
if fd.OneofIndex != nil {
|
|
||||||
k := int(fd.GetOneofIndex())
|
|
||||||
if !(0 <= k && k < len(md.GetOneofDecl())) {
|
|
||||||
return errors.New("message field %q has an invalid oneof index: %d", f.FullName(), k)
|
|
||||||
}
|
|
||||||
o := &m.L2.Oneofs.List[k]
|
|
||||||
f.L1.ContainingOneof = o
|
|
||||||
o.L1.Fields.List = append(o.L1.Fields.List, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
if f.L1.Kind, f.L1.Enum, f.L1.Message, err = r.findTarget(f.Kind(), f.Parent().FullName(), partialName(fd.GetTypeName()), f.IsWeak()); err != nil {
|
|
||||||
return errors.New("message field %q cannot resolve type: %v", f.FullName(), err)
|
|
||||||
}
|
|
||||||
if fd.DefaultValue != nil {
|
|
||||||
v, ev, err := unmarshalDefault(fd.GetDefaultValue(), f, r.allowUnresolvable)
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("message field %q has invalid default: %v", f.FullName(), err)
|
|
||||||
}
|
|
||||||
f.L1.Default = filedesc.DefaultValue(v, ev)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := r.resolveMessageDependencies(m.L1.Messages.List, md.GetNestedType()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := r.resolveExtensionDependencies(m.L1.Extensions.List, md.GetExtension()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *resolver) resolveExtensionDependencies(xs []filedesc.Extension, xds []*descriptorpb.FieldDescriptorProto) (err error) {
|
|
||||||
for i, xd := range xds {
|
|
||||||
x := &xs[i]
|
|
||||||
if x.L1.Extendee, err = r.findMessageDescriptor(x.Parent().FullName(), partialName(xd.GetExtendee()), false); err != nil {
|
|
||||||
return errors.New("extension field %q cannot resolve extendee: %v", x.FullName(), err)
|
|
||||||
}
|
|
||||||
if x.L1.Kind, x.L2.Enum, x.L2.Message, err = r.findTarget(x.Kind(), x.Parent().FullName(), partialName(xd.GetTypeName()), false); err != nil {
|
|
||||||
return errors.New("extension field %q cannot resolve type: %v", x.FullName(), err)
|
|
||||||
}
|
|
||||||
if xd.DefaultValue != nil {
|
|
||||||
v, ev, err := unmarshalDefault(xd.GetDefaultValue(), x, r.allowUnresolvable)
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("extension field %q has invalid default: %v", x.FullName(), err)
|
|
||||||
}
|
|
||||||
x.L2.Default = filedesc.DefaultValue(v, ev)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *resolver) resolveServiceDependencies(ss []filedesc.Service, sds []*descriptorpb.ServiceDescriptorProto) (err error) {
|
|
||||||
for i, sd := range sds {
|
|
||||||
s := &ss[i]
|
|
||||||
for j, md := range sd.GetMethod() {
|
|
||||||
m := &s.L2.Methods.List[j]
|
|
||||||
m.L1.Input, err = r.findMessageDescriptor(m.Parent().FullName(), partialName(md.GetInputType()), false)
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("service method %q cannot resolve input: %v", m.FullName(), err)
|
|
||||||
}
|
|
||||||
m.L1.Output, err = r.findMessageDescriptor(s.FullName(), partialName(md.GetOutputType()), false)
|
|
||||||
if err != nil {
|
|
||||||
return errors.New("service method %q cannot resolve output: %v", m.FullName(), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// findTarget finds an enum or message descriptor if k is an enum, message,
|
|
||||||
// group, or unknown. If unknown, and the name could be resolved, the kind
|
|
||||||
// returned kind is set based on the type of the resolved descriptor.
|
|
||||||
func (r *resolver) findTarget(k protoreflect.Kind, scope protoreflect.FullName, ref partialName, isWeak bool) (protoreflect.Kind, protoreflect.EnumDescriptor, protoreflect.MessageDescriptor, error) {
|
|
||||||
switch k {
|
|
||||||
case protoreflect.EnumKind:
|
|
||||||
ed, err := r.findEnumDescriptor(scope, ref, isWeak)
|
|
||||||
if err != nil {
|
|
||||||
return 0, nil, nil, err
|
|
||||||
}
|
|
||||||
return k, ed, nil, nil
|
|
||||||
case protoreflect.MessageKind, protoreflect.GroupKind:
|
|
||||||
md, err := r.findMessageDescriptor(scope, ref, isWeak)
|
|
||||||
if err != nil {
|
|
||||||
return 0, nil, nil, err
|
|
||||||
}
|
|
||||||
return k, nil, md, nil
|
|
||||||
case 0:
|
|
||||||
// Handle unspecified kinds (possible with parsers that operate
|
|
||||||
// on a per-file basis without knowledge of dependencies).
|
|
||||||
d, err := r.findDescriptor(scope, ref)
|
|
||||||
if err == protoregistry.NotFound && (r.allowUnresolvable || isWeak) {
|
|
||||||
return k, filedesc.PlaceholderEnum(ref.FullName()), filedesc.PlaceholderMessage(ref.FullName()), nil
|
|
||||||
} else if err == protoregistry.NotFound {
|
|
||||||
return 0, nil, nil, errors.New("%q not found", ref.FullName())
|
|
||||||
} else if err != nil {
|
|
||||||
return 0, nil, nil, err
|
|
||||||
}
|
|
||||||
switch d := d.(type) {
|
|
||||||
case protoreflect.EnumDescriptor:
|
|
||||||
return protoreflect.EnumKind, d, nil, nil
|
|
||||||
case protoreflect.MessageDescriptor:
|
|
||||||
return protoreflect.MessageKind, nil, d, nil
|
|
||||||
default:
|
|
||||||
return 0, nil, nil, errors.New("unknown kind")
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if ref != "" {
|
|
||||||
return 0, nil, nil, errors.New("target name cannot be specified for %v", k)
|
|
||||||
}
|
|
||||||
if !k.IsValid() {
|
|
||||||
return 0, nil, nil, errors.New("invalid kind: %d", k)
|
|
||||||
}
|
|
||||||
return k, nil, nil, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// findDescriptor finds the descriptor by name,
|
|
||||||
// which may be a relative name within some scope.
|
|
||||||
//
|
|
||||||
// Suppose the scope was "fizz.buzz" and the reference was "Foo.Bar",
|
|
||||||
// then the following full names are searched:
|
|
||||||
// * fizz.buzz.Foo.Bar
|
|
||||||
// * fizz.Foo.Bar
|
|
||||||
// * Foo.Bar
|
|
||||||
func (r *resolver) findDescriptor(scope protoreflect.FullName, ref partialName) (protoreflect.Descriptor, error) {
|
|
||||||
if !ref.IsValid() {
|
|
||||||
return nil, errors.New("invalid name reference: %q", ref)
|
|
||||||
}
|
|
||||||
if ref.IsFull() {
|
|
||||||
scope, ref = "", ref[1:]
|
|
||||||
}
|
|
||||||
var foundButNotImported protoreflect.Descriptor
|
|
||||||
for {
|
|
||||||
// Derive the full name to search.
|
|
||||||
s := protoreflect.FullName(ref)
|
|
||||||
if scope != "" {
|
|
||||||
s = scope + "." + s
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the current file for the descriptor.
|
|
||||||
if d, ok := r.local[s]; ok {
|
|
||||||
return d, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the remote registry for the descriptor.
|
|
||||||
d, err := r.remote.FindDescriptorByName(s)
|
|
||||||
if err == nil {
|
|
||||||
// Only allow descriptors covered by one of the imports.
|
|
||||||
if r.imports[d.ParentFile().Path()] {
|
|
||||||
return d, nil
|
|
||||||
}
|
|
||||||
foundButNotImported = d
|
|
||||||
} else if err != protoregistry.NotFound {
|
|
||||||
return nil, errors.Wrap(err, "%q", s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Continue on at a higher level of scoping.
|
|
||||||
if scope == "" {
|
|
||||||
if d := foundButNotImported; d != nil {
|
|
||||||
return nil, errors.New("resolved %q, but %q is not imported", d.FullName(), d.ParentFile().Path())
|
|
||||||
}
|
|
||||||
return nil, protoregistry.NotFound
|
|
||||||
}
|
|
||||||
scope = scope.Parent()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *resolver) findEnumDescriptor(scope protoreflect.FullName, ref partialName, isWeak bool) (protoreflect.EnumDescriptor, error) {
|
|
||||||
d, err := r.findDescriptor(scope, ref)
|
|
||||||
if err == protoregistry.NotFound && (r.allowUnresolvable || isWeak) {
|
|
||||||
return filedesc.PlaceholderEnum(ref.FullName()), nil
|
|
||||||
} else if err == protoregistry.NotFound {
|
|
||||||
return nil, errors.New("%q not found", ref.FullName())
|
|
||||||
} else if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ed, ok := d.(protoreflect.EnumDescriptor)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("resolved %q, but it is not an enum", d.FullName())
|
|
||||||
}
|
|
||||||
return ed, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *resolver) findMessageDescriptor(scope protoreflect.FullName, ref partialName, isWeak bool) (protoreflect.MessageDescriptor, error) {
|
|
||||||
d, err := r.findDescriptor(scope, ref)
|
|
||||||
if err == protoregistry.NotFound && (r.allowUnresolvable || isWeak) {
|
|
||||||
return filedesc.PlaceholderMessage(ref.FullName()), nil
|
|
||||||
} else if err == protoregistry.NotFound {
|
|
||||||
return nil, errors.New("%q not found", ref.FullName())
|
|
||||||
} else if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
md, ok := d.(protoreflect.MessageDescriptor)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("resolved %q, but it is not an message", d.FullName())
|
|
||||||
}
|
|
||||||
return md, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// partialName is the partial name. A leading dot means that the name is full,
|
|
||||||
// otherwise the name is relative to some current scope.
|
|
||||||
// See google.protobuf.FieldDescriptorProto.type_name.
|
|
||||||
type partialName string
|
|
||||||
|
|
||||||
func (s partialName) IsFull() bool {
|
|
||||||
return len(s) > 0 && s[0] == '.'
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s partialName) IsValid() bool {
|
|
||||||
if s.IsFull() {
|
|
||||||
return protoreflect.FullName(s[1:]).IsValid()
|
|
||||||
}
|
|
||||||
return protoreflect.FullName(s).IsValid()
|
|
||||||
}
|
|
||||||
|
|
||||||
const unknownPrefix = "*."
|
|
||||||
|
|
||||||
// FullName converts the partial name to a full name on a best-effort basis.
|
|
||||||
// If relative, it creates an invalid full name, using a "*." prefix
|
|
||||||
// to indicate that the start of the full name is unknown.
|
|
||||||
func (s partialName) FullName() protoreflect.FullName {
|
|
||||||
if s.IsFull() {
|
|
||||||
return protoreflect.FullName(s[1:])
|
|
||||||
}
|
|
||||||
return protoreflect.FullName(unknownPrefix + s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmarshalDefault(s string, fd protoreflect.FieldDescriptor, allowUnresolvable bool) (protoreflect.Value, protoreflect.EnumValueDescriptor, error) {
|
|
||||||
var evs protoreflect.EnumValueDescriptors
|
|
||||||
if fd.Enum() != nil {
|
|
||||||
evs = fd.Enum().Values()
|
|
||||||
}
|
|
||||||
v, ev, err := defval.Unmarshal(s, fd.Kind(), evs, defval.Descriptor)
|
|
||||||
if err != nil && allowUnresolvable && evs != nil && protoreflect.Name(s).IsValid() {
|
|
||||||
v = protoreflect.ValueOfEnum(0)
|
|
||||||
if evs.Len() > 0 {
|
|
||||||
v = protoreflect.ValueOfEnum(evs.Get(0).Number())
|
|
||||||
}
|
|
||||||
ev = filedesc.PlaceholderEnumValue(fd.Enum().FullName().Parent().Append(protoreflect.Name(s)))
|
|
||||||
} else if err != nil {
|
|
||||||
return v, ev, err
|
|
||||||
}
|
|
||||||
if fd.Syntax() == protoreflect.Proto3 {
|
|
||||||
return v, ev, errors.New("cannot be specified under proto3 semantics")
|
|
||||||
}
|
|
||||||
if fd.Kind() == protoreflect.MessageKind || fd.Kind() == protoreflect.GroupKind || fd.Cardinality() == protoreflect.Repeated {
|
|
||||||
return v, ev, errors.New("cannot be specified on composite types")
|
|
||||||
}
|
|
||||||
return v, ev, nil
|
|
||||||
}
|
|
374
vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go
generated
vendored
374
vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go
generated
vendored
@ -1,374 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package protodesc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
"unicode"
|
|
||||||
|
|
||||||
"google.golang.org/protobuf/encoding/protowire"
|
|
||||||
"google.golang.org/protobuf/internal/errors"
|
|
||||||
"google.golang.org/protobuf/internal/filedesc"
|
|
||||||
"google.golang.org/protobuf/internal/flags"
|
|
||||||
"google.golang.org/protobuf/internal/genid"
|
|
||||||
"google.golang.org/protobuf/internal/strs"
|
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
|
|
||||||
"google.golang.org/protobuf/types/descriptorpb"
|
|
||||||
)
|
|
||||||
|
|
||||||
func validateEnumDeclarations(es []filedesc.Enum, eds []*descriptorpb.EnumDescriptorProto) error {
|
|
||||||
for i, ed := range eds {
|
|
||||||
e := &es[i]
|
|
||||||
if err := e.L2.ReservedNames.CheckValid(); err != nil {
|
|
||||||
return errors.New("enum %q reserved names has %v", e.FullName(), err)
|
|
||||||
}
|
|
||||||
if err := e.L2.ReservedRanges.CheckValid(); err != nil {
|
|
||||||
return errors.New("enum %q reserved ranges has %v", e.FullName(), err)
|
|
||||||
}
|
|
||||||
if len(ed.GetValue()) == 0 {
|
|
||||||
return errors.New("enum %q must contain at least one value declaration", e.FullName())
|
|
||||||
}
|
|
||||||
allowAlias := ed.GetOptions().GetAllowAlias()
|
|
||||||
foundAlias := false
|
|
||||||
for i := 0; i < e.Values().Len(); i++ {
|
|
||||||
v1 := e.Values().Get(i)
|
|
||||||
if v2 := e.Values().ByNumber(v1.Number()); v1 != v2 {
|
|
||||||
foundAlias = true
|
|
||||||
if !allowAlias {
|
|
||||||
return errors.New("enum %q has conflicting non-aliased values on number %d: %q with %q", e.FullName(), v1.Number(), v1.Name(), v2.Name())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if allowAlias && !foundAlias {
|
|
||||||
return errors.New("enum %q allows aliases, but none were found", e.FullName())
|
|
||||||
}
|
|
||||||
if e.Syntax() == protoreflect.Proto3 {
|
|
||||||
if v := e.Values().Get(0); v.Number() != 0 {
|
|
||||||
return errors.New("enum %q using proto3 semantics must have zero number for the first value", v.FullName())
|
|
||||||
}
|
|
||||||
// Verify that value names in proto3 do not conflict if the
|
|
||||||
// case-insensitive prefix is removed.
|
|
||||||
// See protoc v3.8.0: src/google/protobuf/descriptor.cc:4991-5055
|
|
||||||
names := map[string]protoreflect.EnumValueDescriptor{}
|
|
||||||
prefix := strings.Replace(strings.ToLower(string(e.Name())), "_", "", -1)
|
|
||||||
for i := 0; i < e.Values().Len(); i++ {
|
|
||||||
v1 := e.Values().Get(i)
|
|
||||||
s := strs.EnumValueName(strs.TrimEnumPrefix(string(v1.Name()), prefix))
|
|
||||||
if v2, ok := names[s]; ok && v1.Number() != v2.Number() {
|
|
||||||
return errors.New("enum %q using proto3 semantics has conflict: %q with %q", e.FullName(), v1.Name(), v2.Name())
|
|
||||||
}
|
|
||||||
names[s] = v1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for j, vd := range ed.GetValue() {
|
|
||||||
v := &e.L2.Values.List[j]
|
|
||||||
if vd.Number == nil {
|
|
||||||
return errors.New("enum value %q must have a specified number", v.FullName())
|
|
||||||
}
|
|
||||||
if e.L2.ReservedNames.Has(v.Name()) {
|
|
||||||
return errors.New("enum value %q must not use reserved name", v.FullName())
|
|
||||||
}
|
|
||||||
if e.L2.ReservedRanges.Has(v.Number()) {
|
|
||||||
return errors.New("enum value %q must not use reserved number %d", v.FullName(), v.Number())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateMessageDeclarations(ms []filedesc.Message, mds []*descriptorpb.DescriptorProto) error {
|
|
||||||
for i, md := range mds {
|
|
||||||
m := &ms[i]
|
|
||||||
|
|
||||||
// Handle the message descriptor itself.
|
|
||||||
isMessageSet := md.GetOptions().GetMessageSetWireFormat()
|
|
||||||
if err := m.L2.ReservedNames.CheckValid(); err != nil {
|
|
||||||
return errors.New("message %q reserved names has %v", m.FullName(), err)
|
|
||||||
}
|
|
||||||
if err := m.L2.ReservedRanges.CheckValid(isMessageSet); err != nil {
|
|
||||||
return errors.New("message %q reserved ranges has %v", m.FullName(), err)
|
|
||||||
}
|
|
||||||
if err := m.L2.ExtensionRanges.CheckValid(isMessageSet); err != nil {
|
|
||||||
return errors.New("message %q extension ranges has %v", m.FullName(), err)
|
|
||||||
}
|
|
||||||
if err := (*filedesc.FieldRanges).CheckOverlap(&m.L2.ReservedRanges, &m.L2.ExtensionRanges); err != nil {
|
|
||||||
return errors.New("message %q reserved and extension ranges has %v", m.FullName(), err)
|
|
||||||
}
|
|
||||||
for i := 0; i < m.Fields().Len(); i++ {
|
|
||||||
f1 := m.Fields().Get(i)
|
|
||||||
if f2 := m.Fields().ByNumber(f1.Number()); f1 != f2 {
|
|
||||||
return errors.New("message %q has conflicting fields: %q with %q", m.FullName(), f1.Name(), f2.Name())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if isMessageSet && !flags.ProtoLegacy {
|
|
||||||
return errors.New("message %q is a MessageSet, which is a legacy proto1 feature that is no longer supported", m.FullName())
|
|
||||||
}
|
|
||||||
if isMessageSet && (m.Syntax() != protoreflect.Proto2 || m.Fields().Len() > 0 || m.ExtensionRanges().Len() == 0) {
|
|
||||||
return errors.New("message %q is an invalid proto1 MessageSet", m.FullName())
|
|
||||||
}
|
|
||||||
if m.Syntax() == protoreflect.Proto3 {
|
|
||||||
if m.ExtensionRanges().Len() > 0 {
|
|
||||||
return errors.New("message %q using proto3 semantics cannot have extension ranges", m.FullName())
|
|
||||||
}
|
|
||||||
// Verify that field names in proto3 do not conflict if lowercased
|
|
||||||
// with all underscores removed.
|
|
||||||
// See protoc v3.8.0: src/google/protobuf/descriptor.cc:5830-5847
|
|
||||||
names := map[string]protoreflect.FieldDescriptor{}
|
|
||||||
for i := 0; i < m.Fields().Len(); i++ {
|
|
||||||
f1 := m.Fields().Get(i)
|
|
||||||
s := strings.Replace(strings.ToLower(string(f1.Name())), "_", "", -1)
|
|
||||||
if f2, ok := names[s]; ok {
|
|
||||||
return errors.New("message %q using proto3 semantics has conflict: %q with %q", m.FullName(), f1.Name(), f2.Name())
|
|
||||||
}
|
|
||||||
names[s] = f1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for j, fd := range md.GetField() {
|
|
||||||
f := &m.L2.Fields.List[j]
|
|
||||||
if m.L2.ReservedNames.Has(f.Name()) {
|
|
||||||
return errors.New("message field %q must not use reserved name", f.FullName())
|
|
||||||
}
|
|
||||||
if !f.Number().IsValid() {
|
|
||||||
return errors.New("message field %q has an invalid number: %d", f.FullName(), f.Number())
|
|
||||||
}
|
|
||||||
if !f.Cardinality().IsValid() {
|
|
||||||
return errors.New("message field %q has an invalid cardinality: %d", f.FullName(), f.Cardinality())
|
|
||||||
}
|
|
||||||
if m.L2.ReservedRanges.Has(f.Number()) {
|
|
||||||
return errors.New("message field %q must not use reserved number %d", f.FullName(), f.Number())
|
|
||||||
}
|
|
||||||
if m.L2.ExtensionRanges.Has(f.Number()) {
|
|
||||||
return errors.New("message field %q with number %d in extension range", f.FullName(), f.Number())
|
|
||||||
}
|
|
||||||
if fd.Extendee != nil {
|
|
||||||
return errors.New("message field %q may not have extendee: %q", f.FullName(), fd.GetExtendee())
|
|
||||||
}
|
|
||||||
if f.L1.IsProto3Optional {
|
|
||||||
if f.Syntax() != protoreflect.Proto3 {
|
|
||||||
return errors.New("message field %q under proto3 optional semantics must be specified in the proto3 syntax", f.FullName())
|
|
||||||
}
|
|
||||||
if f.Cardinality() != protoreflect.Optional {
|
|
||||||
return errors.New("message field %q under proto3 optional semantics must have optional cardinality", f.FullName())
|
|
||||||
}
|
|
||||||
if f.ContainingOneof() != nil && f.ContainingOneof().Fields().Len() != 1 {
|
|
||||||
return errors.New("message field %q under proto3 optional semantics must be within a single element oneof", f.FullName())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if f.IsWeak() && !flags.ProtoLegacy {
|
|
||||||
return errors.New("message field %q is a weak field, which is a legacy proto1 feature that is no longer supported", f.FullName())
|
|
||||||
}
|
|
||||||
if f.IsWeak() && (f.Syntax() != protoreflect.Proto2 || !isOptionalMessage(f) || f.ContainingOneof() != nil) {
|
|
||||||
return errors.New("message field %q may only be weak for an optional message", f.FullName())
|
|
||||||
}
|
|
||||||
if f.IsPacked() && !isPackable(f) {
|
|
||||||
return errors.New("message field %q is not packable", f.FullName())
|
|
||||||
}
|
|
||||||
if err := checkValidGroup(f); err != nil {
|
|
||||||
return errors.New("message field %q is an invalid group: %v", f.FullName(), err)
|
|
||||||
}
|
|
||||||
if err := checkValidMap(f); err != nil {
|
|
||||||
return errors.New("message field %q is an invalid map: %v", f.FullName(), err)
|
|
||||||
}
|
|
||||||
if f.Syntax() == protoreflect.Proto3 {
|
|
||||||
if f.Cardinality() == protoreflect.Required {
|
|
||||||
return errors.New("message field %q using proto3 semantics cannot be required", f.FullName())
|
|
||||||
}
|
|
||||||
if f.Enum() != nil && !f.Enum().IsPlaceholder() && f.Enum().Syntax() != protoreflect.Proto3 {
|
|
||||||
return errors.New("message field %q using proto3 semantics may only depend on a proto3 enum", f.FullName())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
seenSynthetic := false // synthetic oneofs for proto3 optional must come after real oneofs
|
|
||||||
for j := range md.GetOneofDecl() {
|
|
||||||
o := &m.L2.Oneofs.List[j]
|
|
||||||
if o.Fields().Len() == 0 {
|
|
||||||
return errors.New("message oneof %q must contain at least one field declaration", o.FullName())
|
|
||||||
}
|
|
||||||
if n := o.Fields().Len(); n-1 != (o.Fields().Get(n-1).Index() - o.Fields().Get(0).Index()) {
|
|
||||||
return errors.New("message oneof %q must have consecutively declared fields", o.FullName())
|
|
||||||
}
|
|
||||||
|
|
||||||
if o.IsSynthetic() {
|
|
||||||
seenSynthetic = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if !o.IsSynthetic() && seenSynthetic {
|
|
||||||
return errors.New("message oneof %q must be declared before synthetic oneofs", o.FullName())
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < o.Fields().Len(); i++ {
|
|
||||||
f := o.Fields().Get(i)
|
|
||||||
if f.Cardinality() != protoreflect.Optional {
|
|
||||||
return errors.New("message field %q belongs in a oneof and must be optional", f.FullName())
|
|
||||||
}
|
|
||||||
if f.IsWeak() {
|
|
||||||
return errors.New("message field %q belongs in a oneof and must not be a weak reference", f.FullName())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := validateEnumDeclarations(m.L1.Enums.List, md.GetEnumType()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := validateMessageDeclarations(m.L1.Messages.List, md.GetNestedType()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := validateExtensionDeclarations(m.L1.Extensions.List, md.GetExtension()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateExtensionDeclarations(xs []filedesc.Extension, xds []*descriptorpb.FieldDescriptorProto) error {
|
|
||||||
for i, xd := range xds {
|
|
||||||
x := &xs[i]
|
|
||||||
// NOTE: Avoid using the IsValid method since extensions to MessageSet
|
|
||||||
// may have a field number higher than normal. This check only verifies
|
|
||||||
// that the number is not negative or reserved. We check again later
|
|
||||||
// if we know that the extendee is definitely not a MessageSet.
|
|
||||||
if n := x.Number(); n < 0 || (protowire.FirstReservedNumber <= n && n <= protowire.LastReservedNumber) {
|
|
||||||
return errors.New("extension field %q has an invalid number: %d", x.FullName(), x.Number())
|
|
||||||
}
|
|
||||||
if !x.Cardinality().IsValid() || x.Cardinality() == protoreflect.Required {
|
|
||||||
return errors.New("extension field %q has an invalid cardinality: %d", x.FullName(), x.Cardinality())
|
|
||||||
}
|
|
||||||
if xd.JsonName != nil {
|
|
||||||
// A bug in older versions of protoc would always populate the
|
|
||||||
// "json_name" option for extensions when it is meaningless.
|
|
||||||
// When it did so, it would always use the camel-cased field name.
|
|
||||||
if xd.GetJsonName() != strs.JSONCamelCase(string(x.Name())) {
|
|
||||||
return errors.New("extension field %q may not have an explicitly set JSON name: %q", x.FullName(), xd.GetJsonName())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if xd.OneofIndex != nil {
|
|
||||||
return errors.New("extension field %q may not be part of a oneof", x.FullName())
|
|
||||||
}
|
|
||||||
if md := x.ContainingMessage(); !md.IsPlaceholder() {
|
|
||||||
if !md.ExtensionRanges().Has(x.Number()) {
|
|
||||||
return errors.New("extension field %q extends %q with non-extension field number: %d", x.FullName(), md.FullName(), x.Number())
|
|
||||||
}
|
|
||||||
isMessageSet := md.Options().(*descriptorpb.MessageOptions).GetMessageSetWireFormat()
|
|
||||||
if isMessageSet && !isOptionalMessage(x) {
|
|
||||||
return errors.New("extension field %q extends MessageSet and must be an optional message", x.FullName())
|
|
||||||
}
|
|
||||||
if !isMessageSet && !x.Number().IsValid() {
|
|
||||||
return errors.New("extension field %q has an invalid number: %d", x.FullName(), x.Number())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if xd.GetOptions().GetWeak() {
|
|
||||||
return errors.New("extension field %q cannot be a weak reference", x.FullName())
|
|
||||||
}
|
|
||||||
if x.IsPacked() && !isPackable(x) {
|
|
||||||
return errors.New("extension field %q is not packable", x.FullName())
|
|
||||||
}
|
|
||||||
if err := checkValidGroup(x); err != nil {
|
|
||||||
return errors.New("extension field %q is an invalid group: %v", x.FullName(), err)
|
|
||||||
}
|
|
||||||
if md := x.Message(); md != nil && md.IsMapEntry() {
|
|
||||||
return errors.New("extension field %q cannot be a map entry", x.FullName())
|
|
||||||
}
|
|
||||||
if x.Syntax() == protoreflect.Proto3 {
|
|
||||||
switch x.ContainingMessage().FullName() {
|
|
||||||
case (*descriptorpb.FileOptions)(nil).ProtoReflect().Descriptor().FullName():
|
|
||||||
case (*descriptorpb.EnumOptions)(nil).ProtoReflect().Descriptor().FullName():
|
|
||||||
case (*descriptorpb.EnumValueOptions)(nil).ProtoReflect().Descriptor().FullName():
|
|
||||||
case (*descriptorpb.MessageOptions)(nil).ProtoReflect().Descriptor().FullName():
|
|
||||||
case (*descriptorpb.FieldOptions)(nil).ProtoReflect().Descriptor().FullName():
|
|
||||||
case (*descriptorpb.OneofOptions)(nil).ProtoReflect().Descriptor().FullName():
|
|
||||||
case (*descriptorpb.ExtensionRangeOptions)(nil).ProtoReflect().Descriptor().FullName():
|
|
||||||
case (*descriptorpb.ServiceOptions)(nil).ProtoReflect().Descriptor().FullName():
|
|
||||||
case (*descriptorpb.MethodOptions)(nil).ProtoReflect().Descriptor().FullName():
|
|
||||||
default:
|
|
||||||
return errors.New("extension field %q cannot be declared in proto3 unless extended descriptor options", x.FullName())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// isOptionalMessage reports whether this is an optional message.
|
|
||||||
// If the kind is unknown, it is assumed to be a message.
|
|
||||||
func isOptionalMessage(fd protoreflect.FieldDescriptor) bool {
|
|
||||||
return (fd.Kind() == 0 || fd.Kind() == protoreflect.MessageKind) && fd.Cardinality() == protoreflect.Optional
|
|
||||||
}
|
|
||||||
|
|
||||||
// isPackable checks whether the pack option can be specified.
|
|
||||||
func isPackable(fd protoreflect.FieldDescriptor) bool {
|
|
||||||
switch fd.Kind() {
|
|
||||||
case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind, protoreflect.GroupKind:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return fd.IsList()
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkValidGroup reports whether fd is a valid group according to the same
|
|
||||||
// rules that protoc imposes.
|
|
||||||
func checkValidGroup(fd protoreflect.FieldDescriptor) error {
|
|
||||||
md := fd.Message()
|
|
||||||
switch {
|
|
||||||
case fd.Kind() != protoreflect.GroupKind:
|
|
||||||
return nil
|
|
||||||
case fd.Syntax() != protoreflect.Proto2:
|
|
||||||
return errors.New("invalid under proto2 semantics")
|
|
||||||
case md == nil || md.IsPlaceholder():
|
|
||||||
return errors.New("message must be resolvable")
|
|
||||||
case fd.FullName().Parent() != md.FullName().Parent():
|
|
||||||
return errors.New("message and field must be declared in the same scope")
|
|
||||||
case !unicode.IsUpper(rune(md.Name()[0])):
|
|
||||||
return errors.New("message name must start with an uppercase")
|
|
||||||
case fd.Name() != protoreflect.Name(strings.ToLower(string(md.Name()))):
|
|
||||||
return errors.New("field name must be lowercased form of the message name")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkValidMap checks whether the field is a valid map according to the same
|
|
||||||
// rules that protoc imposes.
|
|
||||||
// See protoc v3.8.0: src/google/protobuf/descriptor.cc:6045-6115
|
|
||||||
func checkValidMap(fd protoreflect.FieldDescriptor) error {
|
|
||||||
md := fd.Message()
|
|
||||||
switch {
|
|
||||||
case md == nil || !md.IsMapEntry():
|
|
||||||
return nil
|
|
||||||
case fd.FullName().Parent() != md.FullName().Parent():
|
|
||||||
return errors.New("message and field must be declared in the same scope")
|
|
||||||
case md.Name() != protoreflect.Name(strs.MapEntryName(string(fd.Name()))):
|
|
||||||
return errors.New("incorrect implicit map entry name")
|
|
||||||
case fd.Cardinality() != protoreflect.Repeated:
|
|
||||||
return errors.New("field must be repeated")
|
|
||||||
case md.Fields().Len() != 2:
|
|
||||||
return errors.New("message must have exactly two fields")
|
|
||||||
case md.ExtensionRanges().Len() > 0:
|
|
||||||
return errors.New("message must not have any extension ranges")
|
|
||||||
case md.Enums().Len()+md.Messages().Len()+md.Extensions().Len() > 0:
|
|
||||||
return errors.New("message must not have any nested declarations")
|
|
||||||
}
|
|
||||||
kf := md.Fields().Get(0)
|
|
||||||
vf := md.Fields().Get(1)
|
|
||||||
switch {
|
|
||||||
case kf.Name() != genid.MapEntry_Key_field_name || kf.Number() != genid.MapEntry_Key_field_number || kf.Cardinality() != protoreflect.Optional || kf.ContainingOneof() != nil || kf.HasDefault():
|
|
||||||
return errors.New("invalid key field")
|
|
||||||
case vf.Name() != genid.MapEntry_Value_field_name || vf.Number() != genid.MapEntry_Value_field_number || vf.Cardinality() != protoreflect.Optional || vf.ContainingOneof() != nil || vf.HasDefault():
|
|
||||||
return errors.New("invalid value field")
|
|
||||||
}
|
|
||||||
switch kf.Kind() {
|
|
||||||
case protoreflect.BoolKind: // bool
|
|
||||||
case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: // int32
|
|
||||||
case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: // int64
|
|
||||||
case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: // uint32
|
|
||||||
case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: // uint64
|
|
||||||
case protoreflect.StringKind: // string
|
|
||||||
default:
|
|
||||||
return errors.New("invalid key kind: %v", kf.Kind())
|
|
||||||
}
|
|
||||||
if e := vf.Enum(); e != nil && e.Values().Len() > 0 && e.Values().Get(0).Number() != 0 {
|
|
||||||
return errors.New("map enum value must have zero number for the first value")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
252
vendor/google.golang.org/protobuf/reflect/protodesc/proto.go
generated
vendored
252
vendor/google.golang.org/protobuf/reflect/protodesc/proto.go
generated
vendored
@ -1,252 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package protodesc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"google.golang.org/protobuf/internal/encoding/defval"
|
|
||||||
"google.golang.org/protobuf/internal/strs"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
|
|
||||||
"google.golang.org/protobuf/types/descriptorpb"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ToFileDescriptorProto copies a protoreflect.FileDescriptor into a
|
|
||||||
// google.protobuf.FileDescriptorProto message.
|
|
||||||
func ToFileDescriptorProto(file protoreflect.FileDescriptor) *descriptorpb.FileDescriptorProto {
|
|
||||||
p := &descriptorpb.FileDescriptorProto{
|
|
||||||
Name: proto.String(file.Path()),
|
|
||||||
Options: proto.Clone(file.Options()).(*descriptorpb.FileOptions),
|
|
||||||
}
|
|
||||||
if file.Package() != "" {
|
|
||||||
p.Package = proto.String(string(file.Package()))
|
|
||||||
}
|
|
||||||
for i, imports := 0, file.Imports(); i < imports.Len(); i++ {
|
|
||||||
imp := imports.Get(i)
|
|
||||||
p.Dependency = append(p.Dependency, imp.Path())
|
|
||||||
if imp.IsPublic {
|
|
||||||
p.PublicDependency = append(p.PublicDependency, int32(i))
|
|
||||||
}
|
|
||||||
if imp.IsWeak {
|
|
||||||
p.WeakDependency = append(p.WeakDependency, int32(i))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i, locs := 0, file.SourceLocations(); i < locs.Len(); i++ {
|
|
||||||
loc := locs.Get(i)
|
|
||||||
l := &descriptorpb.SourceCodeInfo_Location{}
|
|
||||||
l.Path = append(l.Path, loc.Path...)
|
|
||||||
if loc.StartLine == loc.EndLine {
|
|
||||||
l.Span = []int32{int32(loc.StartLine), int32(loc.StartColumn), int32(loc.EndColumn)}
|
|
||||||
} else {
|
|
||||||
l.Span = []int32{int32(loc.StartLine), int32(loc.StartColumn), int32(loc.EndLine), int32(loc.EndColumn)}
|
|
||||||
}
|
|
||||||
l.LeadingDetachedComments = append([]string(nil), loc.LeadingDetachedComments...)
|
|
||||||
if loc.LeadingComments != "" {
|
|
||||||
l.LeadingComments = proto.String(loc.LeadingComments)
|
|
||||||
}
|
|
||||||
if loc.TrailingComments != "" {
|
|
||||||
l.TrailingComments = proto.String(loc.TrailingComments)
|
|
||||||
}
|
|
||||||
if p.SourceCodeInfo == nil {
|
|
||||||
p.SourceCodeInfo = &descriptorpb.SourceCodeInfo{}
|
|
||||||
}
|
|
||||||
p.SourceCodeInfo.Location = append(p.SourceCodeInfo.Location, l)
|
|
||||||
|
|
||||||
}
|
|
||||||
for i, messages := 0, file.Messages(); i < messages.Len(); i++ {
|
|
||||||
p.MessageType = append(p.MessageType, ToDescriptorProto(messages.Get(i)))
|
|
||||||
}
|
|
||||||
for i, enums := 0, file.Enums(); i < enums.Len(); i++ {
|
|
||||||
p.EnumType = append(p.EnumType, ToEnumDescriptorProto(enums.Get(i)))
|
|
||||||
}
|
|
||||||
for i, services := 0, file.Services(); i < services.Len(); i++ {
|
|
||||||
p.Service = append(p.Service, ToServiceDescriptorProto(services.Get(i)))
|
|
||||||
}
|
|
||||||
for i, exts := 0, file.Extensions(); i < exts.Len(); i++ {
|
|
||||||
p.Extension = append(p.Extension, ToFieldDescriptorProto(exts.Get(i)))
|
|
||||||
}
|
|
||||||
if syntax := file.Syntax(); syntax != protoreflect.Proto2 {
|
|
||||||
p.Syntax = proto.String(file.Syntax().String())
|
|
||||||
}
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToDescriptorProto copies a protoreflect.MessageDescriptor into a
|
|
||||||
// google.protobuf.DescriptorProto message.
|
|
||||||
func ToDescriptorProto(message protoreflect.MessageDescriptor) *descriptorpb.DescriptorProto {
|
|
||||||
p := &descriptorpb.DescriptorProto{
|
|
||||||
Name: proto.String(string(message.Name())),
|
|
||||||
Options: proto.Clone(message.Options()).(*descriptorpb.MessageOptions),
|
|
||||||
}
|
|
||||||
for i, fields := 0, message.Fields(); i < fields.Len(); i++ {
|
|
||||||
p.Field = append(p.Field, ToFieldDescriptorProto(fields.Get(i)))
|
|
||||||
}
|
|
||||||
for i, exts := 0, message.Extensions(); i < exts.Len(); i++ {
|
|
||||||
p.Extension = append(p.Extension, ToFieldDescriptorProto(exts.Get(i)))
|
|
||||||
}
|
|
||||||
for i, messages := 0, message.Messages(); i < messages.Len(); i++ {
|
|
||||||
p.NestedType = append(p.NestedType, ToDescriptorProto(messages.Get(i)))
|
|
||||||
}
|
|
||||||
for i, enums := 0, message.Enums(); i < enums.Len(); i++ {
|
|
||||||
p.EnumType = append(p.EnumType, ToEnumDescriptorProto(enums.Get(i)))
|
|
||||||
}
|
|
||||||
for i, xranges := 0, message.ExtensionRanges(); i < xranges.Len(); i++ {
|
|
||||||
xrange := xranges.Get(i)
|
|
||||||
p.ExtensionRange = append(p.ExtensionRange, &descriptorpb.DescriptorProto_ExtensionRange{
|
|
||||||
Start: proto.Int32(int32(xrange[0])),
|
|
||||||
End: proto.Int32(int32(xrange[1])),
|
|
||||||
Options: proto.Clone(message.ExtensionRangeOptions(i)).(*descriptorpb.ExtensionRangeOptions),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
for i, oneofs := 0, message.Oneofs(); i < oneofs.Len(); i++ {
|
|
||||||
p.OneofDecl = append(p.OneofDecl, ToOneofDescriptorProto(oneofs.Get(i)))
|
|
||||||
}
|
|
||||||
for i, ranges := 0, message.ReservedRanges(); i < ranges.Len(); i++ {
|
|
||||||
rrange := ranges.Get(i)
|
|
||||||
p.ReservedRange = append(p.ReservedRange, &descriptorpb.DescriptorProto_ReservedRange{
|
|
||||||
Start: proto.Int32(int32(rrange[0])),
|
|
||||||
End: proto.Int32(int32(rrange[1])),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
for i, names := 0, message.ReservedNames(); i < names.Len(); i++ {
|
|
||||||
p.ReservedName = append(p.ReservedName, string(names.Get(i)))
|
|
||||||
}
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToFieldDescriptorProto copies a protoreflect.FieldDescriptor into a
|
|
||||||
// google.protobuf.FieldDescriptorProto message.
|
|
||||||
func ToFieldDescriptorProto(field protoreflect.FieldDescriptor) *descriptorpb.FieldDescriptorProto {
|
|
||||||
p := &descriptorpb.FieldDescriptorProto{
|
|
||||||
Name: proto.String(string(field.Name())),
|
|
||||||
Number: proto.Int32(int32(field.Number())),
|
|
||||||
Label: descriptorpb.FieldDescriptorProto_Label(field.Cardinality()).Enum(),
|
|
||||||
Options: proto.Clone(field.Options()).(*descriptorpb.FieldOptions),
|
|
||||||
}
|
|
||||||
if field.IsExtension() {
|
|
||||||
p.Extendee = fullNameOf(field.ContainingMessage())
|
|
||||||
}
|
|
||||||
if field.Kind().IsValid() {
|
|
||||||
p.Type = descriptorpb.FieldDescriptorProto_Type(field.Kind()).Enum()
|
|
||||||
}
|
|
||||||
if field.Enum() != nil {
|
|
||||||
p.TypeName = fullNameOf(field.Enum())
|
|
||||||
}
|
|
||||||
if field.Message() != nil {
|
|
||||||
p.TypeName = fullNameOf(field.Message())
|
|
||||||
}
|
|
||||||
if field.HasJSONName() {
|
|
||||||
// A bug in older versions of protoc would always populate the
|
|
||||||
// "json_name" option for extensions when it is meaningless.
|
|
||||||
// When it did so, it would always use the camel-cased field name.
|
|
||||||
if field.IsExtension() {
|
|
||||||
p.JsonName = proto.String(strs.JSONCamelCase(string(field.Name())))
|
|
||||||
} else {
|
|
||||||
p.JsonName = proto.String(field.JSONName())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if field.Syntax() == protoreflect.Proto3 && field.HasOptionalKeyword() {
|
|
||||||
p.Proto3Optional = proto.Bool(true)
|
|
||||||
}
|
|
||||||
if field.HasDefault() {
|
|
||||||
def, err := defval.Marshal(field.Default(), field.DefaultEnumValue(), field.Kind(), defval.Descriptor)
|
|
||||||
if err != nil && field.DefaultEnumValue() != nil {
|
|
||||||
def = string(field.DefaultEnumValue().Name()) // occurs for unresolved enum values
|
|
||||||
} else if err != nil {
|
|
||||||
panic(fmt.Sprintf("%v: %v", field.FullName(), err))
|
|
||||||
}
|
|
||||||
p.DefaultValue = proto.String(def)
|
|
||||||
}
|
|
||||||
if oneof := field.ContainingOneof(); oneof != nil {
|
|
||||||
p.OneofIndex = proto.Int32(int32(oneof.Index()))
|
|
||||||
}
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToOneofDescriptorProto copies a protoreflect.OneofDescriptor into a
|
|
||||||
// google.protobuf.OneofDescriptorProto message.
|
|
||||||
func ToOneofDescriptorProto(oneof protoreflect.OneofDescriptor) *descriptorpb.OneofDescriptorProto {
|
|
||||||
return &descriptorpb.OneofDescriptorProto{
|
|
||||||
Name: proto.String(string(oneof.Name())),
|
|
||||||
Options: proto.Clone(oneof.Options()).(*descriptorpb.OneofOptions),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToEnumDescriptorProto copies a protoreflect.EnumDescriptor into a
|
|
||||||
// google.protobuf.EnumDescriptorProto message.
|
|
||||||
func ToEnumDescriptorProto(enum protoreflect.EnumDescriptor) *descriptorpb.EnumDescriptorProto {
|
|
||||||
p := &descriptorpb.EnumDescriptorProto{
|
|
||||||
Name: proto.String(string(enum.Name())),
|
|
||||||
Options: proto.Clone(enum.Options()).(*descriptorpb.EnumOptions),
|
|
||||||
}
|
|
||||||
for i, values := 0, enum.Values(); i < values.Len(); i++ {
|
|
||||||
p.Value = append(p.Value, ToEnumValueDescriptorProto(values.Get(i)))
|
|
||||||
}
|
|
||||||
for i, ranges := 0, enum.ReservedRanges(); i < ranges.Len(); i++ {
|
|
||||||
rrange := ranges.Get(i)
|
|
||||||
p.ReservedRange = append(p.ReservedRange, &descriptorpb.EnumDescriptorProto_EnumReservedRange{
|
|
||||||
Start: proto.Int32(int32(rrange[0])),
|
|
||||||
End: proto.Int32(int32(rrange[1])),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
for i, names := 0, enum.ReservedNames(); i < names.Len(); i++ {
|
|
||||||
p.ReservedName = append(p.ReservedName, string(names.Get(i)))
|
|
||||||
}
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToEnumValueDescriptorProto copies a protoreflect.EnumValueDescriptor into a
|
|
||||||
// google.protobuf.EnumValueDescriptorProto message.
|
|
||||||
func ToEnumValueDescriptorProto(value protoreflect.EnumValueDescriptor) *descriptorpb.EnumValueDescriptorProto {
|
|
||||||
return &descriptorpb.EnumValueDescriptorProto{
|
|
||||||
Name: proto.String(string(value.Name())),
|
|
||||||
Number: proto.Int32(int32(value.Number())),
|
|
||||||
Options: proto.Clone(value.Options()).(*descriptorpb.EnumValueOptions),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToServiceDescriptorProto copies a protoreflect.ServiceDescriptor into a
|
|
||||||
// google.protobuf.ServiceDescriptorProto message.
|
|
||||||
func ToServiceDescriptorProto(service protoreflect.ServiceDescriptor) *descriptorpb.ServiceDescriptorProto {
|
|
||||||
p := &descriptorpb.ServiceDescriptorProto{
|
|
||||||
Name: proto.String(string(service.Name())),
|
|
||||||
Options: proto.Clone(service.Options()).(*descriptorpb.ServiceOptions),
|
|
||||||
}
|
|
||||||
for i, methods := 0, service.Methods(); i < methods.Len(); i++ {
|
|
||||||
p.Method = append(p.Method, ToMethodDescriptorProto(methods.Get(i)))
|
|
||||||
}
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// ToMethodDescriptorProto copies a protoreflect.MethodDescriptor into a
|
|
||||||
// google.protobuf.MethodDescriptorProto message.
|
|
||||||
func ToMethodDescriptorProto(method protoreflect.MethodDescriptor) *descriptorpb.MethodDescriptorProto {
|
|
||||||
p := &descriptorpb.MethodDescriptorProto{
|
|
||||||
Name: proto.String(string(method.Name())),
|
|
||||||
InputType: fullNameOf(method.Input()),
|
|
||||||
OutputType: fullNameOf(method.Output()),
|
|
||||||
Options: proto.Clone(method.Options()).(*descriptorpb.MethodOptions),
|
|
||||||
}
|
|
||||||
if method.IsStreamingClient() {
|
|
||||||
p.ClientStreaming = proto.Bool(true)
|
|
||||||
}
|
|
||||||
if method.IsStreamingServer() {
|
|
||||||
p.ServerStreaming = proto.Bool(true)
|
|
||||||
}
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
func fullNameOf(d protoreflect.Descriptor) *string {
|
|
||||||
if d == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(string(d.FullName()), unknownPrefix) {
|
|
||||||
return proto.String(string(d.FullName()[len(unknownPrefix):]))
|
|
||||||
}
|
|
||||||
return proto.String("." + string(d.FullName()))
|
|
||||||
}
|
|
39
vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go
generated
vendored
39
vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go
generated
vendored
@ -94,7 +94,8 @@ type Files struct {
|
|||||||
// Note that enum values are in the top-level since that are in the same
|
// Note that enum values are in the top-level since that are in the same
|
||||||
// scope as the parent enum.
|
// scope as the parent enum.
|
||||||
descsByName map[protoreflect.FullName]interface{}
|
descsByName map[protoreflect.FullName]interface{}
|
||||||
filesByPath map[string]protoreflect.FileDescriptor
|
filesByPath map[string][]protoreflect.FileDescriptor
|
||||||
|
numFiles int
|
||||||
}
|
}
|
||||||
|
|
||||||
type packageDescriptor struct {
|
type packageDescriptor struct {
|
||||||
@ -117,18 +118,17 @@ func (r *Files) RegisterFile(file protoreflect.FileDescriptor) error {
|
|||||||
r.descsByName = map[protoreflect.FullName]interface{}{
|
r.descsByName = map[protoreflect.FullName]interface{}{
|
||||||
"": &packageDescriptor{},
|
"": &packageDescriptor{},
|
||||||
}
|
}
|
||||||
r.filesByPath = make(map[string]protoreflect.FileDescriptor)
|
r.filesByPath = make(map[string][]protoreflect.FileDescriptor)
|
||||||
}
|
}
|
||||||
path := file.Path()
|
path := file.Path()
|
||||||
if prev := r.filesByPath[path]; prev != nil {
|
if prev := r.filesByPath[path]; len(prev) > 0 {
|
||||||
r.checkGenProtoConflict(path)
|
r.checkGenProtoConflict(path)
|
||||||
err := errors.New("file %q is already registered", file.Path())
|
err := errors.New("file %q is already registered", file.Path())
|
||||||
err = amendErrorWithCaller(err, prev, file)
|
err = amendErrorWithCaller(err, prev[0], file)
|
||||||
if r == GlobalFiles && ignoreConflict(file, err) {
|
if !(r == GlobalFiles && ignoreConflict(file, err)) {
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for name := file.Package(); name != ""; name = name.Parent() {
|
for name := file.Package(); name != ""; name = name.Parent() {
|
||||||
switch prev := r.descsByName[name]; prev.(type) {
|
switch prev := r.descsByName[name]; prev.(type) {
|
||||||
@ -168,7 +168,8 @@ func (r *Files) RegisterFile(file protoreflect.FileDescriptor) error {
|
|||||||
rangeTopLevelDescriptors(file, func(d protoreflect.Descriptor) {
|
rangeTopLevelDescriptors(file, func(d protoreflect.Descriptor) {
|
||||||
r.descsByName[d.FullName()] = d
|
r.descsByName[d.FullName()] = d
|
||||||
})
|
})
|
||||||
r.filesByPath[path] = file
|
r.filesByPath[path] = append(r.filesByPath[path], file)
|
||||||
|
r.numFiles++
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,6 +309,7 @@ func (s *nameSuffix) Pop() (name protoreflect.Name) {
|
|||||||
// FindFileByPath looks up a file by the path.
|
// FindFileByPath looks up a file by the path.
|
||||||
//
|
//
|
||||||
// This returns (nil, NotFound) if not found.
|
// This returns (nil, NotFound) if not found.
|
||||||
|
// This returns an error if multiple files have the same path.
|
||||||
func (r *Files) FindFileByPath(path string) (protoreflect.FileDescriptor, error) {
|
func (r *Files) FindFileByPath(path string) (protoreflect.FileDescriptor, error) {
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return nil, NotFound
|
return nil, NotFound
|
||||||
@ -316,13 +318,19 @@ func (r *Files) FindFileByPath(path string) (protoreflect.FileDescriptor, error)
|
|||||||
globalMutex.RLock()
|
globalMutex.RLock()
|
||||||
defer globalMutex.RUnlock()
|
defer globalMutex.RUnlock()
|
||||||
}
|
}
|
||||||
if fd, ok := r.filesByPath[path]; ok {
|
fds := r.filesByPath[path]
|
||||||
return fd, nil
|
switch len(fds) {
|
||||||
}
|
case 0:
|
||||||
return nil, NotFound
|
return nil, NotFound
|
||||||
|
case 1:
|
||||||
|
return fds[0], nil
|
||||||
|
default:
|
||||||
|
return nil, errors.New("multiple files named %q", path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NumFiles reports the number of registered files.
|
// NumFiles reports the number of registered files,
|
||||||
|
// including duplicate files with the same name.
|
||||||
func (r *Files) NumFiles() int {
|
func (r *Files) NumFiles() int {
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return 0
|
return 0
|
||||||
@ -331,10 +339,11 @@ func (r *Files) NumFiles() int {
|
|||||||
globalMutex.RLock()
|
globalMutex.RLock()
|
||||||
defer globalMutex.RUnlock()
|
defer globalMutex.RUnlock()
|
||||||
}
|
}
|
||||||
return len(r.filesByPath)
|
return r.numFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
// RangeFiles iterates over all registered files while f returns true.
|
// RangeFiles iterates over all registered files while f returns true.
|
||||||
|
// If multiple files have the same name, RangeFiles iterates over all of them.
|
||||||
// The iteration order is undefined.
|
// The iteration order is undefined.
|
||||||
func (r *Files) RangeFiles(f func(protoreflect.FileDescriptor) bool) {
|
func (r *Files) RangeFiles(f func(protoreflect.FileDescriptor) bool) {
|
||||||
if r == nil {
|
if r == nil {
|
||||||
@ -344,12 +353,14 @@ func (r *Files) RangeFiles(f func(protoreflect.FileDescriptor) bool) {
|
|||||||
globalMutex.RLock()
|
globalMutex.RLock()
|
||||||
defer globalMutex.RUnlock()
|
defer globalMutex.RUnlock()
|
||||||
}
|
}
|
||||||
for _, file := range r.filesByPath {
|
for _, files := range r.filesByPath {
|
||||||
|
for _, file := range files {
|
||||||
if !f(file) {
|
if !f(file) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NumFilesByPackage reports the number of registered files in a proto package.
|
// NumFilesByPackage reports the number of registered files in a proto package.
|
||||||
func (r *Files) NumFilesByPackage(name protoreflect.FullName) int {
|
func (r *Files) NumFilesByPackage(name protoreflect.FullName) int {
|
||||||
|
4039
vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go
generated
vendored
4039
vendor/google.golang.org/protobuf/types/descriptorpb/descriptor.pb.go
generated
vendored
File diff suppressed because it is too large
Load Diff
50
vendor/modules.txt
vendored
50
vendor/modules.txt
vendored
@ -1,8 +1,8 @@
|
|||||||
# github.com/cyrilix/robocar-base v0.1.5
|
# github.com/cyrilix/robocar-base v0.1.6
|
||||||
## explicit; go 1.17
|
## explicit; go 1.17
|
||||||
github.com/cyrilix/robocar-base/cli
|
github.com/cyrilix/robocar-base/cli
|
||||||
github.com/cyrilix/robocar-base/service
|
github.com/cyrilix/robocar-base/service
|
||||||
# github.com/cyrilix/robocar-protobuf/go v1.0.3
|
# github.com/cyrilix/robocar-protobuf/go v1.0.4
|
||||||
## explicit; go 1.17
|
## explicit; go 1.17
|
||||||
github.com/cyrilix/robocar-protobuf/go/events
|
github.com/cyrilix/robocar-protobuf/go/events
|
||||||
# github.com/disintegration/imaging v1.6.2
|
# github.com/disintegration/imaging v1.6.2
|
||||||
@ -12,9 +12,15 @@ github.com/disintegration/imaging
|
|||||||
## explicit; go 1.14
|
## explicit; go 1.14
|
||||||
github.com/eclipse/paho.mqtt.golang
|
github.com/eclipse/paho.mqtt.golang
|
||||||
github.com/eclipse/paho.mqtt.golang/packets
|
github.com/eclipse/paho.mqtt.golang/packets
|
||||||
|
# github.com/go-logr/logr v1.2.1
|
||||||
|
## explicit; go 1.16
|
||||||
|
github.com/go-logr/logr
|
||||||
|
github.com/go-logr/logr/funcr
|
||||||
|
# github.com/go-logr/stdr v1.2.0
|
||||||
|
## explicit; go 1.16
|
||||||
|
github.com/go-logr/stdr
|
||||||
# github.com/golang/protobuf v1.5.2
|
# github.com/golang/protobuf v1.5.2
|
||||||
## explicit; go 1.9
|
## explicit; go 1.9
|
||||||
github.com/golang/protobuf/proto
|
|
||||||
github.com/golang/protobuf/ptypes/timestamp
|
github.com/golang/protobuf/ptypes/timestamp
|
||||||
# github.com/gorilla/websocket v1.4.2
|
# github.com/gorilla/websocket v1.4.2
|
||||||
## explicit; go 1.12
|
## explicit; go 1.12
|
||||||
@ -27,8 +33,8 @@ github.com/mattn/go-pointer
|
|||||||
github.com/mattn/go-tflite
|
github.com/mattn/go-tflite
|
||||||
github.com/mattn/go-tflite/delegates
|
github.com/mattn/go-tflite/delegates
|
||||||
github.com/mattn/go-tflite/delegates/edgetpu
|
github.com/mattn/go-tflite/delegates/edgetpu
|
||||||
# go.opentelemetry.io/otel v1.2.0
|
# go.opentelemetry.io/otel v1.3.0
|
||||||
## explicit; go 1.15
|
## explicit; go 1.16
|
||||||
go.opentelemetry.io/otel
|
go.opentelemetry.io/otel
|
||||||
go.opentelemetry.io/otel/attribute
|
go.opentelemetry.io/otel/attribute
|
||||||
go.opentelemetry.io/otel/baggage
|
go.opentelemetry.io/otel/baggage
|
||||||
@ -38,44 +44,42 @@ go.opentelemetry.io/otel/internal/baggage
|
|||||||
go.opentelemetry.io/otel/internal/global
|
go.opentelemetry.io/otel/internal/global
|
||||||
go.opentelemetry.io/otel/propagation
|
go.opentelemetry.io/otel/propagation
|
||||||
go.opentelemetry.io/otel/semconv/v1.7.0
|
go.opentelemetry.io/otel/semconv/v1.7.0
|
||||||
# go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.25.0
|
# go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v0.26.0
|
||||||
## explicit; go 1.15
|
## explicit; go 1.16
|
||||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric
|
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric
|
||||||
# go.opentelemetry.io/otel/internal/metric v0.25.0
|
# go.opentelemetry.io/otel/internal/metric v0.26.0
|
||||||
## explicit; go 1.15
|
## explicit; go 1.16
|
||||||
go.opentelemetry.io/otel/internal/metric
|
go.opentelemetry.io/otel/internal/metric
|
||||||
go.opentelemetry.io/otel/internal/metric/global
|
go.opentelemetry.io/otel/internal/metric/global
|
||||||
go.opentelemetry.io/otel/internal/metric/registry
|
go.opentelemetry.io/otel/internal/metric/registry
|
||||||
# go.opentelemetry.io/otel/metric v0.25.0
|
# go.opentelemetry.io/otel/metric v0.26.0
|
||||||
## explicit; go 1.15
|
## explicit; go 1.16
|
||||||
go.opentelemetry.io/otel/metric
|
go.opentelemetry.io/otel/metric
|
||||||
go.opentelemetry.io/otel/metric/global
|
go.opentelemetry.io/otel/metric/global
|
||||||
go.opentelemetry.io/otel/metric/number
|
go.opentelemetry.io/otel/metric/number
|
||||||
go.opentelemetry.io/otel/metric/sdkapi
|
go.opentelemetry.io/otel/metric/sdkapi
|
||||||
go.opentelemetry.io/otel/metric/unit
|
go.opentelemetry.io/otel/metric/unit
|
||||||
# go.opentelemetry.io/otel/sdk v1.2.0
|
# go.opentelemetry.io/otel/sdk v1.3.0
|
||||||
## explicit; go 1.15
|
## explicit; go 1.16
|
||||||
go.opentelemetry.io/otel/sdk/instrumentation
|
go.opentelemetry.io/otel/sdk/instrumentation
|
||||||
go.opentelemetry.io/otel/sdk/resource
|
go.opentelemetry.io/otel/sdk/resource
|
||||||
# go.opentelemetry.io/otel/sdk/export/metric v0.25.0
|
# go.opentelemetry.io/otel/sdk/export/metric v0.26.0
|
||||||
## explicit; go 1.15
|
## explicit; go 1.16
|
||||||
go.opentelemetry.io/otel/sdk/export/metric
|
go.opentelemetry.io/otel/sdk/export/metric
|
||||||
go.opentelemetry.io/otel/sdk/export/metric/aggregation
|
go.opentelemetry.io/otel/sdk/export/metric/aggregation
|
||||||
# go.opentelemetry.io/otel/sdk/metric v0.25.0
|
# go.opentelemetry.io/otel/sdk/metric v0.26.0
|
||||||
## explicit; go 1.15
|
## explicit; go 1.16
|
||||||
go.opentelemetry.io/otel/sdk/metric
|
go.opentelemetry.io/otel/sdk/metric
|
||||||
go.opentelemetry.io/otel/sdk/metric/aggregator
|
go.opentelemetry.io/otel/sdk/metric/aggregator
|
||||||
go.opentelemetry.io/otel/sdk/metric/aggregator/exact
|
|
||||||
go.opentelemetry.io/otel/sdk/metric/aggregator/histogram
|
go.opentelemetry.io/otel/sdk/metric/aggregator/histogram
|
||||||
go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue
|
go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue
|
||||||
go.opentelemetry.io/otel/sdk/metric/aggregator/minmaxsumcount
|
|
||||||
go.opentelemetry.io/otel/sdk/metric/aggregator/sum
|
go.opentelemetry.io/otel/sdk/metric/aggregator/sum
|
||||||
go.opentelemetry.io/otel/sdk/metric/controller/basic
|
go.opentelemetry.io/otel/sdk/metric/controller/basic
|
||||||
go.opentelemetry.io/otel/sdk/metric/controller/time
|
go.opentelemetry.io/otel/sdk/metric/controller/time
|
||||||
go.opentelemetry.io/otel/sdk/metric/processor/basic
|
go.opentelemetry.io/otel/sdk/metric/processor/basic
|
||||||
go.opentelemetry.io/otel/sdk/metric/selector/simple
|
go.opentelemetry.io/otel/sdk/metric/selector/simple
|
||||||
# go.opentelemetry.io/otel/trace v1.2.0
|
# go.opentelemetry.io/otel/trace v1.3.0
|
||||||
## explicit; go 1.15
|
## explicit; go 1.16
|
||||||
go.opentelemetry.io/otel/trace
|
go.opentelemetry.io/otel/trace
|
||||||
# go.uber.org/atomic v1.7.0
|
# go.uber.org/atomic v1.7.0
|
||||||
## explicit; go 1.13
|
## explicit; go 1.13
|
||||||
@ -107,7 +111,7 @@ golang.org/x/sys/internal/unsafeheader
|
|||||||
golang.org/x/sys/unix
|
golang.org/x/sys/unix
|
||||||
golang.org/x/sys/windows
|
golang.org/x/sys/windows
|
||||||
golang.org/x/sys/windows/registry
|
golang.org/x/sys/windows/registry
|
||||||
# google.golang.org/protobuf v1.26.0
|
# google.golang.org/protobuf v1.27.1
|
||||||
## explicit; go 1.9
|
## explicit; go 1.9
|
||||||
google.golang.org/protobuf/encoding/prototext
|
google.golang.org/protobuf/encoding/prototext
|
||||||
google.golang.org/protobuf/encoding/protowire
|
google.golang.org/protobuf/encoding/protowire
|
||||||
@ -130,10 +134,8 @@ google.golang.org/protobuf/internal/set
|
|||||||
google.golang.org/protobuf/internal/strs
|
google.golang.org/protobuf/internal/strs
|
||||||
google.golang.org/protobuf/internal/version
|
google.golang.org/protobuf/internal/version
|
||||||
google.golang.org/protobuf/proto
|
google.golang.org/protobuf/proto
|
||||||
google.golang.org/protobuf/reflect/protodesc
|
|
||||||
google.golang.org/protobuf/reflect/protoreflect
|
google.golang.org/protobuf/reflect/protoreflect
|
||||||
google.golang.org/protobuf/reflect/protoregistry
|
google.golang.org/protobuf/reflect/protoregistry
|
||||||
google.golang.org/protobuf/runtime/protoiface
|
google.golang.org/protobuf/runtime/protoiface
|
||||||
google.golang.org/protobuf/runtime/protoimpl
|
google.golang.org/protobuf/runtime/protoimpl
|
||||||
google.golang.org/protobuf/types/descriptorpb
|
|
||||||
google.golang.org/protobuf/types/known/timestamppb
|
google.golang.org/protobuf/types/known/timestamppb
|
||||||
|
Reference in New Issue
Block a user