diff --git a/go.mod b/go.mod
index f182c87d..c1bfa4d3 100644
--- a/go.mod
+++ b/go.mod
@@ -1,35 +1,35 @@
module github.com/datarhei/core/v16
-go 1.21
+go 1.21.0
toolchain go1.22.1
require (
- github.com/99designs/gqlgen v0.17.45
+ github.com/99designs/gqlgen v0.17.47
github.com/Masterminds/semver/v3 v3.2.1
github.com/atrox/haikunatorgo/v2 v2.0.1
- github.com/caddyserver/certmagic v0.20.0
+ github.com/caddyserver/certmagic v0.21.2
github.com/datarhei/gosrt v0.6.0
- github.com/datarhei/joy4 v0.0.0-20240515122635-392a77dff12d
- github.com/go-playground/validator/v10 v10.19.0
+ github.com/datarhei/joy4 v0.0.0-20240528121836-da80d79b6435
+ github.com/go-playground/validator/v10 v10.20.0
github.com/gobwas/glob v0.2.3
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/google/uuid v1.6.0
github.com/invopop/jsonschema v0.4.0
github.com/joho/godotenv v1.5.1
github.com/labstack/echo-jwt v0.0.0-20221127215225-c84d41a71003
- github.com/labstack/echo/v4 v4.11.4
+ github.com/labstack/echo/v4 v4.12.0
github.com/lithammer/shortuuid/v4 v4.0.0
github.com/mattn/go-isatty v0.0.20
- github.com/minio/minio-go/v7 v7.0.69
+ github.com/minio/minio-go/v7 v7.0.70
github.com/prep/average v0.0.0-20200506183628-d26c465f48c3
- github.com/prometheus/client_golang v1.19.0
+ github.com/prometheus/client_golang v1.19.1
github.com/puzpuzpuz/xsync/v3 v3.1.0
- github.com/shirou/gopsutil/v3 v3.24.3
+ github.com/shirou/gopsutil/v3 v3.24.4
github.com/stretchr/testify v1.9.0
github.com/swaggo/echo-swagger v1.4.1
github.com/swaggo/swag v1.16.3
- github.com/vektah/gqlparser/v2 v2.5.11
+ github.com/vektah/gqlparser/v2 v2.5.12
github.com/xeipuuv/gojsonschema v1.2.0
go.uber.org/zap v1.27.0
golang.org/x/mod v0.17.0
@@ -40,11 +40,12 @@ require (
github.com/agnivade/levenshtein v1.1.1 // indirect
github.com/benburkert/openpgp v0.0.0-20160410205803-c2471f86866c // indirect
github.com/beorn7/perks v1.0.1 // indirect
+ github.com/caddyserver/zerossl v0.1.3 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
- github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
+ github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
- github.com/gabriel-vasile/mimetype v1.4.3 // indirect
+ github.com/gabriel-vasile/mimetype v1.4.4 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
@@ -53,57 +54,54 @@ require (
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
+ github.com/goccy/go-json v0.10.3 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/iancoleman/orderedmap v0.2.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
- github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.8 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/labstack/gommon v0.4.2 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/libdns/libdns v0.2.2 // indirect
- github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74 // indirect
+ github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
- github.com/mholt/acmez v1.2.0 // indirect
- github.com/miekg/dns v1.1.58 // indirect
+ github.com/mholt/acmez/v2 v2.0.1 // indirect
+ github.com/miekg/dns v1.1.59 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
- github.com/minio/sha256-simd v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
- github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
- github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
- github.com/prometheus/common v0.52.3 // indirect
- github.com/prometheus/procfs v0.13.0 // indirect
+ github.com/prometheus/common v0.53.0 // indirect
+ github.com/prometheus/procfs v0.15.0 // indirect
github.com/rs/xid v1.5.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
- github.com/sosodev/duration v1.2.0 // indirect
+ github.com/sosodev/duration v1.3.1 // indirect
github.com/swaggo/files/v2 v2.0.0 // indirect
- github.com/tklauser/go-sysconf v0.3.13 // indirect
- github.com/tklauser/numcpus v0.7.0 // indirect
- github.com/urfave/cli/v2 v2.27.1 // indirect
+ github.com/tklauser/go-sysconf v0.3.14 // indirect
+ github.com/tklauser/numcpus v0.8.0 // indirect
+ github.com/urfave/cli/v2 v2.27.2 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
- github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
+ github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
go.uber.org/multierr v1.11.0 // indirect
- golang.org/x/crypto v0.22.0 // indirect
- golang.org/x/net v0.24.0 // indirect
+ golang.org/x/crypto v0.23.0 // indirect
+ golang.org/x/net v0.25.0 // indirect
golang.org/x/sync v0.7.0 // indirect
- golang.org/x/sys v0.19.0 // indirect
- golang.org/x/text v0.14.0 // indirect
+ golang.org/x/sys v0.20.0 // indirect
+ golang.org/x/text v0.15.0 // indirect
golang.org/x/time v0.5.0 // indirect
- golang.org/x/tools v0.20.0 // indirect
- google.golang.org/protobuf v1.33.0 // indirect
+ golang.org/x/tools v0.21.0 // indirect
+ google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
diff --git a/go.sum b/go.sum
index 6792bc36..83626305 100644
--- a/go.sum
+++ b/go.sum
@@ -1,11 +1,11 @@
-github.com/99designs/gqlgen v0.17.45 h1:bH0AH67vIJo8JKNKPJP+pOPpQhZeuVRQLf53dKIpDik=
-github.com/99designs/gqlgen v0.17.45/go.mod h1:Bas0XQ+Jiu/Xm5E33jC8sES3G+iC2esHBMXcq0fUPs0=
+github.com/99designs/gqlgen v0.17.47 h1:M9DTK8X3+3ATNBfZlHBwMwNngn4hhZWDxNmTiuQU5tQ=
+github.com/99designs/gqlgen v0.17.47/go.mod h1:ejVkldSdtmuudqmtfaiqjwlGXWAhIv0DKXGXFY25F04=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
-github.com/PuerkitoBio/goquery v1.9.1 h1:mTL6XjbJTZdpfL+Gwl5U2h1l9yEkJjhmlTeV9VPW7UI=
-github.com/PuerkitoBio/goquery v1.9.1/go.mod h1:cW1n6TmIMDoORQU5IU/P1T3tGFunOeXEpGP2WHRwkbY=
+github.com/PuerkitoBio/goquery v1.9.2 h1:4/wZksC3KgkQw7SQgkKotmKljk0M6V8TUvA8Wb4yPeE=
+github.com/PuerkitoBio/goquery v1.9.2/go.mod h1:GHPCaP0ODyyxqcNoFGYlAprUFH81NuRPd0GX3Zu2Mvk=
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
@@ -20,16 +20,18 @@ github.com/benburkert/openpgp v0.0.0-20160410205803-c2471f86866c h1:8XZeJrs4+ZYh
github.com/benburkert/openpgp v0.0.0-20160410205803-c2471f86866c/go.mod h1:x1vxHcL/9AVzuk5HOloOEPrtJY0MaalYr78afXZ+pWI=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
-github.com/caddyserver/certmagic v0.20.0 h1:bTw7LcEZAh9ucYCRXyCpIrSAGplplI0vGYJ4BpCQ/Fc=
-github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg=
+github.com/caddyserver/certmagic v0.21.2 h1:O18LtaYBGDooyy257cYePnhp4lPfz6TaJELil6Q1fDg=
+github.com/caddyserver/certmagic v0.21.2/go.mod h1:Zq6pklO9nVRl3DIFUw9gVUfXKdpc/0qwTUAQMBlfgtI=
+github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA=
+github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
-github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
+github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/datarhei/gosrt v0.6.0 h1:HrrXAw90V78ok4WMIhX6se1aTHPCn82Sg2hj+PhdmGc=
github.com/datarhei/gosrt v0.6.0/go.mod h1:fsOWdLSHUHShHjgi/46h6wjtdQrtnSdAQFnlas8ONxs=
-github.com/datarhei/joy4 v0.0.0-20240515122635-392a77dff12d h1:pb2UfphyP0/aCBMRdearSQUuCCQZrzMh3R/BAff9/TY=
-github.com/datarhei/joy4 v0.0.0-20240515122635-392a77dff12d/go.mod h1:Jcw/6jZDQQmPx8A7INEkXmuEF7E9jjBbSTfVSLwmiQw=
+github.com/datarhei/joy4 v0.0.0-20240528121836-da80d79b6435 h1:bXcqdyQWtKyb1i82qLMqi4DxbVrZMpk0oVmKtWJjWhg=
+github.com/datarhei/joy4 v0.0.0-20240528121836-da80d79b6435/go.mod h1:Jcw/6jZDQQmPx8A7INEkXmuEF7E9jjBbSTfVSLwmiQw=
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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -37,8 +39,8 @@ github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
-github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
-github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
+github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I=
+github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
@@ -58,10 +60,12 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
-github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4=
-github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
+github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
+github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
+github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
+github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
@@ -72,7 +76,6 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -89,8 +92,6 @@ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
-github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
-github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
@@ -103,8 +104,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/echo-jwt v0.0.0-20221127215225-c84d41a71003 h1:FyalHKl9hnJvhNbrABJXXjC2hG7gvIF0ioW9i0xHNQU=
github.com/labstack/echo-jwt v0.0.0-20221127215225-c84d41a71003/go.mod h1:ovRFgyKvi73jQIFCWz9ByQwzhIyohkzY0MFAlPGyr8Q=
-github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8=
-github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8=
+github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0=
+github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM=
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
@@ -114,8 +115,8 @@ github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfs
github.com/lithammer/shortuuid/v4 v4.0.0 h1:QRbbVkfgNippHOS8PXDkti4NaWeyYfcBTHtw7k08o4c=
github.com/lithammer/shortuuid/v4 v4.0.0/go.mod h1:Zs8puNcrvf2rV9rTH51ZLLcj7ZXqQI3lv67aw4KiB1Y=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
-github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74 h1:1KuuSOy4ZNgW0KA2oYIngXVFhQcXxhLqCVK7cBcldkk=
-github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
+github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae h1:dIZY4ULFcto4tAFlj1FYZl8ztUZ13bdq+PLY+NOfbyI=
+github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
@@ -123,23 +124,16 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
-github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30=
-github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE=
-github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
-github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
+github.com/mholt/acmez/v2 v2.0.1 h1:3/3N0u1pLjMK4sNEAFSI+bcvzbPhRpY383sy1kLHJ6k=
+github.com/mholt/acmez/v2 v2.0.1/go.mod h1:fX4c9r5jYwMyMsC+7tkYRxHibkOTgta5DIFGoe67e1U=
+github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs=
+github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
-github.com/minio/minio-go/v7 v7.0.69 h1:l8AnsQFyY1xiwa/DaQskY4NXSLA2yrGsW5iD9nRPVS0=
-github.com/minio/minio-go/v7 v7.0.69/go.mod h1:XAvOPJQ5Xlzk5o3o/ArO2NMbhSGkimC+bpW/ngRKDmQ=
-github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
-github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
+github.com/minio/minio-go/v7 v7.0.70 h1:1u9NtMgfK1U42kUxcsl5v0yj6TEOPR497OAQxpJnn2g=
+github.com/minio/minio-go/v7 v7.0.70/go.mod h1:4yBA8v80xGA30cfM3fz0DKYMXunWl/AV/6tWEs9ryzo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
-github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -148,14 +142,14 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prep/average v0.0.0-20200506183628-d26c465f48c3 h1:Y7qCvg282QmlyrVQuL2fgGwebuw7zvfnRym09r+dUGc=
github.com/prep/average v0.0.0-20200506183628-d26c465f48c3/go.mod h1:0ZE5gcyWKS151WBDIpmLshHY0l+3edpuKnBUWVVbWKk=
-github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
-github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k=
+github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
+github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
-github.com/prometheus/common v0.52.3 h1:5f8uj6ZwHSscOGNdIQg6OiZv/ybiK2CO2q2drVZAQSA=
-github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
-github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o=
-github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g=
+github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE=
+github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U=
+github.com/prometheus/procfs v0.15.0 h1:A82kmvXJq2jTu5YUhSGNlYoxh85zLnKgPz4bMZgI5Ek=
+github.com/prometheus/procfs v0.15.0/go.mod h1:Y0RJ/Y5g5wJpkTisOtqwDSo4HwhGmLB4VQSw2sQJLHk=
github.com/puzpuzpuz/xsync/v3 v3.1.0 h1:EewKT7/LNac5SLiEblJeUu8z5eERHrmRLnMQL2d7qX4=
github.com/puzpuzpuz/xsync/v3 v3.1.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
@@ -166,14 +160,14 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
-github.com/shirou/gopsutil/v3 v3.24.3 h1:eoUGJSmdfLzJ3mxIhmOAhgKEKgQkeOwKpz1NbhVnuPE=
-github.com/shirou/gopsutil/v3 v3.24.3/go.mod h1:JpND7O217xa72ewWz9zN2eIIkPWsDN/3pl0H8Qt0uwg=
+github.com/shirou/gopsutil/v3 v3.24.4 h1:dEHgzZXt4LMNm+oYELpzl9YCqV65Yr/6SfrvgRBtXeU=
+github.com/shirou/gopsutil/v3 v3.24.4/go.mod h1:lTd2mdiOspcqLgAnr9/nGi71NkeMpWKdmhuxm9GusH8=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
-github.com/sosodev/duration v1.2.0 h1:pqK/FLSjsAADWY74SyWDCjOcd5l7H8GSnnOGEB9A1Us=
-github.com/sosodev/duration v1.2.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg=
+github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4=
+github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -192,19 +186,19 @@ github.com/swaggo/files/v2 v2.0.0/go.mod h1:24kk2Y9NYEJ5lHuCra6iVwkMjIekMCaFq/0J
github.com/swaggo/swag v1.16.3 h1:PnCYjPCah8FK4I26l2F/KQ4yz3sILcVUN3cTlBFA9Pg=
github.com/swaggo/swag v1.16.3/go.mod h1:DImHIuOFXKpMFAQjcC7FG4m3Dg4+QuUgUzJmKjI/gRk=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
-github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4=
-github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0=
+github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU=
+github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
-github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4=
-github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY=
-github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=
-github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
+github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY=
+github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE=
+github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI=
+github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
-github.com/vektah/gqlparser/v2 v2.5.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8=
-github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc=
+github.com/vektah/gqlparser/v2 v2.5.12 h1:COMhVVnql6RoaF7+aTBWiTADdpLGyZWU3K/NwW0ph98=
+github.com/vektah/gqlparser/v2 v2.5.12/go.mod h1:WQQjFc+I1YIzoPvZBhUQX7waZgg3pMLi0r8KymvAE2w=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@@ -212,8 +206,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
-github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
-github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
+github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw=
+github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
@@ -228,12 +222,12 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
-golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
-golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
+golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
+golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
-golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
+golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
+golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -244,18 +238,18 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
+golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
-golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
-golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
+golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
+golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
-google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
+google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
diff --git a/vendor/github.com/99designs/gqlgen/.gitignore b/vendor/github.com/99designs/gqlgen/.gitignore
index 22af48fb..9025d25a 100644
--- a/vendor/github.com/99designs/gqlgen/.gitignore
+++ b/vendor/github.com/99designs/gqlgen/.gitignore
@@ -18,3 +18,8 @@ gqlgen
*.exe
node_modules
+
+# generated files
+/api/testdata/default/graph/generated.go
+/api/testdata/federation2/graph/federation.go
+/api/testdata/federation2/graph/generated.go
\ No newline at end of file
diff --git a/vendor/github.com/99designs/gqlgen/.golangci.yml b/vendor/github.com/99designs/gqlgen/.golangci.yml
index 5966bf2c..97a514b9 100644
--- a/vendor/github.com/99designs/gqlgen/.golangci.yml
+++ b/vendor/github.com/99designs/gqlgen/.golangci.yml
@@ -1,11 +1,25 @@
run:
tests: true
- skip-dirs:
- - bin
linters-settings:
errcheck:
- ignore: fmt:.*,[rR]ead|[wW]rite|[cC]lose,io:Copy
+ exclude-functions:
+ - (io.Writer).Write
+ - io.Copy
+ - io.WriteString
+ revive:
+ enable-all-rules: false
+ rules:
+ - name: empty-lines
+ testifylint:
+ disable-all: true
+ enable:
+ - bool-compare
+ - compares
+ - error-is-as
+ - error-nil
+ - expected-actual
+ - nil-compare
linters:
disable-all: true
@@ -22,14 +36,19 @@ linters:
- misspell
- nakedret
- prealloc
+ - revive
- staticcheck
+ - testifylint
- typecheck
- unconvert
- unused
issues:
+ exclude-dirs:
+ - bin
exclude-rules:
# Exclude some linters from running on tests files.
- path: _test\.go
linters:
- dupl
+ - errcheck
diff --git a/vendor/github.com/99designs/gqlgen/CHANGELOG.md b/vendor/github.com/99designs/gqlgen/CHANGELOG.md
index 6357842b..acea9f11 100644
--- a/vendor/github.com/99designs/gqlgen/CHANGELOG.md
+++ b/vendor/github.com/99designs/gqlgen/CHANGELOG.md
@@ -5,10 +5,1149 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-## [Unreleased](https://github.com/99designs/gqlgen/compare/v0.17.42...HEAD)
+## [Unreleased](https://github.com/99designs/gqlgen/compare/v0.17.45...HEAD)
+
+## [v0.17.45](https://github.com/99designs/gqlgen/compare/v0.17.44...v0.17.45) - 2024-03-11
+- b6d1a8b9 release v0.17.45
+
+
a854eb65 Bump golang.org/x/tools from 0.18.0 to 0.19.0 (#2963)
+
+* Bump golang.org/x/tools from 0.18.0 to 0.19.0
+
+Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.18.0 to 0.19.0.
+- [Release notes](https://github.com/golang/tools/releases)
+- [Commits](https://github.com/golang/tools/compare/v0.18.0...v0.19.0)
+
+---
+updated-dependencies:
+- dependency-name: golang.org/x/tools
+ dependency-type: direct:production
+ update-type: version-update:semver-minor
+...
+
+
+* Go mod tidy examples and websocket
+
+
+---------
+
+
+
+908498e3 Bump typescript from 5.3.3 to 5.4.2 in /integration (#2960)
+
+Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.3.3 to 5.4.2.
+- [Release notes](https://github.com/Microsoft/TypeScript/releases)
+- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml)
+- [Commits](https://github.com/Microsoft/TypeScript/compare/v5.3.3...v5.4.2)
+
+---
+updated-dependencies:
+- dependency-name: typescript
+ dependency-type: direct:development
+ update-type: version-update:semver-minor
+...
+
+
+
+6e77359b Bump vite from 5.1.4 to 5.1.5 in /integration (#2961)
+
+Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.1.4 to 5.1.5.
+- [Release notes](https://github.com/vitejs/vite/releases)
+- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
+- [Commits](https://github.com/vitejs/vite/commits/v5.1.5/packages/vite)
+
+---
+updated-dependencies:
+- dependency-name: vite
+ dependency-type: direct:development
+ update-type: version-update:semver-patch
+...
+
+
+
+361cb189 Bump [@apollo](https://github.com/apollo)/client from 3.9.5 to 3.9.6 in /integration (#2962)
+
+- [Release notes](https://github.com/apollographql/apollo-client/releases)
+- [Changelog](https://github.com/apollographql/apollo-client/blob/main/CHANGELOG.md)
+- [Commits](https://github.com/apollographql/apollo-client/compare/v3.9.5...v3.9.6)
+
+---
+updated-dependencies:
+ dependency-type: direct:development
+ update-type: version-update:semver-patch
+...
+
+
+
+d2271d8f Bump google.golang.org/protobuf from 1.32.0 to 1.33.0 (#2964)
+
+Bumps google.golang.org/protobuf from 1.32.0 to 1.33.0.
+
+---
+updated-dependencies:
+- dependency-name: google.golang.org/protobuf
+ dependency-type: direct:production
+ update-type: version-update:semver-minor
+...
+
+
+
+- caf1faa7 Add case for resolvers_always_return_pointers:false (#2966)
+
+- 0d24aa9b handle models in federation pkg (#2965)
+
+- 2aa9bbb4 fix(docs): convert an unnecessarily capitalized word in the middle of sentences to lowercase (#2959)
+
+- bc72cd8c Add option to omit resolver fields from models (#2957)
+
+95f9dc79 Bump github.com/stretchr/testify from 1.8.4 to 1.9.0 (#2953)
+
+Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.4 to 1.9.0.
+- [Release notes](https://github.com/stretchr/testify/releases)
+- [Commits](https://github.com/stretchr/testify/compare/v1.8.4...v1.9.0)
+
+---
+updated-dependencies:
+- dependency-name: github.com/stretchr/testify
+ dependency-type: direct:production
+ update-type: version-update:semver-minor
+...
+
+
+
+fbcceec2 Bump github.com/PuerkitoBio/goquery from 1.9.0 to 1.9.1 (#2954)
+
+* Bump github.com/PuerkitoBio/goquery from 1.9.0 to 1.9.1
+
+Bumps [github.com/PuerkitoBio/goquery](https://github.com/PuerkitoBio/goquery) from 1.9.0 to 1.9.1.
+- [Release notes](https://github.com/PuerkitoBio/goquery/releases)
+- [Commits](https://github.com/PuerkitoBio/goquery/compare/v1.9.0...v1.9.1)
+
+---
+updated-dependencies:
+- dependency-name: github.com/PuerkitoBio/goquery
+ dependency-type: direct:production
+ update-type: version-update:semver-patch
+...
+
+
+* mod tidy examples
+
+
+---------
+
+
+
+c15af8ce Bump github.com/stretchr/testify from 1.8.4 to 1.9.0 in /_examples (#2955)
+
+Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.4 to 1.9.0.
+- [Release notes](https://github.com/stretchr/testify/releases)
+- [Commits](https://github.com/stretchr/testify/compare/v1.8.4...v1.9.0)
+
+---
+updated-dependencies:
+- dependency-name: github.com/stretchr/testify
+ dependency-type: direct:production
+ update-type: version-update:semver-minor
+...
+
+
+
+1993b3aa Bump vitest from 1.3.0 to 1.3.1 in /integration (#2946)
+
+Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 1.3.0 to 1.3.1.
+- [Release notes](https://github.com/vitest-dev/vitest/releases)
+- [Commits](https://github.com/vitest-dev/vitest/commits/v1.3.1/packages/vitest)
+
+---
+updated-dependencies:
+- dependency-name: vitest
+ dependency-type: direct:development
+ update-type: version-update:semver-patch
+...
+
+
+
+d16c6adc Bump github.com/PuerkitoBio/goquery from 1.8.1 to 1.9.0 (#2943)
+
+* Bump github.com/PuerkitoBio/goquery from 1.8.1 to 1.9.0
+
+Bumps [github.com/PuerkitoBio/goquery](https://github.com/PuerkitoBio/goquery) from 1.8.1 to 1.9.0.
+- [Release notes](https://github.com/PuerkitoBio/goquery/releases)
+- [Commits](https://github.com/PuerkitoBio/goquery/compare/v1.8.1...v1.9.0)
+
+---
+updated-dependencies:
+- dependency-name: github.com/PuerkitoBio/goquery
+ dependency-type: direct:production
+ update-type: version-update:semver-minor
+...
+
+
+* Tidy examples
+
+
+---------
+
+
+
+be74b6a0 Bump [@graphql](https://github.com/graphql)-codegen/client-preset from 4.2.2 to 4.2.4 in /integration (#2945)
+
+- [Release notes](https://github.com/dotansimha/graphql-code-generator/releases)
+- [Changelog](https://github.com/dotansimha/graphql-code-generator/blob/master/packages/presets/client/CHANGELOG.md)
+
+---
+updated-dependencies:
+ dependency-type: direct:development
+ update-type: version-update:semver-patch
+...
+
+
+
+90aa9243 Bump [@graphql](https://github.com/graphql)-codegen/introspection from 4.0.2 to 4.0.3 in /integration (#2944)
+
+- [Release notes](https://github.com/dotansimha/graphql-code-generator/releases)
+- [Changelog](https://github.com/dotansimha/graphql-code-generator/blob/master/packages/plugins/other/introspection/CHANGELOG.md)
+
+---
+updated-dependencies:
+ dependency-type: direct:development
+ update-type: version-update:semver-patch
+...
+
+
+
+137ddbd3 Bump vite from 5.1.3 to 5.1.4 in /integration (#2947)
+
+Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.1.3 to 5.1.4.
+- [Release notes](https://github.com/vitejs/vite/releases)
+- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
+- [Commits](https://github.com/vitejs/vite/commits/v5.1.4/packages/vite)
+
+---
+updated-dependencies:
+- dependency-name: vite
+ dependency-type: direct:development
+ update-type: version-update:semver-patch
+...
+
+
+
+15cef76f Optionally render entity requires populator function for advanced [@requires](https://github.com/requires) use cases (#2884) (closes #1)
+
+* Adding generation of new functions to populate requires representations. WIP.
+
+* Something.
+
+* Adding config option for Package to allow for enabling flags. Added flag to render explicit requires function.
+
+
+* Adding explicit requires testsing and make requires follow federation package.
+
+* Fix test failure.
+
+* Using embeded template like federation gotpl. Fix rewriter not using correct dir.
+
+* Update generated code.
+
+
+* Adding initial docs for explicit requires
+
+* Add example docs for explicit requires
+
+* Adding ordering fix.
+
+* Regenerate.
+
+---------
+
+
+
+e186813e Bump golang.org/x/tools from 0.17.0 to 0.18.0 (#2940)
+
+* Bump golang.org/x/tools from 0.17.0 to 0.18.0
+
+Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.17.0 to 0.18.0.
+- [Release notes](https://github.com/golang/tools/releases)
+- [Commits](https://github.com/golang/tools/compare/v0.17.0...v0.18.0)
+
+---
+updated-dependencies:
+- dependency-name: golang.org/x/tools
+ dependency-type: direct:production
+ update-type: version-update:semver-minor
+...
+
+
+* Update example module
+
+
+---------
+
+
+
+e1fb6c03 Bump vite from 5.1.1 to 5.1.3 in /integration (#2936)
+
+Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.1.1 to 5.1.3.
+- [Release notes](https://github.com/vitejs/vite/releases)
+- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
+- [Commits](https://github.com/vitejs/vite/commits/v5.1.3/packages/vite)
+
+---
+updated-dependencies:
+- dependency-name: vite
+ dependency-type: direct:development
+ update-type: version-update:semver-patch
+...
+
+
+
+1ff1107e Bump graphql-ws from 5.14.3 to 5.15.0 in /integration (#2935)
+
+Bumps [graphql-ws](https://github.com/enisdenjo/graphql-ws) from 5.14.3 to 5.15.0.
+- [Release notes](https://github.com/enisdenjo/graphql-ws/releases)
+- [Changelog](https://github.com/enisdenjo/graphql-ws/blob/master/CHANGELOG.md)
+- [Commits](https://github.com/enisdenjo/graphql-ws/compare/v5.14.3...v5.15.0)
+
+---
+updated-dependencies:
+- dependency-name: graphql-ws
+ dependency-type: direct:development
+ update-type: version-update:semver-minor
+...
+
+
+
+d4696f88 Bump vitest from 1.2.2 to 1.3.0 in /integration (#2937)
+
+Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 1.2.2 to 1.3.0.
+- [Release notes](https://github.com/vitest-dev/vitest/releases)
+- [Commits](https://github.com/vitest-dev/vitest/commits/v1.3.0/packages/vitest)
+
+---
+updated-dependencies:
+- dependency-name: vitest
+ dependency-type: direct:development
+ update-type: version-update:semver-minor
+...
+
+
+
+4808f0db Bump [@apollo](https://github.com/apollo)/client from 3.9.4 to 3.9.5 in /integration (#2938)
+
+- [Release notes](https://github.com/apollographql/apollo-client/releases)
+- [Changelog](https://github.com/apollographql/apollo-client/blob/main/CHANGELOG.md)
+- [Commits](https://github.com/apollographql/apollo-client/compare/v3.9.4...v3.9.5)
+
+---
+updated-dependencies:
+ dependency-type: direct:development
+ update-type: version-update:semver-patch
+...
+
+
+
+a96e3395 Bump github.com/matryer/moq from 0.3.3 to 0.3.4 (#2939)
+
+Bumps [github.com/matryer/moq](https://github.com/matryer/moq) from 0.3.3 to 0.3.4.
+- [Release notes](https://github.com/matryer/moq/releases)
+- [Changelog](https://github.com/matryer/moq/blob/main/.goreleaser.yml)
+- [Commits](https://github.com/matryer/moq/compare/v0.3.3...v0.3.4)
+
+---
+updated-dependencies:
+- dependency-name: github.com/matryer/moq
+ dependency-type: direct:production
+ update-type: version-update:semver-patch
+...
+
+
+
+- 7ca35b11 v0.17.44 postrelease bump
+
+
+
+
+
+
+## [v0.17.44](https://github.com/99designs/gqlgen/compare/v0.17.43...v0.17.44) - 2024-02-15
+- 296b3c49 release v0.17.44
+
+e85ce95b Bump react-dom from 16.14.0 to 18.2.0 in /_examples/chat (#2930)
+
+Bumps [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) from 16.14.0 to 18.2.0.
+- [Release notes](https://github.com/facebook/react/releases)
+- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
+- [Commits](https://github.com/facebook/react/commits/v18.2.0/packages/react-dom)
+
+---
+updated-dependencies:
+- dependency-name: react-dom
+ dependency-type: direct:production
+ update-type: version-update:semver-major
+...
+
+
+
+c88cf024 Bump github.com/sosodev/duration from 1.1.0 to 1.2.0 (#2927)
+
+* Bump github.com/sosodev/duration from 1.1.0 to 1.2.0
+
+Bumps [github.com/sosodev/duration](https://github.com/sosodev/duration) from 1.1.0 to 1.2.0.
+- [Release notes](https://github.com/sosodev/duration/releases)
+- [Commits](https://github.com/sosodev/duration/compare/v1.1.0...v1.2.0)
+
+---
+updated-dependencies:
+- dependency-name: github.com/sosodev/duration
+ dependency-type: direct:production
+ update-type: version-update:semver-minor
+...
+
+
+* Tidy example go mod
+
+
+---------
+
+
+
+848fd835 Bump [@graphql](https://github.com/graphql)-codegen/cli from 4.0.1 to 5.0.2 in /integration (#2932)
+
+- [Release notes](https://github.com/dotansimha/graphql-code-generator/releases)
+- [Changelog](https://github.com/dotansimha/graphql-code-generator/blob/master/packages/graphql-codegen-cli/CHANGELOG.md)
+
+---
+updated-dependencies:
+ dependency-type: direct:development
+ update-type: version-update:semver-major
+...
+
+
+
+900040c4 Bump vite from 4.5.2 to 5.1.1 in /integration (#2931)
+
+Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.5.2 to 5.1.1.
+- [Release notes](https://github.com/vitejs/vite/releases)
+- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
+- [Commits](https://github.com/vitejs/vite/commits/v5.1.1/packages/vite)
+
+---
+updated-dependencies:
+- dependency-name: vite
+ dependency-type: direct:development
+ update-type: version-update:semver-major
+...
+
+
+
+e329cf83 Bump react from 16.14.0 to 18.2.0 in /_examples/chat (#2929)
+
+Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react) from 16.14.0 to 18.2.0.
+- [Release notes](https://github.com/facebook/react/releases)
+- [Changelog](https://github.com/facebook/react/blob/main/CHANGELOG.md)
+- [Commits](https://github.com/facebook/react/commits/v18.2.0/packages/react)
+
+---
+updated-dependencies:
+- dependency-name: react
+ dependency-type: direct:production
+ update-type: version-update:semver-major
+...
+
+
+
+9faad588 Bump google.golang.org/protobuf from 1.30.0 to 1.32.0 (#2926)
+
+Bumps google.golang.org/protobuf from 1.30.0 to 1.32.0.
+
+---
+updated-dependencies:
+- dependency-name: google.golang.org/protobuf
+ dependency-type: direct:production
+ update-type: version-update:semver-minor
+...
+
+
+
+92b3871b Bump github.com/stretchr/testify from 1.8.2 to 1.8.4 (#2925)
+
+Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.2 to 1.8.4.
+- [Release notes](https://github.com/stretchr/testify/releases)
+- [Commits](https://github.com/stretchr/testify/compare/v1.8.2...v1.8.4)
+
+---
+updated-dependencies:
+- dependency-name: github.com/stretchr/testify
+ dependency-type: direct:production
+ update-type: version-update:semver-patch
+...
+
+
+
+3f5e1f28 Bump github.com/google/uuid from 1.3.0 to 1.6.0 (#2924)
+
+Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.3.0 to 1.6.0.
+- [Release notes](https://github.com/google/uuid/releases)
+- [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md)
+- [Commits](https://github.com/google/uuid/compare/v1.3.0...v1.6.0)
+
+---
+updated-dependencies:
+- dependency-name: github.com/google/uuid
+ dependency-type: direct:production
+ update-type: version-update:semver-minor
+...
+
+
+
+fd97abcd Bump golangci/golangci-lint-action from 3.7.0 to 4.0.0 (#2928)
+
+Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 3.7.0 to 4.0.0.
+- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
+- [Commits](https://github.com/golangci/golangci-lint-action/compare/v3.7.0...v4.0.0)
+
+---
+updated-dependencies:
+- dependency-name: golangci/golangci-lint-action
+ dependency-type: direct:production
+ update-type: version-update:semver-major
+...
+
+
+
+64d0f07c graphql/uint: Fix unmarshalling of negative numbers (#2922)
+
+Converting a negative number to uint directly returns a really big number. For
+example,
+
+ v := -5
+ fmt.Println(uint(v)) // 18446744073709551611
+
+So we should handle this cases explicitly and return an error.
+
+
+
+e223f1d2 Bump node-fetch from 2.7.0 to 3.3.2 in /_examples/federation (#2916)
+
+* Bump node-fetch from 2.7.0 to 3.3.2 in /_examples/federation
+
+Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.7.0 to 3.3.2.
+- [Release notes](https://github.com/node-fetch/node-fetch/releases)
+- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.7.0...v3.3.2)
+
+---
+updated-dependencies:
+- dependency-name: node-fetch
+ dependency-type: direct:development
+ update-type: version-update:semver-major
+...
+
+
+* Try updating require to import
+
+
+* Try updating Apollo server and gateway
+
+
+
+
+* Change versions of everything in npm
+
+
+* Rever to node 16
+
+
+* Switch to apollo Link
+
+
+* Use more better newer thingy
+
+
+* Change federation node version back to 16
+
+
+* Apollo Link uses uri now instead of link
+
+
+* Change inmemory cache import
+
+
+* Remove node fetch from integration test
+
+
+* Add cross fetch
+
+
+* Adjust cross fetch to dev dependency
+
+
+* Fixup package-lock
+
+
+* Try again
+
+
+* Switch to node 18 to get fetch
+
+
+* Add type module to package.json
+
+
+* export default
+
+
+* Re-order?
+
+
+* Add external
+
+
+* add experimental vm modules to jest
+
+
+* Update git ignore for node_modules
+
+
+* Add some more jest stuff
+
+
+* refmt and regenerate
+
+
+* Add rehackt to dev dependencies
+
+
+* Change to core import
+
+
+* Aaaand do it over here too
+
+
+* Some of each
+
+
+* Move to different HTTP Link
+
+
+* Try again
+
+
+* add gql from apollo core
+
+
+* Change link to uri
+
+
+* Try just passing a string
+
+
+---------
+
+
+
+9a3694e5 Bump github.com/hashicorp/golang-lru/v2 from 2.0.3 to 2.0.7 (#2915)
+
+* Bump github.com/hashicorp/golang-lru/v2 from 2.0.3 to 2.0.7
+
+Bumps [github.com/hashicorp/golang-lru/v2](https://github.com/hashicorp/golang-lru) from 2.0.3 to 2.0.7.
+- [Release notes](https://github.com/hashicorp/golang-lru/releases)
+- [Commits](https://github.com/hashicorp/golang-lru/compare/v2.0.3...v2.0.7)
+
+---
+updated-dependencies:
+- dependency-name: github.com/hashicorp/golang-lru/v2
+ dependency-type: direct:production
+ update-type: version-update:semver-patch
+...
+
+
+* mod tidy for examples
+
+
+---------
+
+
+
+4b7eec41 Bump urql from 4.0.4 to 4.0.6 in /integration (#2906)
+
+Bumps [urql](https://github.com/urql-graphql/urql/tree/HEAD/packages/react-urql) from 4.0.4 to 4.0.6.
+- [Release notes](https://github.com/urql-graphql/urql/releases)
+- [Changelog](https://github.com/urql-graphql/urql/blob/main/packages/react-urql/CHANGELOG.md)
+
+---
+updated-dependencies:
+- dependency-name: urql
+ dependency-type: direct:development
+ update-type: version-update:semver-patch
+...
+
+
+
+8874254a Bump github.com/mattn/go-isatty from 0.0.19 to 0.0.20 (#2908)
+
+* Bump github.com/mattn/go-isatty from 0.0.19 to 0.0.20
+
+Bumps [github.com/mattn/go-isatty](https://github.com/mattn/go-isatty) from 0.0.19 to 0.0.20.
+- [Commits](https://github.com/mattn/go-isatty/compare/v0.0.19...v0.0.20)
+
+---
+updated-dependencies:
+- dependency-name: github.com/mattn/go-isatty
+ dependency-type: direct:production
+ update-type: version-update:semver-patch
+...
+
+
+* Go mod tidy
+
+
+---------
+
+
+
+9a6b5655 Bump [@graphql](https://github.com/graphql)-codegen/schema-ast from 4.0.0 to 4.0.2 in /integration (#2918)
+
+- [Release notes](https://github.com/dotansimha/graphql-code-generator/releases)
+- [Changelog](https://github.com/dotansimha/graphql-code-generator/blob/master/packages/plugins/other/schema-ast/CHANGELOG.md)
+
+---
+updated-dependencies:
+ dependency-type: direct:development
+ update-type: version-update:semver-patch
+...
+
+
+
+76c02143 Bump typescript from 5.1.3 to 5.3.3 in /integration (#2921)
+
+Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.1.3 to 5.3.3.
+- [Release notes](https://github.com/Microsoft/TypeScript/releases)
+- [Commits](https://github.com/Microsoft/TypeScript/compare/v5.1.3...v5.3.3)
+
+---
+updated-dependencies:
+- dependency-name: typescript
+ dependency-type: direct:development
+ update-type: version-update:semver-minor
+...
+
+
+
+dca5109c Bump jest from 25.5.4 to 29.7.0 in /_examples/federation (#2920)
+
+Bumps [jest](https://github.com/jestjs/jest/tree/HEAD/packages/jest) from 25.5.4 to 29.7.0.
+- [Release notes](https://github.com/jestjs/jest/releases)
+- [Changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md)
+- [Commits](https://github.com/jestjs/jest/commits/v29.7.0/packages/jest)
+
+---
+updated-dependencies:
+- dependency-name: jest
+ dependency-type: direct:development
+ update-type: version-update:semver-major
+...
+
+
+
+4d77a4f0 Bump graphql from 14.7.0 to 16.8.1 in /_examples/chat (#2899)
+
+Bumps [graphql](https://github.com/graphql/graphql-js) from 14.7.0 to 16.8.1.
+- [Release notes](https://github.com/graphql/graphql-js/releases)
+- [Commits](https://github.com/graphql/graphql-js/compare/v14.7.0...v16.8.1)
+
+---
+updated-dependencies:
+- dependency-name: graphql
+ dependency-type: direct:production
+ update-type: version-update:semver-major
+...
+
+
+
+76f1a55b Bump github.com/rs/cors from 1.9.0 to 1.10.1 in /_examples (#2904)
+
+Bumps [github.com/rs/cors](https://github.com/rs/cors) from 1.9.0 to 1.10.1.
+- [Release notes](https://github.com/rs/cors/releases)
+- [Commits](https://github.com/rs/cors/compare/v1.9.0...v1.10.1)
+
+---
+updated-dependencies:
+- dependency-name: github.com/rs/cors
+ dependency-type: direct:production
+ update-type: version-update:semver-minor
+...
+
+
+
+bfa9ed8b Bump github.com/google/uuid from 1.3.0 to 1.6.0 in /_examples (#2909)
+
+Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.3.0 to 1.6.0.
+- [Release notes](https://github.com/google/uuid/releases)
+- [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md)
+- [Commits](https://github.com/google/uuid/compare/v1.3.0...v1.6.0)
+
+---
+updated-dependencies:
+- dependency-name: github.com/google/uuid
+ dependency-type: direct:production
+ update-type: version-update:semver-minor
+...
+
+
+
+524fdf78 Bump subscriptions-transport-ws from 0.9.19 to 0.11.0 in /_examples/chat (#2911)
+
+Bumps [subscriptions-transport-ws](https://github.com/apollostack/subscriptions-transport-ws) from 0.9.19 to 0.11.0.
+- [Release notes](https://github.com/apollostack/subscriptions-transport-ws/releases)
+- [Changelog](https://github.com/apollographql/subscriptions-transport-ws/blob/master/CHANGELOG.md)
+- [Commits](https://github.com/apollostack/subscriptions-transport-ws/compare/v0.9.19...v0.11.0)
+
+---
+updated-dependencies:
+- dependency-name: subscriptions-transport-ws
+ dependency-type: direct:production
+ update-type: version-update:semver-minor
+...
+
+
+
+ed5f0bc2 Bump github.com/urfave/cli/v2 from 2.25.5 to 2.27.1 (#2912)
+
+Bumps [github.com/urfave/cli/v2](https://github.com/urfave/cli) from 2.25.5 to 2.27.1.
+- [Release notes](https://github.com/urfave/cli/releases)
+- [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md)
+- [Commits](https://github.com/urfave/cli/compare/v2.25.5...v2.27.1)
+
+---
+updated-dependencies:
+- dependency-name: github.com/urfave/cli/v2
+ dependency-type: direct:production
+ update-type: version-update:semver-minor
+...
+
+
+
+5346a37c Bump react-scripts from 2.1.8 to 5.0.1 in /_examples/chat (#2914)
+
+Bumps [react-scripts](https://github.com/facebook/create-react-app/tree/HEAD/packages/react-scripts) from 2.1.8 to 5.0.1.
+- [Release notes](https://github.com/facebook/create-react-app/releases)
+- [Changelog](https://github.com/facebook/create-react-app/blob/main/CHANGELOG-2.x.md)
+
+---
+updated-dependencies:
+- dependency-name: react-scripts
+ dependency-type: direct:production
+ update-type: version-update:semver-major
+...
+
+
+
+8f8c38db Bump typescript from 4.9.5 to 5.3.3 in /_examples/chat (#2917)
+
+Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.9.5 to 5.3.3.
+- [Release notes](https://github.com/Microsoft/TypeScript/releases)
+- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.9.5...v5.3.3)
+
+---
+updated-dependencies:
+- dependency-name: typescript
+ dependency-type: direct:production
+ update-type: version-update:semver-major
+...
+
+
+
+6d847969 Bump graphql-sse from 2.1.4 to 2.5.2 in /integration (#2913)
+
+Bumps [graphql-sse](https://github.com/enisdenjo/graphql-sse) from 2.1.4 to 2.5.2.
+- [Release notes](https://github.com/enisdenjo/graphql-sse/releases)
+- [Changelog](https://github.com/enisdenjo/graphql-sse/blob/master/CHANGELOG.md)
+- [Commits](https://github.com/enisdenjo/graphql-sse/compare/v2.1.4...v2.5.2)
+
+---
+updated-dependencies:
+- dependency-name: graphql-sse
+ dependency-type: direct:development
+ update-type: version-update:semver-minor
+...
+
+
+
+14e321ad Bump styled-components from 5.3.11 to 6.1.8 in /_examples/chat (#2905)
+
+Bumps [styled-components](https://github.com/styled-components/styled-components) from 5.3.11 to 6.1.8.
+- [Release notes](https://github.com/styled-components/styled-components/releases)
+- [Commits](https://github.com/styled-components/styled-components/compare/v5.3.11...v6.1.8)
+
+---
+updated-dependencies:
+- dependency-name: styled-components
+ dependency-type: direct:production
+ update-type: version-update:semver-major
+...
+
+
+
+76312bc6 Bump vitest from 0.32.0 to 1.2.2 in /integration (#2919)
+
+Bumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 0.32.0 to 1.2.2.
+- [Release notes](https://github.com/vitest-dev/vitest/releases)
+- [Commits](https://github.com/vitest-dev/vitest/commits/v1.2.2/packages/vitest)
+
+---
+updated-dependencies:
+- dependency-name: vitest
+ dependency-type: direct:development
+ update-type: version-update:semver-major
+...
+
+
+
+7b67b2e4 Bump github.com/matryer/moq from 0.2.7 to 0.3.3 (#2902)
+
+Bumps [github.com/matryer/moq](https://github.com/matryer/moq) from 0.2.7 to 0.3.3.
+- [Release notes](https://github.com/matryer/moq/releases)
+- [Changelog](https://github.com/matryer/moq/blob/main/.goreleaser.yml)
+- [Commits](https://github.com/matryer/moq/compare/v0.2.7...v0.3.3)
+
+---
+updated-dependencies:
+- dependency-name: github.com/matryer/moq
+ dependency-type: direct:production
+ update-type: version-update:semver-minor
+...
+
+
+
+96c064c4 Bump github.com/gorilla/websocket from 1.5.0 to 1.5.1 in /_examples (#2901)
+
+Bumps [github.com/gorilla/websocket](https://github.com/gorilla/websocket) from 1.5.0 to 1.5.1.
+- [Release notes](https://github.com/gorilla/websocket/releases)
+- [Commits](https://github.com/gorilla/websocket/compare/v1.5.0...v1.5.1)
+
+---
+updated-dependencies:
+- dependency-name: github.com/gorilla/websocket
+ dependency-type: direct:production
+ update-type: version-update:semver-patch
+...
+
+
+
+8719860b Bump github.com/stretchr/testify from 1.8.2 to 1.8.4 in /_examples (#2897)
+
+Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.2 to 1.8.4.
+- [Release notes](https://github.com/stretchr/testify/releases)
+- [Commits](https://github.com/stretchr/testify/compare/v1.8.2...v1.8.4)
+
+---
+updated-dependencies:
+- dependency-name: github.com/stretchr/testify
+ dependency-type: direct:production
+ update-type: version-update:semver-patch
+...
+
+
+
+6d3c5a82 Bump golangci/golangci-lint-action from 3.5.0 to 3.7.0 (#2896)
+
+Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 3.5.0 to 3.7.0.
+- [Release notes](https://github.com/golangci/golangci-lint-action/releases)
+- [Commits](https://github.com/golangci/golangci-lint-action/compare/v3.5.0...v3.7.0)
+
+---
+updated-dependencies:
+- dependency-name: golangci/golangci-lint-action
+ dependency-type: direct:production
+ update-type: version-update:semver-minor
+...
+
+
+
+ad4d7f25 Bump nick-fields/retry from 2 to 3 (#2907)
+
+Bumps [nick-fields/retry](https://github.com/nick-fields/retry) from 2 to 3.
+- [Release notes](https://github.com/nick-fields/retry/releases)
+- [Changelog](https://github.com/nick-fields/retry/blob/master/.releaserc.js)
+- [Commits](https://github.com/nick-fields/retry/compare/v2...v3)
+
+---
+updated-dependencies:
+- dependency-name: nick-fields/retry
+ dependency-type: direct:production
+ update-type: version-update:semver-major
+...
+
+
+
+912cc8da Bump actions/setup-node from 3 to 4 (#2910)
+
+Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3 to 4.
+- [Release notes](https://github.com/actions/setup-node/releases)
+- [Commits](https://github.com/actions/setup-node/compare/v3...v4)
+
+---
+updated-dependencies:
+- dependency-name: actions/setup-node
+ dependency-type: direct:production
+ update-type: version-update:semver-major
+...
+
+
+
+2f3d96ab Bump actions/checkout from 3 to 4 (#2903)
+
+Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
+- [Release notes](https://github.com/actions/checkout/releases)
+- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
+- [Commits](https://github.com/actions/checkout/compare/v3...v4)
+
+---
+updated-dependencies:
+- dependency-name: actions/checkout
+ dependency-type: direct:production
+ update-type: version-update:semver-major
+...
+
+
+
+34f8d084 Bump actions/setup-go from 3 to 5 (#2900)
+
+Bumps [actions/setup-go](https://github.com/actions/setup-go) from 3 to 5.
+- [Release notes](https://github.com/actions/setup-go/releases)
+- [Commits](https://github.com/actions/setup-go/compare/v3...v5)
+
+---
+updated-dependencies:
+- dependency-name: actions/setup-go
+ dependency-type: direct:production
+ update-type: version-update:semver-major
+...
+
+
+
+143edebe Update x/tools and add go v1.21,v1.22 in CI workflows (#2894)
+
+* Update golang.org/x/tools
+
+* Update Go versions to 1.21 and 1.22 in CI workflows
+
+* Run go mod tidy on submodule _examples
+
+
+* Update to Go 1.20
+
+
+* go modules on for all checks
+
+
+* reduce redundant invocations
+
+
+* add echo to non-sensitive checks
+
+
+* More comments
+
+
+* Make submodule go generate chain differently
+
+
+* Add which cd
+
+
+* Try to figure out why cd is not in path
+
+
+* set CWD to examples in go generate instead
+
+
+* Try export
+
+
+* Use env in go generate comment
+
+
+* make go generate comment always successful
+
+
+* Try shelling out
+
+
+* Update our github actions, npm, and go modules via dependabot
+
+
+---------
+
+
+
+- e174d59e Work with https://specs.apollo.dev/federation/v2.x (#2891)
+
+4d8b6edb Update federation plugin (#2876)
+
+* update 2.7 impl, add missing 2.6 support
+
+* address feedback
+
+* go fmt
+
+
+
+5524a399 Bump vite from 4.3.9 to 4.5.2 in /integration (#2885)
+
+Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.3.9 to 4.5.2.
+- [Release notes](https://github.com/vitejs/vite/releases)
+- [Changelog](https://github.com/vitejs/vite/blob/v4.5.2/packages/vite/CHANGELOG.md)
+- [Commits](https://github.com/vitejs/vite/commits/v4.5.2/packages/vite)
+
+---
+updated-dependencies:
+- dependency-name: vite
+ dependency-type: direct:development
+...
+
+
+
+- 41b14fcf v0.17.43 postrelease bump
+
+
+
+
+
+
+## [v0.17.43](https://github.com/99designs/gqlgen/compare/v0.17.42...v0.17.43) - 2024-01-18
+- 0d5519cf release v0.17.43
+
+- 5779ac21 Update gqlparser to v2.5.11 (#2882)
+
+- f06f58b0 add omitempty config to example gqlgen.yml (#2880)
+
+- 32bdbdd1 Add config option to omit root objects from models (#2878)
+
+5b656891 Fix code generation for federated multi-key, multi-entity types (#2877)
+
+* fix codegen for multi-key, multi-entity type
+
+* adding tests
+
+* updated generated code
+
+---------
+
+
+
+- 15c05a78 Update changelog
+
+- 87a7517a v0.17.42 postrelease bump
+
+
+
+
+
## [v0.17.42](https://github.com/99designs/gqlgen/compare/v0.17.41...v0.17.42) - 2023-12-29
- 7bf0c223 release v0.17.42
@@ -2434,7 +3573,7 @@ when generating next the context was captured there.
Which means later when the returned function from DispatchOperation is
called. The responseContext which accumulates the errors is the
-tempResponseContext which we no longer have access to to read the errors
+tempResponseContext which we no longer have access to read the errors
out of it.
Instead add a context to next() so that it can be passed through and
diff --git a/vendor/github.com/99designs/gqlgen/README.md b/vendor/github.com/99designs/gqlgen/README.md
index 34656595..898b658b 100644
--- a/vendor/github.com/99designs/gqlgen/README.md
+++ b/vendor/github.com/99designs/gqlgen/README.md
@@ -20,9 +20,9 @@ Still not convinced enough to use **gqlgen**? Compare **gqlgen** with other Go g
cd example
go mod init example
-2. Add `github.com/99designs/gqlgen` to your [project's tools.go](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module)
+2. Add `github.com/99designs/gqlgen` to your [project's tools.go](https://go.dev/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module)
- printf '// +build tools\npackage tools\nimport (_ "github.com/99designs/gqlgen"\n _ "github.com/99designs/gqlgen/graphql/introspection")' | gofmt > tools.go
+ printf '//go:build tools\npackage tools\nimport (_ "github.com/99designs/gqlgen"\n _ "github.com/99designs/gqlgen/graphql/introspection")' | gofmt > tools.go
go mod tidy
@@ -135,6 +135,7 @@ models:
model:
- github.com/99designs/gqlgen/graphql.IntID # a go integer
- github.com/99designs/gqlgen/graphql.ID # or a go string
+ - github.com/99designs/gqlgen/graphql.UintID # or a go uint
```
This means gqlgen will be able to automatically bind to strings or ints for models you have written yourself, but the
diff --git a/vendor/github.com/99designs/gqlgen/RELEASE-CHECKLIST.md b/vendor/github.com/99designs/gqlgen/RELEASE-CHECKLIST.md
index ce087bf9..0be8f706 100644
--- a/vendor/github.com/99designs/gqlgen/RELEASE-CHECKLIST.md
+++ b/vendor/github.com/99designs/gqlgen/RELEASE-CHECKLIST.md
@@ -6,10 +6,9 @@ Assuming the next version is $NEW_VERSION=v0.16.0 or something like that.
./bin/release $NEW_VERSION
```
2. git-chglog -o CHANGELOG.md
-3. go generate ./...; cd _examples; go generate ./...; cd ..
+3. go generate ./...
4. git commit and push the CHANGELOG.md
5. Go to https://github.com/99designs/gqlgen/releases and draft new release, autogenerate the release notes, and Create a discussion for this release
6. Comment on the release discussion with any really important notes (breaking changes)
I used https://github.com/git-chglog/git-chglog to automate the changelog maintenance process for now. We could just as easily use go releaser to make the whole thing automated.
-
diff --git a/vendor/github.com/99designs/gqlgen/api/generate.go b/vendor/github.com/99designs/gqlgen/api/generate.go
index 8193f2fb..8102b744 100644
--- a/vendor/github.com/99designs/gqlgen/api/generate.go
+++ b/vendor/github.com/99designs/gqlgen/api/generate.go
@@ -13,6 +13,11 @@ import (
"github.com/99designs/gqlgen/plugin/resolvergen"
)
+var (
+ urlRegex = regexp.MustCompile(`(?s)@link.*\(.*url:.*?"(.*?)"[^)]+\)`) // regex to grab the url of a link directive, should it exist
+ versionRegex = regexp.MustCompile(`v(\d+).(\d+)$`) // regex to grab the version number from a url
+)
+
func Generate(cfg *config.Config, option ...Option) error {
_ = syscall.Unlink(cfg.Exec.Filename)
if cfg.Model.IsDefined() {
@@ -26,8 +31,6 @@ func Generate(cfg *config.Config, option ...Option) error {
plugins = append(plugins, resolvergen.New())
if cfg.Federation.IsDefined() {
if cfg.Federation.Version == 0 { // default to using the user's choice of version, but if unset, try to sort out which federation version to use
- urlRegex := regexp.MustCompile(`(?s)@link.*\(.*url:.*?"(.*?)"[^)]+\)`) // regex to grab the url of a link directive, should it exist
- versionRegex := regexp.MustCompile(`v(\d+).(\d+)$`) // regex to grab the version number from a url
// check the sources, and if one is marked as federation v2, we mark the entirety to be generated using that format
for _, v := range cfg.Sources {
cfg.Federation.Version = 1
diff --git a/vendor/github.com/99designs/gqlgen/codegen/config/binder.go b/vendor/github.com/99designs/gqlgen/codegen/config/binder.go
index a50de90a..6a488032 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/config/binder.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/config/binder.go
@@ -5,6 +5,7 @@ import (
"fmt"
"go/token"
"go/types"
+ "strings"
"github.com/vektah/gqlparser/v2/ast"
"golang.org/x/tools/go/packages"
@@ -204,6 +205,7 @@ type TypeReference struct {
IsContext bool // Is the Marshaler/Unmarshaller the context version; applies to either the method or interface variety.
PointersInUmarshalInput bool // Inverse values and pointers in return.
IsRoot bool // Is the type a root level definition such as Query, Mutation or Subscription
+ EnumValues []EnumValueReference
}
func (ref *TypeReference) Elem() *TypeReference {
@@ -321,6 +323,10 @@ func (ref *TypeReference) IsTargetNilable() bool {
return IsNilable(ref.Target)
}
+func (ref *TypeReference) HasEnumValues() bool {
+ return len(ref.EnumValues) > 0
+}
+
func (b *Binder) PushRef(ret *TypeReference) {
b.References = append(b.References, ret)
}
@@ -428,7 +434,12 @@ func (b *Binder) TypeReference(schemaType *ast.Type, bindTarget types.Type) (ret
return nil, err
}
- if fun, isFunc := obj.(*types.Func); isFunc {
+ if values := b.enumValues(def); len(values) > 0 {
+ err = b.enumReference(ref, obj, values)
+ if err != nil {
+ return nil, err
+ }
+ } else if fun, isFunc := obj.(*types.Func); isFunc {
ref.GO = fun.Type().(*types.Signature).Params().At(0).Type()
ref.IsContext = fun.Type().(*types.Signature).Results().At(0).Type().String() == "github.com/99designs/gqlgen/graphql.ContextMarshaler"
ref.Marshaler = fun
@@ -548,3 +559,81 @@ func basicUnderlying(it types.Type) *types.Basic {
return nil
}
+
+type EnumValueReference struct {
+ Definition *ast.EnumValueDefinition
+ Object types.Object
+}
+
+func (b *Binder) enumValues(def *ast.Definition) map[string]EnumValue {
+ if def.Kind != ast.Enum {
+ return nil
+ }
+
+ if strings.HasPrefix(def.Name, "__") {
+ return nil
+ }
+
+ model, ok := b.cfg.Models[def.Name]
+ if !ok {
+ return nil
+ }
+
+ return model.EnumValues
+}
+
+func (b *Binder) enumReference(ref *TypeReference, obj types.Object, values map[string]EnumValue) error {
+ if len(ref.Definition.EnumValues) != len(values) {
+ return fmt.Errorf("not all enum values are binded for %v", ref.Definition.Name)
+ }
+
+ if fn, ok := obj.Type().(*types.Signature); ok {
+ ref.GO = fn.Params().At(0).Type()
+ } else {
+ ref.GO = obj.Type()
+ }
+
+ str, err := b.TypeReference(&ast.Type{NamedType: "String"}, nil)
+ if err != nil {
+ return err
+ }
+
+ ref.Marshaler = str.Marshaler
+ ref.Unmarshaler = str.Unmarshaler
+ ref.EnumValues = make([]EnumValueReference, 0, len(values))
+
+ for _, value := range ref.Definition.EnumValues {
+ v, ok := values[value.Name]
+ if !ok {
+ return fmt.Errorf("enum value not found for: %v, of enum: %v", value.Name, ref.Definition.Name)
+ }
+
+ pkgName, typeName := code.PkgAndType(v.Value)
+ if pkgName == "" {
+ return fmt.Errorf("missing package name for %v", value.Name)
+ }
+
+ valueObj, err := b.FindObject(pkgName, typeName)
+ if err != nil {
+ return err
+ }
+
+ if !types.AssignableTo(valueObj.Type(), ref.GO) {
+ return fmt.Errorf("wrong type: %v, for enum value: %v, expected type: %v, of enum: %v",
+ valueObj.Type(), value.Name, ref.GO, ref.Definition.Name)
+ }
+
+ switch valueObj.(type) {
+ case *types.Const, *types.Var:
+ ref.EnumValues = append(ref.EnumValues, EnumValueReference{
+ Definition: value,
+ Object: valueObj,
+ })
+ default:
+ return fmt.Errorf("unsupported enum value for: %v, of enum: %v, only const and var allowed",
+ value.Name, ref.Definition.Name)
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/config/config.go b/vendor/github.com/99designs/gqlgen/codegen/config/config.go
index d1c6fe86..39120e56 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/config/config.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/config/config.go
@@ -275,6 +275,10 @@ func (c *Config) injectTypesFromSchema() error {
SkipRuntime: true,
}
+ c.Directives["goExtraField"] = DirectiveConfig{
+ SkipRuntime: true,
+ }
+
c.Directives["goField"] = DirectiveConfig{
SkipRuntime: true,
}
@@ -283,6 +287,10 @@ func (c *Config) injectTypesFromSchema() error {
SkipRuntime: true,
}
+ c.Directives["goEnum"] = DirectiveConfig{
+ SkipRuntime: true,
+ }
+
for _, schemaType := range c.Schema.Types {
if c.IsRoot(schemaType) {
continue
@@ -342,6 +350,82 @@ func (c *Config) injectTypesFromSchema() error {
}
}
}
+
+ if efds := schemaType.Directives.ForNames("goExtraField"); len(efds) != 0 {
+ for _, efd := range efds {
+ if fn := efd.Arguments.ForName("name"); fn != nil {
+ extraFieldName := ""
+ if fnv, err := fn.Value.Value(nil); err == nil {
+ extraFieldName = fnv.(string)
+ }
+
+ if extraFieldName == "" {
+ return fmt.Errorf(
+ "argument 'name' for directive @goExtraField (src: %s, line: %d) cannot by empty",
+ efd.Position.Src.Name,
+ efd.Position.Line,
+ )
+ }
+
+ extraField := ModelExtraField{}
+ if t := efd.Arguments.ForName("type"); t != nil {
+ if tv, err := t.Value.Value(nil); err == nil {
+ extraField.Type = tv.(string)
+ }
+ }
+
+ if extraField.Type == "" {
+ return fmt.Errorf(
+ "argument 'type' for directive @goExtraField (src: %s, line: %d) cannot by empty",
+ efd.Position.Src.Name,
+ efd.Position.Line,
+ )
+ }
+
+ if ot := efd.Arguments.ForName("overrideTags"); ot != nil {
+ if otv, err := ot.Value.Value(nil); err == nil {
+ extraField.OverrideTags = otv.(string)
+ }
+ }
+
+ if d := efd.Arguments.ForName("description"); d != nil {
+ if dv, err := d.Value.Value(nil); err == nil {
+ extraField.Description = dv.(string)
+ }
+ }
+
+ typeMapEntry := c.Models[schemaType.Name]
+ if typeMapEntry.ExtraFields == nil {
+ typeMapEntry.ExtraFields = make(map[string]ModelExtraField)
+ }
+
+ c.Models[schemaType.Name] = typeMapEntry
+ c.Models[schemaType.Name].ExtraFields[extraFieldName] = extraField
+ }
+ }
+ }
+ }
+
+ if schemaType.Kind == ast.Enum && !strings.HasPrefix(schemaType.Name, "__") {
+ values := make(map[string]EnumValue)
+
+ for _, value := range schemaType.EnumValues {
+ if directive := value.Directives.ForName("goEnum"); directive != nil {
+ if arg := directive.Arguments.ForName("value"); arg != nil {
+ if v, err := arg.Value.Value(nil); err == nil {
+ values[value.Name] = EnumValue{
+ Value: v.(string),
+ }
+ }
+ }
+ }
+ }
+
+ if len(values) > 0 {
+ model := c.Models[schemaType.Name]
+ model.EnumValues = values
+ c.Models[schemaType.Name] = model
+ }
}
}
@@ -352,6 +436,7 @@ type TypeMapEntry struct {
Model StringList `yaml:"model,omitempty"`
ForceGenerate bool `yaml:"forceGenerate,omitempty"`
Fields map[string]TypeMapField `yaml:"fields,omitempty"`
+ EnumValues map[string]EnumValue `yaml:"enum_values,omitempty"`
// Key is the Go name of the field.
ExtraFields map[string]ModelExtraField `yaml:"extraFields,omitempty"`
@@ -363,6 +448,10 @@ type TypeMapField struct {
GeneratedMethod string `yaml:"-"`
}
+type EnumValue struct {
+ Value string
+}
+
type ModelExtraField struct {
// Type is the Go type of the field.
//
@@ -518,6 +607,14 @@ func (tm TypeMap) Check() error {
return fmt.Errorf("model %s: invalid type specifier \"%s\" - you need to specify a struct to map to", typeName, entry.Model)
}
}
+
+ if len(entry.Model) == 0 {
+ for enum, v := range entry.EnumValues {
+ if v.Value != "" {
+ return fmt.Errorf("model is empty for: %v, but enum value is specified for %v", typeName, enum)
+ }
+ }
+ }
}
return nil
}
diff --git a/vendor/github.com/99designs/gqlgen/codegen/directive.go b/vendor/github.com/99designs/gqlgen/codegen/directive.go
index f955665b..2034abfc 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/directive.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/directive.go
@@ -124,7 +124,6 @@ func (b *builder) getDirectives(list ast.DirectiveList) ([]*Directive, error) {
DirectiveDefinition: list[i].Definition,
Builtin: b.Config.Directives[d.Name].SkipRuntime,
}
-
}
return dirs, nil
diff --git a/vendor/github.com/99designs/gqlgen/codegen/field.go b/vendor/github.com/99designs/gqlgen/codegen/field.go
index 1af2d836..f58d7087 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/field.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/field.go
@@ -287,7 +287,7 @@ func (b *builder) findBindStructTagTarget(in types.Type, name string) (types.Obj
tags := reflect.StructTag(t.Tag(i))
if val, ok := tags.Lookup(b.Config.StructTag); ok && equalFieldName(val, name) {
if found != nil {
- return nil, fmt.Errorf("tag %s is ambigious; multiple fields have the same tag value of %s", b.Config.StructTag, val)
+ return nil, fmt.Errorf("tag %s is ambiguous; multiple fields have the same tag value of %s", b.Config.StructTag, val)
}
found = field
diff --git a/vendor/github.com/99designs/gqlgen/codegen/field.gotpl b/vendor/github.com/99designs/gqlgen/codegen/field.gotpl
index de031769..124a6ff3 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/field.gotpl
+++ b/vendor/github.com/99designs/gqlgen/codegen/field.gotpl
@@ -21,7 +21,7 @@ func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Contex
res := &{{ $field.TypeReference.Elem.GO | ref }}{}
{{- else }}
res := {{ $field.TypeReference.GO | ref }}{}
- {{- end }}
+ {{- end }}
fc.Result = res
return ec.{{ $field.TypeReference.MarshalFunc }}(ctx, field.Selections, res)
{{- else}}
@@ -72,7 +72,7 @@ func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Contex
{{- end }}
}
-func (ec *executionContext) {{ $field.FieldContextFunc }}(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
+func (ec *executionContext) {{ $field.FieldContextFunc }}({{ if not $field.Args }}_{{ else }}ctx{{ end }} context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: {{quote $field.Object.Name}},
Field: field,
diff --git a/vendor/github.com/99designs/gqlgen/codegen/object.gotpl b/vendor/github.com/99designs/gqlgen/codegen/object.gotpl
index adb1df49..604e58ff 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/object.gotpl
+++ b/vendor/github.com/99designs/gqlgen/codegen/object.gotpl
@@ -48,7 +48,7 @@ func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.Selec
{{- if $field.IsConcurrent }}
field := field
- innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) {
+ innerFunc := func(ctx context.Context, {{ if $field.TypeReference.GQL.NonNull }}fs{{ else }}_{{ end }} *graphql.FieldSet) (res graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
diff --git a/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go b/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go
index 4a4e9159..669ab58d 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go
+++ b/vendor/github.com/99designs/gqlgen/codegen/templates/templates.go
@@ -201,6 +201,7 @@ func Funcs() template.FuncMap {
"rawQuote": rawQuote,
"dump": Dump,
"ref": ref,
+ "obj": obj,
"ts": TypeIdentifier,
"call": Call,
"prefixLines": prefixLines,
@@ -247,6 +248,15 @@ func ref(p types.Type) string {
return CurrentImports.LookupType(p)
}
+func obj(obj types.Object) string {
+ pkg := CurrentImports.Lookup(obj.Pkg().Path())
+ if pkg != "" {
+ pkg += "."
+ }
+
+ return pkg + obj.Name()
+}
+
func Call(p *types.Func) string {
pkg := CurrentImports.Lookup(p.Pkg().Path())
diff --git a/vendor/github.com/99designs/gqlgen/codegen/type.gotpl b/vendor/github.com/99designs/gqlgen/codegen/type.gotpl
index 272f3db3..116f0a90 100644
--- a/vendor/github.com/99designs/gqlgen/codegen/type.gotpl
+++ b/vendor/github.com/99designs/gqlgen/codegen/type.gotpl
@@ -34,7 +34,10 @@
return &pres, nil
{{- else }}
{{- if $type.Unmarshaler }}
- {{- if $type.CastType }}
+ {{- if $type.HasEnumValues }}
+ tmp, err := {{ $type.Unmarshaler | call }}(v)
+ res := {{ $type.UnmarshalFunc }}[tmp]
+ {{- else if $type.CastType }}
{{- if $type.IsContext }}
tmp, err := {{ $type.Unmarshaler | call }}(ctx, v)
{{- else }}
@@ -170,7 +173,12 @@
{{- else if and (not $type.IsTargetNilable) $type.IsNilable }}
{{- $v = "*v" }}
{{- end }}
- res := {{ $type.Marshaler | call }}({{- if $type.CastType }}{{ $type.CastType | ref }}({{ $v }}){{else}}{{ $v }}{{- end }})
+ {{- if $type.HasEnumValues }}
+ {{- $v = printf "%v[%v]" $type.MarshalFunc $v }}
+ {{- else if $type.CastType }}
+ {{- $v = printf "%v(%v)" ($type.CastType | ref) $v}}
+ {{- end }}
+ res := {{ $type.Marshaler | call }}({{ $v }})
{{- if $type.GQL.NonNull }}
if res == graphql.Null {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
@@ -196,4 +204,23 @@
{{- end }}
}
{{- end }}
+
+ {{- if $type.HasEnumValues }}
+ {{- $enum := $type.GO }}
+ {{- if $type.IsNilable }}
+ {{- $enum = $type.GO.Elem }}
+ {{- end }}
+ var (
+ {{ $type.UnmarshalFunc }} = map[string]{{ $enum | ref }}{
+ {{- range $value := $type.EnumValues }}
+ "{{ $value.Definition.Name }}": {{ $value.Object | obj }},
+ {{- end }}
+ }
+ {{ $type.MarshalFunc }} = map[{{ $enum | ref }}]string{
+ {{- range $value := $type.EnumValues }}
+ {{ $value.Object | obj }}: "{{ $value.Definition.Name }}",
+ {{- end }}
+ }
+ )
+ {{- end }}
{{- end }}
diff --git a/vendor/github.com/99designs/gqlgen/generate_examples.sh b/vendor/github.com/99designs/gqlgen/generate_examples.sh
deleted file mode 100644
index 814a8d85..00000000
--- a/vendor/github.com/99designs/gqlgen/generate_examples.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env sh
-cd ./_examples
-go generate ./... || return 0
diff --git a/vendor/github.com/99designs/gqlgen/graphql/context_path.go b/vendor/github.com/99designs/gqlgen/graphql/context_path.go
index a46ed83d..bdb53e7a 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/context_path.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/context_path.go
@@ -34,7 +34,6 @@ func (fic *PathContext) Path() ast.Path {
if fic.ParentField != nil {
fieldPath := fic.ParentField.Path()
return append(fieldPath, path...)
-
}
return path
diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/server.go b/vendor/github.com/99designs/gqlgen/graphql/handler/server.go
index fd365ccb..893f0944 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/handler/server.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/handler/server.go
@@ -107,7 +107,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
resp := &graphql.Response{Errors: []*gqlerror.Error{gqlErr}}
b, _ := json.Marshal(resp)
w.WriteHeader(http.StatusUnprocessableEntity)
- w.Write(b)
+ _, _ = w.Write(b)
}
}()
@@ -128,7 +128,7 @@ func sendError(w http.ResponseWriter, code int, errors ...*gqlerror.Error) {
if err != nil {
panic(err)
}
- w.Write(b)
+ _, _ = w.Write(b)
}
func sendErrorf(w http.ResponseWriter, code int, format string, args ...interface{}) {
diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/error.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/error.go
index 18f09f55..7c4e2d8e 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/error.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/error.go
@@ -18,7 +18,7 @@ func SendError(w http.ResponseWriter, code int, errors ...*gqlerror.Error) {
if err != nil {
panic(err)
}
- w.Write(b)
+ _, _ = w.Write(b)
}
// SendErrorf wraps SendError to add formatted messages
diff --git a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go
index e1334b92..236a30c2 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/handler/transport/websocket.go
@@ -103,7 +103,7 @@ func (t Websocket) Do(w http.ResponseWriter, r *http.Request, exec graphql.Graph
switch ws.Subprotocol() {
default:
msg := websocket.FormatCloseMessage(websocket.CloseProtocolError, fmt.Sprintf("unsupported negotiated subprotocol %s", ws.Subprotocol()))
- ws.WriteMessage(websocket.CloseMessage, msg)
+ _ = ws.WriteMessage(websocket.CloseMessage, msg)
return
case graphqlwsSubprotocol, "":
// clients are required to send a subprotocol, to be backward compatible with the previous implementation we select
@@ -272,7 +272,7 @@ func (c *wsConnection) run() {
if !c.MissingPongOk {
// Note: when the connection is closed by this deadline, the client
// will receive an "invalid close code"
- c.conn.SetReadDeadline(time.Now().UTC().Add(2 * c.PingPongInterval))
+ _ = c.conn.SetReadDeadline(time.Now().UTC().Add(2 * c.PingPongInterval))
}
go c.ping(ctx)
}
@@ -312,7 +312,7 @@ func (c *wsConnection) run() {
c.receivedPong = true
c.mu.Unlock()
// Clear ReadTimeout -- 0 time val clears.
- c.conn.SetReadDeadline(time.Time{})
+ _ = c.conn.SetReadDeadline(time.Time{})
default:
c.sendConnectionError("unexpected message %s", m.t)
c.close(websocket.CloseProtocolError, "unexpected message")
@@ -357,7 +357,7 @@ func (c *wsConnection) ping(ctx context.Context) {
// if we have not yet received a pong, don't reset the deadline.
c.mu.Lock()
if !c.MissingPongOk && c.receivedPong {
- c.conn.SetReadDeadline(time.Now().UTC().Add(2 * c.PingPongInterval))
+ _ = c.conn.SetReadDeadline(time.Now().UTC().Add(2 * c.PingPongInterval))
}
c.receivedPong = false
c.mu.Unlock()
diff --git a/vendor/github.com/99designs/gqlgen/graphql/id.go b/vendor/github.com/99designs/gqlgen/graphql/id.go
index b24605d1..0583995f 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/id.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/id.go
@@ -56,3 +56,32 @@ func UnmarshalIntID(v interface{}) (int, error) {
return 0, fmt.Errorf("%T is not an int", v)
}
}
+
+func MarshalUintID(i uint) Marshaler {
+ return WriterFunc(func(w io.Writer) {
+ writeQuotedString(w, strconv.FormatUint(uint64(i), 10))
+ })
+}
+
+func UnmarshalUintID(v interface{}) (uint, error) {
+ switch v := v.(type) {
+ case string:
+ result, err := strconv.ParseUint(v, 10, 64)
+ return uint(result), err
+ case int:
+ return uint(v), nil
+ case int64:
+ return uint(v), nil
+ case int32:
+ return uint(v), nil
+ case uint32:
+ return uint(v), nil
+ case uint64:
+ return uint(v), nil
+ case json.Number:
+ result, err := strconv.ParseUint(string(v), 10, 64)
+ return uint(result), err
+ default:
+ return 0, fmt.Errorf("%T is not an uint", v)
+ }
+}
diff --git a/vendor/github.com/99designs/gqlgen/graphql/version.go b/vendor/github.com/99designs/gqlgen/graphql/version.go
index 93f58b54..630b49f3 100644
--- a/vendor/github.com/99designs/gqlgen/graphql/version.go
+++ b/vendor/github.com/99designs/gqlgen/graphql/version.go
@@ -1,3 +1,3 @@
package graphql
-const Version = "v0.17.45"
+const Version = "v0.17.47"
diff --git a/vendor/github.com/99designs/gqlgen/internal/code/packages.go b/vendor/github.com/99designs/gqlgen/internal/code/packages.go
index e7f8655a..17fd5bb6 100644
--- a/vendor/github.com/99designs/gqlgen/internal/code/packages.go
+++ b/vendor/github.com/99designs/gqlgen/internal/code/packages.go
@@ -21,12 +21,10 @@ var (
var mode = packages.NeedName |
packages.NeedFiles |
- packages.NeedImports |
packages.NeedTypes |
packages.NeedSyntax |
packages.NeedTypesInfo |
- packages.NeedModule |
- packages.NeedDeps
+ packages.NeedModule
type (
// Packages is a wrapper around x/tools/go/packages that maintains a (hopefully prewarmed) cache of packages
@@ -135,11 +133,6 @@ func (p *Packages) LoadAll(importPaths ...string) []*packages.Package {
func (p *Packages) addToCache(pkg *packages.Package) {
imp := NormalizeVendor(pkg.PkgPath)
p.packages[imp] = pkg
- for _, imp := range pkg.Imports {
- if _, found := p.packages[NormalizeVendor(imp.PkgPath)]; !found {
- p.addToCache(imp)
- }
- }
}
// Load works the same as LoadAll, except a single package at a time.
@@ -220,18 +213,9 @@ func (p *Packages) NameForPackage(importPath string) string {
return pkg.Name
}
-// Evict removes a given package import path from the cache, along with any packages that depend on it. Further calls
-// to Load will fetch it from disk.
+// Evict removes a given package import path from the cache. Further calls to Load will fetch it from disk.
func (p *Packages) Evict(importPath string) {
delete(p.packages, importPath)
-
- for _, pkg := range p.packages {
- for _, imported := range pkg.Imports {
- if imported.PkgPath == importPath {
- p.Evict(pkg.PkgPath)
- }
- }
- }
}
func (p *Packages) ModTidy() error {
diff --git a/vendor/github.com/99designs/gqlgen/internal/rewrite/rewriter.go b/vendor/github.com/99designs/gqlgen/internal/rewrite/rewriter.go
index 7e68e55d..909cfe71 100644
--- a/vendor/github.com/99designs/gqlgen/internal/rewrite/rewriter.go
+++ b/vendor/github.com/99designs/gqlgen/internal/rewrite/rewriter.go
@@ -63,7 +63,6 @@ func (r *Rewriter) getFile(filename string) string {
}
r.files[filename] = string(b)
-
}
return r.files[filename]
diff --git a/vendor/github.com/99designs/gqlgen/main.go b/vendor/github.com/99designs/gqlgen/main.go
index a50f1e27..c920ec27 100644
--- a/vendor/github.com/99designs/gqlgen/main.go
+++ b/vendor/github.com/99designs/gqlgen/main.go
@@ -1,6 +1,6 @@
package main
-//go:generate sh generate_examples.sh
+//go:generate sh -c "cd _examples && go generate ./..."
import (
"bytes"
diff --git a/vendor/github.com/99designs/gqlgen/plugin/federation/federation.go b/vendor/github.com/99designs/gqlgen/plugin/federation/federation.go
index 240311ac..fd33255b 100644
--- a/vendor/github.com/99designs/gqlgen/plugin/federation/federation.go
+++ b/vendor/github.com/99designs/gqlgen/plugin/federation/federation.go
@@ -182,7 +182,6 @@ func (f *federation) InjectSourceLate(schema *ast.Schema) *ast.Source {
var entities, resolvers, entityResolverInputDefinitions string
for _, e := range f.Entities {
-
if e.Def.Kind != ast.Interface {
if entities != "" {
entities += " | "
@@ -329,7 +328,6 @@ func (f *federation) GenerateCode(data *codegen.Data) error {
// add type info to entity
e.Type = obj.Type
-
}
}
@@ -416,7 +414,6 @@ func (f *federation) GenerateCode(data *codegen.Data) error {
if err != nil {
return err
}
-
}
return templates.Render(templates.Options{
diff --git a/vendor/github.com/99designs/gqlgen/plugin/federation/federation.gotpl b/vendor/github.com/99designs/gqlgen/plugin/federation/federation.gotpl
index ca0e6e2d..119bab5b 100644
--- a/vendor/github.com/99designs/gqlgen/plugin/federation/federation.gotpl
+++ b/vendor/github.com/99designs/gqlgen/plugin/federation/federation.gotpl
@@ -253,19 +253,30 @@ func (ec *executionContext) __resolve_entities(ctx context.Context, representati
ok bool
)
_ = val
+ // if all of the KeyFields values for this resolver are null,
+ // we shouldn't use use it
+ allNull := true
{{- range $_, $keyField := .KeyFields }}
m = rep
{{- range $i, $field := .Field }}
- if {{ if (ne $i $keyField.Field.LastIndex ) -}}val{{- else -}}_{{- end -}}, ok = m["{{.}}"]; !ok {
+ val, ok = m["{{.}}"]
+ if !ok {
break
}
{{- if (ne $i $keyField.Field.LastIndex ) }}
if m, ok = val.(map[string]interface{}); !ok {
break
}
+ {{- else}}
+ if allNull {
+ allNull = val == nil
+ }
{{- end}}
{{- end}}
{{- end }}
+ if allNull {
+ break
+ }
return "{{.ResolverName}}", nil
}
{{- end }}
diff --git a/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go b/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go
index f59991a0..9b60923f 100644
--- a/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go
+++ b/vendor/github.com/99designs/gqlgen/plugin/modelgen/models.go
@@ -176,7 +176,6 @@ func (m *Plugin) MutateConfig(cfg *config.Config) error {
uniqueMap[iface] = true
}
}
-
}
b.Models = append(b.Models, it)
diff --git a/vendor/github.com/99designs/gqlgen/plugin/plugin.go b/vendor/github.com/99designs/gqlgen/plugin/plugin.go
index ccb8f8b9..a5e1ba84 100644
--- a/vendor/github.com/99designs/gqlgen/plugin/plugin.go
+++ b/vendor/github.com/99designs/gqlgen/plugin/plugin.go
@@ -33,5 +33,5 @@ type LateSourceInjector interface {
// ResolverImplementer is used to generate code inside resolvers
type ResolverImplementer interface {
- Implement(field *codegen.Field) string
+ Implement(prevImplementation string, field *codegen.Field) string
}
diff --git a/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go b/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go
index 085c2958..97a20477 100644
--- a/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go
+++ b/vendor/github.com/99designs/gqlgen/plugin/resolvergen/resolver.go
@@ -127,14 +127,9 @@ func (m *Plugin) generatePerSchema(data *codegen.Data) error {
if !f.IsResolver {
continue
}
-
structName := templates.LcFirst(o.Name) + templates.UcFirst(data.Config.Resolver.Type)
comment := strings.TrimSpace(strings.TrimLeft(rewriter.GetMethodComment(structName, f.GoFieldName), `\`))
implementation := strings.TrimSpace(rewriter.GetMethodBody(structName, f.GoFieldName))
- if implementation == "" {
- // use default implementation, if no implementation was previously used
- implementation = fmt.Sprintf("panic(fmt.Errorf(\"not implemented: %v - %v\"))", f.GoFieldName, f.Name)
- }
resolver := Resolver{o, f, rewriter.GetPrevDecl(structName, f.GoFieldName), comment, implementation, nil}
var implExists bool
for _, p := range data.Plugins {
@@ -257,13 +252,20 @@ type Resolver struct {
PrevDecl *ast.FuncDecl
Comment string
ImplementationStr string
- ImplementationRender func(r *codegen.Field) string
+ ImplementationRender func(prevImplementation string, r *codegen.Field) string
}
func (r *Resolver) Implementation() string {
if r.ImplementationRender != nil {
- return r.ImplementationRender(r.Field)
+ // use custom implementation
+ return r.ImplementationRender(r.ImplementationStr, r.Field)
}
+ // if not implementation was previously used, use default implementation
+ if r.ImplementationStr == "" {
+ // use default implementation, if no implementation was previously used
+ return fmt.Sprintf("panic(fmt.Errorf(\"not implemented: %v - %v\"))", r.Field.GoFieldName, r.Field.Name)
+ }
+ // use previously used implementation
return r.ImplementationStr
}
diff --git a/vendor/github.com/caddyserver/certmagic/README.md b/vendor/github.com/caddyserver/certmagic/README.md
index 8e3b145d..c1aa8f52 100644
--- a/vendor/github.com/caddyserver/certmagic/README.md
+++ b/vendor/github.com/caddyserver/certmagic/README.md
@@ -60,13 +60,16 @@ CertMagic - Automatic HTTPS using Let's Encrypt
- [Advanced use](#advanced-use)
- [Wildcard Certificates](#wildcard-certificates)
- [Behind a load balancer (or in a cluster)](#behind-a-load-balancer-or-in-a-cluster)
- - [The ACME Challenges](#the-acme-challenges)
- - [HTTP Challenge](#http-challenge)
- - [TLS-ALPN Challenge](#tls-alpn-challenge)
- - [DNS Challenge](#dns-challenge)
- - [On-Demand TLS](#on-demand-tls)
- - [Storage](#storage)
- - [Cache](#cache)
+- [The ACME Challenges](#the-acme-challenges)
+ - [HTTP Challenge](#http-challenge)
+ - [TLS-ALPN Challenge](#tls-alpn-challenge)
+ - [DNS Challenge](#dns-challenge)
+- [On-Demand TLS](#on-demand-tls)
+- [Storage](#storage)
+- [Cache](#cache)
+- [Events](#events)
+- [ZeroSSL](#zerossl)
+- [FAQ](#faq)
- [Contributing](#contributing)
- [Project History](#project-history)
- [Credits and License](#credits-and-license)
@@ -87,7 +90,7 @@ CertMagic - Automatic HTTPS using Let's Encrypt
- Exponential backoff with carefully-tuned intervals
- Retries with optional test/staging CA endpoint instead of production, to avoid rate limits
- Written in Go, a language with memory-safety guarantees
-- Powered by [ACMEz](https://github.com/mholt/acmez), _the_ premier ACME client library for Go
+- Powered by [ACMEz](https://github.com/mholt/acmez/v2), _the_ premier ACME client library for Go
- All [libdns](https://github.com/libdns) DNS providers work out-of-the-box
- Pluggable storage backends (default: file system)
- Pluggable key sources
@@ -110,6 +113,7 @@ CertMagic - Automatic HTTPS using Let's Encrypt
- Cross-platform support! Mac, Windows, Linux, BSD, Android...
- Scales to hundreds of thousands of names/certificates per instance
- Use in conjunction with your own certificates
+- Full support for [draft-ietf-acme-ari](https://datatracker.ietf.org/doc/draft-ietf-acme-ari/) (ACME Renewal Information; ARI) extension
## Requirements
@@ -125,6 +129,7 @@ CertMagic - Automatic HTTPS using Let's Encrypt
4. Persistent storage
- Typically the local file system (default)
- Other integrations available/possible
+5. Go 1.21 or newer
**_Before using this library, your domain names MUST be pointed (A/AAAA records) at your server (unless you use the DNS challenge)!_**
@@ -292,7 +297,7 @@ tlsConfig.NextProtos = append([]string{"h2", "http/1.1"}, tlsConfig.NextProtos..
// we can simply set its GetCertificate field and append the
// TLS-ALPN challenge protocol to the NextProtos
myTLSConfig.GetCertificate = magic.GetCertificate
-myTLSConfig.NextProtos = append(myTLSConfig.NextProtos, tlsalpn01.ACMETLS1Protocol)
+myTLSConfig.NextProtos = append(myTLSConfig.NextProtos, acmez.ACMETLS1Protocol)
// the HTTP challenge has to be handled by your HTTP server;
// if you don't have one, you should have disabled it earlier
@@ -379,7 +384,7 @@ Or make two simple changes to an existing `tls.Config`:
```go
myTLSConfig.GetCertificate = magic.GetCertificate
-myTLSConfig.NextProtos = append(myTLSConfig.NextProtos, tlsalpn01.ACMETLS1Protocol}
+myTLSConfig.NextProtos = append(myTLSConfig.NextProtos, acmez.ACMETLS1Protocol}
```
Then just make sure your TLS listener is listening on port 443:
@@ -401,8 +406,10 @@ To enable it, just set the `DNS01Solver` field on a `certmagic.ACMEIssuer` struc
import "github.com/libdns/cloudflare"
certmagic.DefaultACME.DNS01Solver = &certmagic.DNS01Solver{
- DNSProvider: &cloudflare.Provider{
- APIToken: "topsecret",
+ DNSManager: certmagic.DNSManager{
+ DNSProvider: &cloudflare.Provider{
+ APIToken: "topsecret",
+ },
},
}
```
@@ -504,6 +511,26 @@ CertMagic emits events when possible things of interest happen. Set the [`OnEven
`OnEvent` can return an error. Some events may be aborted by returning an error. For example, returning an error from `cert_obtained` can cancel obtaining the certificate. Only return an error from `OnEvent` if you want to abort program flow.
+## ZeroSSL
+
+ZeroSSL has both ACME and HTTP API services for getting certificates. CertMagic works with both of them.
+
+To use ZeroSSL's ACME server, configure CertMagic with an [`ACMEIssuer`](https://pkg.go.dev/github.com/caddyserver/certmagic#ACMEIssuer) like you would with any other ACME CA (just adjust the directory URL). External Account Binding (EAB) is required for ZeroSSL. You can use the [ZeroSSL API](https://pkg.go.dev/github.com/caddyserver/zerossl) to generate one, or your account dashboard.
+
+To use ZeroSSL's API instead, use the [`ZeroSSLIssuer`](https://pkg.go.dev/github.com/caddyserver/certmagic#ZeroSSLIssuer). Here is a simple example:
+
+```go
+magic := certmagic.NewDefault()
+
+magic.Issuers = []certmagic.Issuer{
+ certmagic.ZeroSSLIssuer{
+ APIKey: "",
+ }),
+}
+
+err := magic.ManageSync(ctx, []string{"example.com"})
+```
+
## FAQ
### Can I use some of my own certificates while using CertMagic?
@@ -540,7 +567,7 @@ We welcome your contributions! Please see our **[contributing guidelines](https:
## Project History
-CertMagic is the core of Caddy's advanced TLS automation code, extracted into a library. The underlying ACME client implementation is [ACMEz](https://github.com/mholt/acmez). CertMagic's code was originally a central part of Caddy even before Let's Encrypt entered public beta in 2015.
+CertMagic is the core of Caddy's advanced TLS automation code, extracted into a library. The underlying ACME client implementation is [ACMEz](https://github.com/mholt/acmez/v2). CertMagic's code was originally a central part of Caddy even before Let's Encrypt entered public beta in 2015.
In the years since then, Caddy's TLS automation techniques have been widely adopted, tried and tested in production, and served millions of sites and secured trillions of connections.
diff --git a/vendor/github.com/caddyserver/certmagic/account.go b/vendor/github.com/caddyserver/certmagic/account.go
index f3cb755a..f3b8d44d 100644
--- a/vendor/github.com/caddyserver/certmagic/account.go
+++ b/vendor/github.com/caddyserver/certmagic/account.go
@@ -32,7 +32,7 @@ import (
"strings"
"sync"
- "github.com/mholt/acmez/acme"
+ "github.com/mholt/acmez/v2/acme"
)
// getAccount either loads or creates a new account, depending on if
@@ -88,11 +88,18 @@ func (*ACMEIssuer) newAccount(email string) (acme.Account, error) {
// If it does not exist in storage, it will be retrieved from the ACME server and added to storage.
// The account must already exist; it does not create a new account.
func (am *ACMEIssuer) GetAccount(ctx context.Context, privateKeyPEM []byte) (acme.Account, error) {
- account, err := am.loadAccountByKey(ctx, privateKeyPEM)
- if errors.Is(err, fs.ErrNotExist) {
- account, err = am.lookUpAccount(ctx, privateKeyPEM)
+ email := am.getEmail()
+ if email == "" {
+ if account, err := am.loadAccountByKey(ctx, privateKeyPEM); err == nil {
+ return account, nil
+ }
+ } else {
+ keyBytes, err := am.config.Storage.Load(ctx, am.storageKeyUserPrivateKey(am.CA, email))
+ if err == nil && bytes.Equal(bytes.TrimSpace(keyBytes), bytes.TrimSpace(privateKeyPEM)) {
+ return am.loadAccount(ctx, am.CA, email)
+ }
}
- return account, err
+ return am.lookUpAccount(ctx, privateKeyPEM)
}
// loadAccountByKey loads the account with the given private key from storage, if it exists.
@@ -107,9 +114,14 @@ func (am *ACMEIssuer) loadAccountByKey(ctx context.Context, privateKeyPEM []byte
email := path.Base(accountFolderKey)
keyBytes, err := am.config.Storage.Load(ctx, am.storageKeyUserPrivateKey(am.CA, email))
if err != nil {
- return acme.Account{}, err
+ // Try the next account: This one is missing its private key, if it turns out to be the one we're looking
+ // for we will try to save it again after confirming with the ACME server.
+ continue
}
if bytes.Equal(bytes.TrimSpace(keyBytes), bytes.TrimSpace(privateKeyPEM)) {
+ // Found the account with the correct private key, try loading it. If this fails we we will follow
+ // the same procedure as if the private key was not found and confirm with the ACME server before saving
+ // it again.
return am.loadAccount(ctx, am.CA, email)
}
}
@@ -171,6 +183,16 @@ func (am *ACMEIssuer) saveAccount(ctx context.Context, ca string, account acme.A
return storeTx(ctx, am.config.Storage, all)
}
+// deleteAccountLocally deletes the registration info and private key of the account
+// for the given CA from storage.
+func (am *ACMEIssuer) deleteAccountLocally(ctx context.Context, ca string, account acme.Account) error {
+ primaryContact := getPrimaryContact(account)
+ if err := am.config.Storage.Delete(ctx, am.storageKeyUserReg(ca, primaryContact)); err != nil {
+ return err
+ }
+ return am.config.Storage.Delete(ctx, am.storageKeyUserPrivateKey(ca, primaryContact))
+}
+
// setEmail does everything it can to obtain an email address
// from the user within the scope of memory and storage to use
// for ACME TLS. If it cannot get an email address, it does nothing
diff --git a/vendor/github.com/caddyserver/certmagic/acmeclient.go b/vendor/github.com/caddyserver/certmagic/acmeclient.go
index e9569afd..8d7888f2 100644
--- a/vendor/github.com/caddyserver/certmagic/acmeclient.go
+++ b/vendor/github.com/caddyserver/certmagic/acmeclient.go
@@ -18,23 +18,19 @@ import (
"context"
"crypto/x509"
"fmt"
- weakrand "math/rand"
"net"
+ "net/http"
"net/url"
"strconv"
"strings"
"sync"
"time"
- "github.com/mholt/acmez"
- "github.com/mholt/acmez/acme"
+ "github.com/mholt/acmez/v2"
+ "github.com/mholt/acmez/v2/acme"
"go.uber.org/zap"
)
-func init() {
- weakrand.Seed(time.Now().UnixNano())
-}
-
// acmeClient holds state necessary to perform ACME operations
// for certificate management with an ACME account. Call
// ACMEIssuer.newACMEClientWithAccount() to get a valid one.
@@ -141,44 +137,21 @@ func (iss *ACMEIssuer) newACMEClientWithAccount(ctx context.Context, useTestCA,
// independent of any particular ACME account. If useTestCA is true, am.TestCA
// will be used if it is set; otherwise, the primary CA will be used.
func (iss *ACMEIssuer) newACMEClient(useTestCA bool) (*acmez.Client, error) {
- // ensure defaults are filled in
- var caURL string
- if useTestCA {
- caURL = iss.TestCA
+ client, err := iss.newBasicACMEClient()
+ if err != nil {
+ return nil, err
}
- if caURL == "" {
- caURL = iss.CA
- }
- if caURL == "" {
- caURL = DefaultACME.CA
+
+ // fill in a little more beyond a basic client
+ if useTestCA && iss.TestCA != "" {
+ client.Client.Directory = iss.TestCA
}
certObtainTimeout := iss.CertObtainTimeout
if certObtainTimeout == 0 {
certObtainTimeout = DefaultACME.CertObtainTimeout
}
-
- // ensure endpoint is secure (assume HTTPS if scheme is missing)
- if !strings.Contains(caURL, "://") {
- caURL = "https://" + caURL
- }
- u, err := url.Parse(caURL)
- if err != nil {
- return nil, err
- }
- if u.Scheme != "https" && !isLoopback(u.Host) && !isInternal(u.Host) {
- return nil, fmt.Errorf("%s: insecure CA URL (HTTPS required)", caURL)
- }
-
- client := &acmez.Client{
- Client: &acme.Client{
- Directory: caURL,
- PollTimeout: certObtainTimeout,
- UserAgent: buildUAString(),
- HTTPClient: iss.httpClient,
- },
- ChallengeSolvers: make(map[string]acmez.Solver),
- }
- client.Logger = iss.Logger.Named("acme_client")
+ client.Client.PollTimeout = certObtainTimeout
+ client.ChallengeSolvers = make(map[string]acmez.Solver)
// configure challenges (most of the time, DNS challenge is
// exclusive of other ones because it is usually only used
@@ -186,38 +159,24 @@ func (iss *ACMEIssuer) newACMEClient(useTestCA bool) (*acmez.Client, error) {
if iss.DNS01Solver == nil {
// enable HTTP-01 challenge
if !iss.DisableHTTPChallenge {
- useHTTPPort := HTTPChallengePort
- if HTTPPort > 0 && HTTPPort != HTTPChallengePort {
- useHTTPPort = HTTPPort
- }
- if iss.AltHTTPPort > 0 {
- useHTTPPort = iss.AltHTTPPort
- }
client.ChallengeSolvers[acme.ChallengeTypeHTTP01] = distributedSolver{
storage: iss.config.Storage,
storageKeyIssuerPrefix: iss.storageKeyCAPrefix(client.Directory),
solver: &httpSolver{
- acmeIssuer: iss,
- address: net.JoinHostPort(iss.ListenHost, strconv.Itoa(useHTTPPort)),
+ handler: iss.HTTPChallengeHandler(http.NewServeMux()),
+ address: net.JoinHostPort(iss.ListenHost, strconv.Itoa(iss.getHTTPPort())),
},
}
}
// enable TLS-ALPN-01 challenge
if !iss.DisableTLSALPNChallenge {
- useTLSALPNPort := TLSALPNChallengePort
- if HTTPSPort > 0 && HTTPSPort != TLSALPNChallengePort {
- useTLSALPNPort = HTTPSPort
- }
- if iss.AltTLSALPNPort > 0 {
- useTLSALPNPort = iss.AltTLSALPNPort
- }
client.ChallengeSolvers[acme.ChallengeTypeTLSALPN01] = distributedSolver{
storage: iss.config.Storage,
storageKeyIssuerPrefix: iss.storageKeyCAPrefix(client.Directory),
solver: &tlsALPNSolver{
config: iss.config,
- address: net.JoinHostPort(iss.ListenHost, strconv.Itoa(useTLSALPNPort)),
+ address: net.JoinHostPort(iss.ListenHost, strconv.Itoa(iss.getTLSALPNPort())),
},
}
}
@@ -248,6 +207,64 @@ func (iss *ACMEIssuer) newACMEClient(useTestCA bool) (*acmez.Client, error) {
return client, nil
}
+// newBasicACMEClient sets up a basically-functional ACME client that is not capable
+// of solving challenges but can provide basic interactions with the server.
+func (iss *ACMEIssuer) newBasicACMEClient() (*acmez.Client, error) {
+ caURL := iss.CA
+ if caURL == "" {
+ caURL = DefaultACME.CA
+ }
+ // ensure endpoint is secure (assume HTTPS if scheme is missing)
+ if !strings.Contains(caURL, "://") {
+ caURL = "https://" + caURL
+ }
+ u, err := url.Parse(caURL)
+ if err != nil {
+ return nil, err
+ }
+ if u.Scheme != "https" && !SubjectIsInternal(u.Host) {
+ return nil, fmt.Errorf("%s: insecure CA URL (HTTPS required for non-internal CA)", caURL)
+ }
+ return &acmez.Client{
+ Client: &acme.Client{
+ Directory: caURL,
+ UserAgent: buildUAString(),
+ HTTPClient: iss.httpClient,
+ Logger: iss.Logger.Named("acme_client"),
+ },
+ }, nil
+}
+
+func (iss *ACMEIssuer) getRenewalInfo(ctx context.Context, cert Certificate) (acme.RenewalInfo, error) {
+ acmeClient, err := iss.newBasicACMEClient()
+ if err != nil {
+ return acme.RenewalInfo{}, err
+ }
+ return acmeClient.GetRenewalInfo(ctx, cert.Certificate.Leaf)
+}
+
+func (iss *ACMEIssuer) getHTTPPort() int {
+ useHTTPPort := HTTPChallengePort
+ if HTTPPort > 0 && HTTPPort != HTTPChallengePort {
+ useHTTPPort = HTTPPort
+ }
+ if iss.AltHTTPPort > 0 {
+ useHTTPPort = iss.AltHTTPPort
+ }
+ return useHTTPPort
+}
+
+func (iss *ACMEIssuer) getTLSALPNPort() int {
+ useTLSALPNPort := TLSALPNChallengePort
+ if HTTPSPort > 0 && HTTPSPort != TLSALPNChallengePort {
+ useTLSALPNPort = HTTPSPort
+ }
+ if iss.AltTLSALPNPort > 0 {
+ useTLSALPNPort = iss.AltTLSALPNPort
+ }
+ return useTLSALPNPort
+}
+
func (c *acmeClient) throttle(ctx context.Context, names []string) error {
email := c.iss.getEmail()
diff --git a/vendor/github.com/caddyserver/certmagic/acmeissuer.go b/vendor/github.com/caddyserver/certmagic/acmeissuer.go
index 580a7721..87fa5ff5 100644
--- a/vendor/github.com/caddyserver/certmagic/acmeissuer.go
+++ b/vendor/github.com/caddyserver/certmagic/acmeissuer.go
@@ -1,3 +1,17 @@
+// Copyright 2015 Matthew Holt
+//
+// 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 certmagic
import (
@@ -14,8 +28,8 @@ import (
"sync"
"time"
- "github.com/mholt/acmez"
- "github.com/mholt/acmez/acme"
+ "github.com/mholt/acmez/v2"
+ "github.com/mholt/acmez/v2/acme"
"go.uber.org/zap"
)
@@ -55,6 +69,13 @@ type ACMEIssuer struct {
// with this ACME account
ExternalAccount *acme.EAB
+ // Optionally specify the validity period of
+ // the certificate(s) here as offsets from the
+ // approximate time of certificate issuance,
+ // but note that not all CAs support this
+ // (EXPERIMENTAL: Subject to change)
+ NotBefore, NotAfter time.Duration
+
// Disable all HTTP challenges
DisableHTTPChallenge bool
@@ -169,6 +190,12 @@ func NewACMEIssuer(cfg *Config, template ACMEIssuer) *ACMEIssuer {
if template.ExternalAccount == nil {
template.ExternalAccount = DefaultACME.ExternalAccount
}
+ if template.NotBefore == 0 {
+ template.NotBefore = DefaultACME.NotBefore
+ }
+ if template.NotAfter == 0 {
+ template.NotAfter = DefaultACME.NotAfter
+ }
if !template.DisableHTTPChallenge {
template.DisableHTTPChallenge = DefaultACME.DisableHTTPChallenge
}
@@ -296,14 +323,32 @@ func (iss *ACMEIssuer) isAgreed() bool {
// PreCheck performs a few simple checks before obtaining or
// renewing a certificate with ACME, and returns whether this
-// batch is eligible for certificates if using Let's Encrypt.
-// It also ensures that an email address is available.
+// batch is eligible for certificates. It also ensures that an
+// email address is available if possible.
+//
+// IP certificates via ACME are defined in RFC 8738.
func (am *ACMEIssuer) PreCheck(ctx context.Context, names []string, interactive bool) error {
- publicCA := strings.Contains(am.CA, "api.letsencrypt.org") || strings.Contains(am.CA, "acme.zerossl.com") || strings.Contains(am.CA, "api.pki.goog")
+ publicCAsAndIPCerts := map[string]bool{ // map of public CAs to whether they support IP certificates (last updated: Q1 2024)
+ "api.letsencrypt.org": false, // https://community.letsencrypt.org/t/certificate-for-static-ip/84/2?u=mholt
+ "acme.zerossl.com": false, // only supported via their API, not ACME endpoint
+ "api.pki.goog": true, // https://pki.goog/faq/#faq-IPCerts
+ "api.buypass.com": false, // https://community.buypass.com/t/h7hm76w/buypass-support-for-rfc-8738
+ "acme.ssl.com": false,
+ }
+ var publicCA, ipCertAllowed bool
+ for caSubstr, ipCert := range publicCAsAndIPCerts {
+ if strings.Contains(am.CA, caSubstr) {
+ publicCA, ipCertAllowed = true, ipCert
+ break
+ }
+ }
if publicCA {
for _, name := range names {
if !SubjectQualifiesForPublicCert(name) {
- return fmt.Errorf("subject does not qualify for a public certificate: %s", name)
+ return fmt.Errorf("subject '%s' does not qualify for a public certificate", name)
+ }
+ if !ipCertAllowed && SubjectIsIP(name) {
+ return fmt.Errorf("subject '%s' cannot have public IP certificate from %s (if CA's policy has changed, please notify the developers in an issue)", name, am.CA)
}
}
}
@@ -317,12 +362,13 @@ func (am *ACMEIssuer) Issue(ctx context.Context, csr *x509.CertificateRequest) (
panic("missing config pointer (must use NewACMEIssuer)")
}
- var isRetry bool
- if attempts, ok := ctx.Value(AttemptsCtxKey).(*int); ok {
- isRetry = *attempts > 0
+ var attempts int
+ if attemptsPtr, ok := ctx.Value(AttemptsCtxKey).(*int); ok {
+ attempts = *attemptsPtr
}
+ isRetry := attempts > 0
- cert, usedTestCA, err := am.doIssue(ctx, csr, isRetry)
+ cert, usedTestCA, err := am.doIssue(ctx, csr, attempts)
if err != nil {
return nil, err
}
@@ -350,7 +396,7 @@ func (am *ACMEIssuer) Issue(ctx context.Context, csr *x509.CertificateRequest) (
// other endpoint. This is more likely to happen if a user is testing with
// the staging CA as the main CA, then changes their configuration once they
// think they are ready for the production endpoint.
- cert, _, err = am.doIssue(ctx, csr, false)
+ cert, _, err = am.doIssue(ctx, csr, 0)
if err != nil {
// succeeded with test CA but failed just now with the production CA;
// either we are observing differing internal states of each CA that will
@@ -378,7 +424,8 @@ func (am *ACMEIssuer) Issue(ctx context.Context, csr *x509.CertificateRequest) (
return cert, err
}
-func (am *ACMEIssuer) doIssue(ctx context.Context, csr *x509.CertificateRequest, useTestCA bool) (*IssuedCertificate, bool, error) {
+func (am *ACMEIssuer) doIssue(ctx context.Context, csr *x509.CertificateRequest, attempts int) (*IssuedCertificate, bool, error) {
+ useTestCA := attempts > 0
client, err := am.newACMEClientWithAccount(ctx, useTestCA, false)
if err != nil {
return nil, false, err
@@ -393,12 +440,72 @@ func (am *ACMEIssuer) doIssue(ctx context.Context, csr *x509.CertificateRequest,
}
}
- certChains, err := client.acmeClient.ObtainCertificateUsingCSR(ctx, client.account, csr)
+ params, err := acmez.OrderParametersFromCSR(client.account, csr)
if err != nil {
- return nil, usingTestCA, fmt.Errorf("%v %w (ca=%s)", nameSet, err, client.acmeClient.Directory)
+ return nil, false, fmt.Errorf("generating order parameters from CSR: %v", err)
}
- if len(certChains) == 0 {
- return nil, usingTestCA, fmt.Errorf("no certificate chains")
+ if am.NotBefore != 0 {
+ params.NotBefore = time.Now().Add(am.NotBefore)
+ }
+ if am.NotAfter != 0 {
+ params.NotAfter = time.Now().Add(am.NotAfter)
+ }
+
+ // Notify the ACME server we are replacing a certificate (if the caller says we are),
+ // only if the following conditions are met:
+ // - The caller has set a Replaces value in the context, indicating this is a renewal.
+ // - Not using test CA. This should be obvious, but a test CA should be in a separate
+ // environment from production, and thus not have knowledge of the cert being replaced.
+ // - Not a certain attempt number. We skip setting Replaces once early on in the retries
+ // in case the reason the order is failing is only because there is a state inconsistency
+ // between client and server or some sort of bookkeeping error with regards to the certID
+ // and the server is rejecting the ARI certID. In any case, an invalid certID may cause
+ // orders to fail. So try once without setting it.
+ if !usingTestCA && attempts != 2 {
+ if replacing, ok := ctx.Value(ctxKeyARIReplaces).(*x509.Certificate); ok {
+ params.Replaces = replacing
+ }
+ }
+
+ // do this in a loop because there's an error case that may necessitate a retry, but not more than once
+ var certChains []acme.Certificate
+ for i := 0; i < 2; i++ {
+ am.Logger.Info("using ACME account",
+ zap.String("account_id", params.Account.Location),
+ zap.Strings("account_contact", params.Account.Contact))
+
+ certChains, err = client.acmeClient.ObtainCertificate(ctx, params)
+ if err != nil {
+ var prob acme.Problem
+ if errors.As(err, &prob) && prob.Type == acme.ProblemTypeAccountDoesNotExist {
+ am.Logger.Warn("ACME account does not exist on server; attempting to recreate",
+ zap.String("account_id", client.account.Location),
+ zap.Strings("account_contact", client.account.Contact),
+ zap.String("key_location", am.storageKeyUserPrivateKey(client.acmeClient.Directory, am.getEmail())),
+ zap.Object("problem", prob))
+
+ // the account we have no longer exists on the CA, so we need to create a new one;
+ // we could use the same key pair, but this is a good opportunity to rotate keys
+ // (see https://caddy.community/t/acme-account-is-not-regenerated-when-acme-server-gets-reinstalled/22627)
+ // (basically this happens if the CA gets reset or reinstalled; usually just internal PKI)
+ err := am.deleteAccountLocally(ctx, client.iss.CA, client.account)
+ if err != nil {
+ return nil, usingTestCA, fmt.Errorf("%v ACME account no longer exists on CA, but resetting our local copy of the account info failed: %v", nameSet, err)
+ }
+
+ // recreate account and try again
+ client, err = am.newACMEClientWithAccount(ctx, useTestCA, false)
+ if err != nil {
+ return nil, false, err
+ }
+ continue
+ }
+ return nil, usingTestCA, fmt.Errorf("%v %w (ca=%s)", nameSet, err, client.acmeClient.Directory)
+ }
+ if len(certChains) == 0 {
+ return nil, usingTestCA, fmt.Errorf("no certificate chains")
+ }
+ break
}
preferredChain := am.selectPreferredChain(certChains)
@@ -408,6 +515,8 @@ func (am *ACMEIssuer) doIssue(ctx context.Context, csr *x509.CertificateRequest,
Metadata: preferredChain,
}
+ am.Logger.Debug("selected certificate chain", zap.String("url", preferredChain.URL))
+
return ic, usingTestCA, nil
}
@@ -523,16 +632,27 @@ var DefaultACME = ACMEIssuer{
HTTPProxy: http.ProxyFromEnvironment,
}
-// Some well-known CA endpoints available to use.
+// Some well-known CA endpoints available to use. See
+// the documentation for each service; some may require
+// External Account Binding (EAB) and possibly payment.
+// COMPATIBILITY NOTICE: These constants refer to external
+// resources and are thus subject to change or removal
+// without a major version bump.
const (
- LetsEncryptStagingCA = "https://acme-staging-v02.api.letsencrypt.org/directory"
- LetsEncryptProductionCA = "https://acme-v02.api.letsencrypt.org/directory"
- ZeroSSLProductionCA = "https://acme.zerossl.com/v2/DV90"
+ LetsEncryptStagingCA = "https://acme-staging-v02.api.letsencrypt.org/directory" // https://letsencrypt.org/docs/staging-environment/
+ LetsEncryptProductionCA = "https://acme-v02.api.letsencrypt.org/directory" // https://letsencrypt.org/getting-started/
+ ZeroSSLProductionCA = "https://acme.zerossl.com/v2/DV90" // https://zerossl.com/documentation/acme/
+ GoogleTrustStagingCA = "https://dv.acme-v02.test-api.pki.goog/directory" // https://cloud.google.com/certificate-manager/docs/public-ca-tutorial
+ GoogleTrustProductionCA = "https://dv.acme-v02.api.pki.goog/directory" // https://cloud.google.com/certificate-manager/docs/public-ca-tutorial
)
// prefixACME is the storage key prefix used for ACME-specific assets.
const prefixACME = "acme"
+type ctxKey string
+
+const ctxKeyARIReplaces = ctxKey("ari_replaces")
+
// Interface guards
var (
_ PreChecker = (*ACMEIssuer)(nil)
diff --git a/vendor/github.com/caddyserver/certmagic/cache.go b/vendor/github.com/caddyserver/certmagic/cache.go
index 152fe18a..73d698f3 100644
--- a/vendor/github.com/caddyserver/certmagic/cache.go
+++ b/vendor/github.com/caddyserver/certmagic/cache.go
@@ -16,7 +16,7 @@ package certmagic
import (
"fmt"
- weakrand "math/rand" // seeded elsewhere
+ weakrand "math/rand"
"strings"
"sync"
"time"
@@ -394,17 +394,26 @@ func (certCache *Cache) AllMatchingCertificates(name string) []Certificate {
return certs
}
+// SubjectIssuer pairs a subject name with an issuer ID/key.
+type SubjectIssuer struct {
+ Subject, IssuerKey string
+}
+
// RemoveManaged removes managed certificates for the given subjects from the cache.
-// This effectively stops maintenance of those certificates.
-func (certCache *Cache) RemoveManaged(subjects []string) {
+// This effectively stops maintenance of those certificates. If an IssuerKey is
+// specified alongside the subject, only certificates for that subject from the
+// specified issuer will be removed.
+func (certCache *Cache) RemoveManaged(subjects []SubjectIssuer) {
deleteQueue := make([]string, 0, len(subjects))
- for _, subject := range subjects {
- certs := certCache.getAllMatchingCerts(subject) // does NOT expand wildcards; exact matches only
+ for _, subj := range subjects {
+ certs := certCache.getAllMatchingCerts(subj.Subject) // does NOT expand wildcards; exact matches only
for _, cert := range certs {
if !cert.managed {
continue
}
- deleteQueue = append(deleteQueue, cert.hash)
+ if subj.IssuerKey == "" || cert.issuerKey == subj.IssuerKey {
+ deleteQueue = append(deleteQueue, cert.hash)
+ }
}
}
certCache.Remove(deleteQueue)
diff --git a/vendor/github.com/caddyserver/certmagic/certificates.go b/vendor/github.com/caddyserver/certmagic/certificates.go
index dbee2aaf..a5147a2d 100644
--- a/vendor/github.com/caddyserver/certmagic/certificates.go
+++ b/vendor/github.com/caddyserver/certmagic/certificates.go
@@ -18,12 +18,15 @@ import (
"context"
"crypto/tls"
"crypto/x509"
+ "encoding/json"
"fmt"
+ "math/rand"
"net"
"os"
"strings"
"time"
+ "github.com/mholt/acmez/v2/acme"
"go.uber.org/zap"
"golang.org/x/crypto/ocsp"
)
@@ -56,6 +59,9 @@ type Certificate struct {
// The unique string identifying the issuer of this certificate.
issuerKey string
+
+ // ACME Renewal Information, if available
+ ari acme.RenewalInfo
}
// Empty returns true if the certificate struct is not filled out; at
@@ -67,10 +73,106 @@ func (cert Certificate) Empty() bool {
// Hash returns a checksum of the certificate chain's DER-encoded bytes.
func (cert Certificate) Hash() string { return cert.hash }
-// NeedsRenewal returns true if the certificate is
-// expiring soon (according to cfg) or has expired.
+// NeedsRenewal returns true if the certificate is expiring
+// soon (according to ARI and/or cfg) or has expired.
func (cert Certificate) NeedsRenewal(cfg *Config) bool {
- return currentlyInRenewalWindow(cert.Leaf.NotBefore, expiresAt(cert.Leaf), cfg.RenewalWindowRatio)
+ return cfg.certNeedsRenewal(cert.Leaf, cert.ari, true)
+}
+
+// certNeedsRenewal consults ACME Renewal Info (ARI) and certificate expiration to determine
+// whether the leaf certificate needs to be renewed yet. If true is returned, the certificate
+// should be renewed as soon as possible. The reasoning for a true return value is logged
+// unless emitLogs is false; this can be useful to suppress noisy logs in the case where you
+// first call this to determine if a cert in memory needs renewal, and then right after you
+// call it again to see if the cert in storage still needs renewal -- you probably don't want
+// to log the second time for checking the cert in storage which is mainly for synchronization.
+func (cfg *Config) certNeedsRenewal(leaf *x509.Certificate, ari acme.RenewalInfo, emitLogs bool) bool {
+ expiration := expiresAt(leaf)
+
+ var logger *zap.Logger
+ if emitLogs {
+ logger = cfg.Logger.With(
+ zap.Strings("subjects", leaf.DNSNames),
+ zap.Time("expiration", expiration),
+ zap.String("ari_cert_id", ari.UniqueIdentifier),
+ zap.Timep("next_ari_update", ari.RetryAfter),
+ zap.Duration("renew_check_interval", cfg.certCache.options.RenewCheckInterval),
+ zap.Time("window_start", ari.SuggestedWindow.Start),
+ zap.Time("window_end", ari.SuggestedWindow.End))
+ } else {
+ logger = zap.NewNop()
+ }
+
+ // first check ARI: if it says it's time to renew, it's time to renew
+ // (notice that we don't strictly require an ARI window to also exist; we presume
+ // that if a time has been selected, a window does or did exist, even if it didn't
+ // get stored/encoded for some reason - but also: this allows administrators to
+ // manually or explicitly schedule a renewal time indepedently of ARI which could
+ // be useful)
+ selectedTime := ari.SelectedTime
+
+ // if, for some reason a random time in the window hasn't been selected yet, but an ARI
+ // window does exist, we can always improvise one... even if this is called repeatedly,
+ // a random time is a random time, whether you generate it once or more :D
+ // (code borrowed from our acme package)
+ if selectedTime.IsZero() &&
+ (!ari.SuggestedWindow.Start.IsZero() && !ari.SuggestedWindow.End.IsZero()) {
+ start, end := ari.SuggestedWindow.Start.Unix()+1, ari.SuggestedWindow.End.Unix()
+ selectedTime = time.Unix(rand.Int63n(end-start)+start, 0).UTC()
+ logger.Warn("no renewal time had been selected with ARI; chose an ephemeral one for now",
+ zap.Time("ephemeral_selected_time", selectedTime))
+ }
+
+ // if a renewal time has been selected, start with that
+ if !selectedTime.IsZero() {
+ // ARI spec recommends an algorithm that renews after the randomly-selected
+ // time OR just before it if the next waking time would be after it; this
+ // cutoff can actually be before the start of the renewal window, but the spec
+ // author says that's OK: https://github.com/aarongable/draft-acme-ari/issues/71
+ cutoff := ari.SelectedTime.Add(-cfg.certCache.options.RenewCheckInterval)
+ if time.Now().After(cutoff) {
+ logger.Info("certificate needs renewal based on ARI window",
+ zap.Time("selected_time", selectedTime),
+ zap.Time("renewal_cutoff", cutoff))
+ return true
+ }
+
+ // according to ARI, we are not ready to renew; however, we do not rely solely on
+ // ARI calculations... what if there is a bug in our implementation, or in the
+ // server's, or the stored metadata? for redundancy, give credence to the expiration
+ // date; ignore ARI if we are past a "dangerously close" limit, to avoid any
+ // possibility of a bug in ARI compromising a site's uptime: we should always always
+ // always give heed to actual validity period
+ if currentlyInRenewalWindow(leaf.NotBefore, expiration, 1.0/20.0) {
+ logger.Warn("certificate is in emergency renewal window; superceding ARI",
+ zap.Duration("remaining", time.Until(expiration)),
+ zap.Time("renewal_cutoff", cutoff))
+ return true
+ }
+
+ }
+
+ // the normal check, in the absence of ARI, is to determine if we're near enough (or past)
+ // the expiration date based on the configured remaining:lifetime ratio
+ if currentlyInRenewalWindow(leaf.NotBefore, expiration, cfg.RenewalWindowRatio) {
+ logger.Info("certificate is in configured renewal window based on expiration date",
+ zap.Duration("remaining", time.Until(expiration)))
+ return true
+ }
+
+ // finally, if the certificate is expiring imminently, always attempt a renewal;
+ // we check both a (very low) lifetime ratio and also a strict difference between
+ // the time until expiration and the interval at which we run the standard maintenance
+ // routine to check for renewals, to accommodate both exceptionally long and short
+ // cert lifetimes
+ if currentlyInRenewalWindow(leaf.NotBefore, expiration, 1.0/50.0) ||
+ time.Until(expiration) < cfg.certCache.options.RenewCheckInterval*5 {
+ logger.Warn("certificate is in emergency renewal window; expiration imminent",
+ zap.Duration("remaining", time.Until(expiration)))
+ return true
+ }
+
+ return false
}
// Expired returns true if the certificate has expired.
@@ -85,10 +187,12 @@ func (cert Certificate) Expired() bool {
return time.Now().After(expiresAt(cert.Leaf))
}
-// currentlyInRenewalWindow returns true if the current time is
-// within the renewal window, according to the given start/end
+// currentlyInRenewalWindow returns true if the current time is within
+// (or after) the renewal window, according to the given start/end
// dates and the ratio of the renewal window. If true is returned,
-// the certificate being considered is due for renewal.
+// the certificate being considered is due for renewal. The ratio
+// is remaining:total time, i.e. 1/3 = 1/3 of lifetime remaining,
+// or 9/10 = 9/10 of time lifetime remaining.
func currentlyInRenewalWindow(notBefore, notAfter time.Time, renewalWindowRatio float64) bool {
if notAfter.IsZero() {
return false
@@ -130,6 +234,7 @@ func expiresAt(cert *x509.Certificate) time.Time {
//
// This method is safe for concurrent use.
func (cfg *Config) CacheManagedCertificate(ctx context.Context, domain string) (Certificate, error) {
+ domain = cfg.transformSubject(ctx, nil, domain)
cert, err := cfg.loadManagedCertificate(ctx, domain)
if err != nil {
return cert, err
@@ -153,16 +258,44 @@ func (cfg *Config) loadManagedCertificate(ctx context.Context, domain string) (C
}
cert.managed = true
cert.issuerKey = certRes.issuerKey
+ if ari, err := certRes.getARI(); err == nil && ari != nil {
+ cert.ari = *ari
+ }
return cert, nil
}
+// getARI unpacks ACME Renewal Information from the issuer data, if available.
+// It is only an error if there is invalid JSON.
+func (certRes CertificateResource) getARI() (*acme.RenewalInfo, error) {
+ acmeData, err := certRes.getACMEData()
+ if err != nil {
+ return nil, err
+ }
+ return acmeData.RenewalInfo, nil
+}
+
+// getACMEData returns the ACME certificate metadata from the IssuerData, but
+// note that a non-ACME-issued certificate may return an empty value and nil
+// since the JSON may still decode successfully but just not match any or all
+// of the fields. Remember that the IssuerKey is used to store and access the
+// cert files in the first place (it is part of the path) so in theory if you
+// load a CertificateResource from an ACME issuer it should work as expected.
+func (certRes CertificateResource) getACMEData() (acme.Certificate, error) {
+ if len(certRes.IssuerData) == 0 {
+ return acme.Certificate{}, nil
+ }
+ var acmeCert acme.Certificate
+ err := json.Unmarshal(certRes.IssuerData, &acmeCert)
+ return acmeCert, err
+}
+
// CacheUnmanagedCertificatePEMFile loads a certificate for host using certFile
// and keyFile, which must be in PEM format. It stores the certificate in
// the in-memory cache and returns the hash, useful for removing from the cache.
//
// This method is safe for concurrent use.
func (cfg *Config) CacheUnmanagedCertificatePEMFile(ctx context.Context, certFile, keyFile string, tags []string) (string, error) {
- cert, err := cfg.makeCertificateFromDiskWithOCSP(ctx, cfg.Storage, certFile, keyFile)
+ cert, err := cfg.makeCertificateFromDiskWithOCSP(ctx, certFile, keyFile)
if err != nil {
return "", err
}
@@ -185,6 +318,15 @@ func (cfg *Config) CacheUnmanagedTLSCertificate(ctx context.Context, tlsCert tls
if err != nil {
return "", err
}
+ if time.Now().After(cert.Leaf.NotAfter) {
+ cfg.Logger.Warn("unmanaged certificate has expired",
+ zap.Time("not_after", cert.Leaf.NotAfter),
+ zap.Strings("sans", cert.Names))
+ } else if time.Until(cert.Leaf.NotAfter) < 24*time.Hour {
+ cfg.Logger.Warn("unmanaged certificate expires within 1 day",
+ zap.Time("not_after", cert.Leaf.NotAfter),
+ zap.Strings("sans", cert.Names))
+ }
err = stapleOCSP(ctx, cfg.OCSP, cfg.Storage, &cert, nil)
if err != nil {
cfg.Logger.Warn("stapling OCSP", zap.Error(err))
@@ -215,7 +357,7 @@ func (cfg *Config) CacheUnmanagedCertificatePEMBytes(ctx context.Context, certBy
// certificate and key files. It fills out all the fields in
// the certificate except for the Managed and OnDemand flags.
// (It is up to the caller to set those.) It staples OCSP.
-func (cfg Config) makeCertificateFromDiskWithOCSP(ctx context.Context, storage Storage, certFile, keyFile string) (Certificate, error) {
+func (cfg Config) makeCertificateFromDiskWithOCSP(ctx context.Context, certFile, keyFile string) (Certificate, error) {
certPEMBlock, err := os.ReadFile(certFile)
if err != nil {
return Certificate{}, err
@@ -319,21 +461,22 @@ func fillCertFromLeaf(cert *Certificate, tlsCert tls.Certificate) error {
return nil
}
-// managedCertInStorageExpiresSoon returns true if cert (being a
-// managed certificate) is expiring within RenewDurationBefore.
-// It returns false if there was an error checking the expiration
-// of the certificate as found in storage, or if the certificate
-// in storage is NOT expiring soon. A certificate that is expiring
+// managedCertInStorageNeedsRenewal returns true if cert (being a
+// managed certificate) is expiring soon (according to cfg) or if
+// ACME Renewal Information (ARI) is available and says that it is
+// time to renew (it uses existing ARI; it does not update it).
+// It returns false if there was an error, the cert is not expiring
+// soon, and ARI window is still future. A certificate that is expiring
// soon in our cache but is not expiring soon in storage probably
// means that another instance renewed the certificate in the
// meantime, and it would be a good idea to simply load the cert
// into our cache rather than repeating the renewal process again.
-func (cfg *Config) managedCertInStorageExpiresSoon(ctx context.Context, cert Certificate) (bool, error) {
+func (cfg *Config) managedCertInStorageNeedsRenewal(ctx context.Context, cert Certificate) (bool, error) {
certRes, err := cfg.loadCertResourceAnyIssuer(ctx, cert.Names[0])
if err != nil {
return false, err
}
- _, needsRenew := cfg.managedCertNeedsRenewal(certRes)
+ _, _, needsRenew := cfg.managedCertNeedsRenewal(certRes, false)
return needsRenew, nil
}
@@ -376,8 +519,8 @@ func SubjectQualifiesForCert(subj string) bool {
// SubjectQualifiesForPublicCert returns true if the subject
// name appears eligible for automagic TLS with a public
-// CA such as Let's Encrypt. For example: localhost and IP
-// addresses are not eligible because we cannot obtain certs
+// CA such as Let's Encrypt. For example: internal IP addresses
+// and localhost are not eligible because we cannot obtain certs
// for those names with a public CA. Wildcard names are
// allowed, as long as they conform to CABF requirements (only
// one wildcard label, and it must be the left-most label).
@@ -385,13 +528,9 @@ func SubjectQualifiesForPublicCert(subj string) bool {
// must at least qualify for a certificate
return SubjectQualifiesForCert(subj) &&
- // localhost, .localhost TLD, and .local TLD are ineligible
+ // loopback hosts and internal IPs are ineligible
!SubjectIsInternal(subj) &&
- // cannot be an IP address (as of yet), see
- // https://community.letsencrypt.org/t/certificate-for-static-ip/84/2?u=mholt
- !SubjectIsIP(subj) &&
-
// only one wildcard label allowed, and it must be left-most, with 3+ labels
(!strings.Contains(subj, "*") ||
(strings.Count(subj, "*") == 1 &&
@@ -406,12 +545,55 @@ func SubjectIsIP(subj string) bool {
}
// SubjectIsInternal returns true if subj is an internal-facing
-// hostname or address.
+// hostname or address, including localhost/loopback hosts.
+// Ports are ignored, if present.
func SubjectIsInternal(subj string) bool {
+ subj = strings.ToLower(strings.TrimSuffix(hostOnly(subj), "."))
return subj == "localhost" ||
strings.HasSuffix(subj, ".localhost") ||
strings.HasSuffix(subj, ".local") ||
- strings.HasSuffix(subj, ".home.arpa")
+ strings.HasSuffix(subj, ".home.arpa") ||
+ isInternalIP(subj)
+}
+
+// isInternalIP returns true if the IP of addr
+// belongs to a private network IP range. addr
+// must only be an IP or an IP:port combination.
+func isInternalIP(addr string) bool {
+ privateNetworks := []string{
+ "127.0.0.0/8", // IPv4 loopback
+ "0.0.0.0/16",
+ "10.0.0.0/8", // RFC1918
+ "172.16.0.0/12", // RFC1918
+ "192.168.0.0/16", // RFC1918
+ "169.254.0.0/16", // RFC3927 link-local
+ "::1/7", // IPv6 loopback
+ "fe80::/10", // IPv6 link-local
+ "fc00::/7", // IPv6 unique local addr
+ }
+ host := hostOnly(addr)
+ ip := net.ParseIP(host)
+ if ip == nil {
+ return false
+ }
+ for _, privateNetwork := range privateNetworks {
+ _, ipnet, _ := net.ParseCIDR(privateNetwork)
+ if ipnet.Contains(ip) {
+ return true
+ }
+ }
+ return false
+}
+
+// hostOnly returns only the host portion of hostport.
+// If there is no port or if there is an error splitting
+// the port off, the whole input string is returned.
+func hostOnly(hostport string) string {
+ host, _, err := net.SplitHostPort(hostport)
+ if err != nil {
+ return hostport // OK; probably had no port to begin with
+ }
+ return host
}
// MatchWildcard returns true if subject (a candidate DNS name)
diff --git a/vendor/github.com/caddyserver/certmagic/certmagic.go b/vendor/github.com/caddyserver/certmagic/certmagic.go
index 860f5e76..6b7be634 100644
--- a/vendor/github.com/caddyserver/certmagic/certmagic.go
+++ b/vendor/github.com/caddyserver/certmagic/certmagic.go
@@ -39,6 +39,7 @@ import (
"crypto"
"crypto/tls"
"crypto/x509"
+ "encoding/json"
"fmt"
"log"
"net"
@@ -302,52 +303,6 @@ type OnDemandConfig struct {
hostAllowlist map[string]struct{}
}
-// isLoopback returns true if the hostname of addr looks
-// explicitly like a common local hostname. addr must only
-// be a host or a host:port combination.
-func isLoopback(addr string) bool {
- host := hostOnly(addr)
- return host == "localhost" ||
- strings.Trim(host, "[]") == "::1" ||
- strings.HasPrefix(host, "127.")
-}
-
-// isInternal returns true if the IP of addr
-// belongs to a private network IP range. addr
-// must only be an IP or an IP:port combination.
-// Loopback addresses are considered false.
-func isInternal(addr string) bool {
- privateNetworks := []string{
- "10.0.0.0/8",
- "172.16.0.0/12",
- "192.168.0.0/16",
- "fc00::/7",
- }
- host := hostOnly(addr)
- ip := net.ParseIP(host)
- if ip == nil {
- return false
- }
- for _, privateNetwork := range privateNetworks {
- _, ipnet, _ := net.ParseCIDR(privateNetwork)
- if ipnet.Contains(ip) {
- return true
- }
- }
- return false
-}
-
-// hostOnly returns only the host portion of hostport.
-// If there is no port or if there is an error splitting
-// the port off, the whole input string is returned.
-func hostOnly(hostport string) string {
- host, _, err := net.SplitHostPort(hostport)
- if err != nil {
- return hostport // OK; probably had no port to begin with
- }
- return host
-}
-
// PreChecker is an interface that can be optionally implemented by
// Issuers. Pre-checks are performed before each call (or batch of
// identical calls) to Issue(), giving the issuer the option to ensure
@@ -394,7 +349,12 @@ type Revoker interface {
type Manager interface {
// GetCertificate returns the certificate to use to complete the handshake.
// Since this is called during every TLS handshake, it must be very fast and not block.
- // Returning (nil, nil) is valid and is simply treated as a no-op.
+ // Returning any non-nil value indicates that this Manager manages a certificate
+ // for the described handshake. Returning (nil, nil) is valid and is simply treated as
+ // a no-op Return (nil, nil) when the Manager has no certificate for this handshake.
+ // Return an error or a certificate only if the Manager is supposed to get a certificate
+ // for this handshake. Returning (nil, nil) other Managers or Issuers to try to get
+ // a certificate for the handshake.
GetCertificate(context.Context, *tls.ClientHelloInfo) (*tls.Certificate, error)
}
@@ -429,7 +389,8 @@ type IssuedCertificate struct {
Certificate []byte
// Any extra information to serialize alongside the
- // certificate in storage.
+ // certificate in storage. It MUST be serializable
+ // as JSON in order to be preserved.
Metadata any
}
@@ -450,7 +411,7 @@ type CertificateResource struct {
// Any extra information associated with the certificate,
// usually provided by the issuer implementation.
- IssuerData any `json:"issuer_data,omitempty"`
+ IssuerData json.RawMessage `json:"issuer_data,omitempty"`
// The unique string identifying the issuer of the
// certificate; internally useful for storage access.
diff --git a/vendor/github.com/caddyserver/certmagic/config.go b/vendor/github.com/caddyserver/certmagic/config.go
index 3d80a7eb..5a9cf498 100644
--- a/vendor/github.com/caddyserver/certmagic/config.go
+++ b/vendor/github.com/caddyserver/certmagic/config.go
@@ -24,17 +24,19 @@ import (
"crypto/x509/pkix"
"encoding/asn1"
"encoding/json"
+ "encoding/pem"
"errors"
"fmt"
"io/fs"
weakrand "math/rand"
"net"
+ "net/http"
"net/url"
"strings"
"time"
- "github.com/mholt/acmez"
- "github.com/mholt/acmez/acme"
+ "github.com/mholt/acmez/v2"
+ "github.com/mholt/acmez/v2/acme"
"go.uber.org/zap"
"golang.org/x/crypto/ocsp"
"golang.org/x/net/idna"
@@ -50,6 +52,7 @@ type Config struct {
// it should be renewed; for most certificates, the
// global default is good, but for extremely short-
// lived certs, you may want to raise this to ~0.5.
+ // Ratio is remaining:total lifetime.
RenewalWindowRatio float64
// An optional event callback clients can set
@@ -135,9 +138,17 @@ type Config struct {
// storage is properly configured and has sufficient
// space, you can disable this check to reduce I/O
// if that is expensive for you.
- // EXPERIMENTAL: Option subject to change or removal.
+ // EXPERIMENTAL: Subject to change or removal.
DisableStorageCheck bool
+ // SubjectTransformer is a hook that can transform the
+ // subject (SAN) of a certificate being loaded or issued.
+ // For example, a common use case is to replace the
+ // left-most label with an asterisk (*) to become a
+ // wildcard certificate.
+ // EXPERIMENTAL: Subject to change or removal.
+ SubjectTransformer func(ctx context.Context, domain string) string
+
// Set a logger to enable logging. If not set,
// a default logger will be created.
Logger *zap.Logger
@@ -436,6 +447,15 @@ func (cfg *Config) manageOne(ctx context.Context, domainName string, async bool)
return err
}
+ // ensure ARI is updated before we check whether the cert needs renewing
+ // (we ignore the second return value because we already check if needs renewing anyway)
+ if cert.ari.NeedsRefresh() {
+ cert, _, err = cfg.updateARI(ctx, cert, cfg.Logger)
+ if err != nil {
+ cfg.Logger.Error("updating ARI upon managing", zap.Error(err))
+ }
+ }
+
// otherwise, simply renew the certificate if needed
if cert.NeedsRenewal(cfg) {
var err error
@@ -484,6 +504,10 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool
return fmt.Errorf("no issuers configured; impossible to obtain or check for existing certificate in storage")
}
+ log := cfg.Logger.Named("obtain")
+
+ name = cfg.transformSubject(ctx, log, name)
+
// if storage has all resources for this certificate, obtain is a no-op
if cfg.storageHasCertResourcesAnyIssuer(ctx, name) {
return nil
@@ -496,8 +520,6 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool
return fmt.Errorf("failed storage check: %v - storage is probably misconfigured", err)
}
- log := cfg.Logger.Named("obtain")
-
log.Info("acquiring lock", zap.String("identifier", name))
// ensure idempotency of the obtain operation for this name
@@ -561,7 +583,7 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool
}
}
- csr, err := cfg.generateCSR(privKey, []string{name})
+ csr, err := cfg.generateCSR(privKey, []string{name}, false)
if err != nil {
return err
}
@@ -583,7 +605,19 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool
}
}
- issuedCert, err = issuer.Issue(ctx, csr)
+ // TODO: ZeroSSL's API currently requires CommonName to be set, and requires it be
+ // distinct from SANs. If this was a cert it would violate the BRs, but their certs
+ // are compliant, so their CSR requirements just needlessly add friction, complexity,
+ // and inefficiency for clients. CommonName has been deprecated for 25+ years.
+ useCSR := csr
+ if issuer.IssuerKey() == zerosslIssuerKey {
+ useCSR, err = cfg.generateCSR(privKey, []string{name}, true)
+ if err != nil {
+ return err
+ }
+ }
+
+ issuedCert, err = issuer.Issue(ctx, useCSR)
if err == nil {
issuerUsed = issuer
break
@@ -615,11 +649,15 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool
issuerKey := issuerUsed.IssuerKey()
// success - immediately save the certificate resource
+ metaJSON, err := json.Marshal(issuedCert.Metadata)
+ if err != nil {
+ log.Error("unable to encode certificate metadata", zap.Error(err))
+ }
certRes := CertificateResource{
SANs: namesFromCSR(csr),
CertificatePEM: issuedCert.Certificate,
PrivateKeyPEM: privKeyPEM,
- IssuerData: issuedCert.Metadata,
+ IssuerData: metaJSON,
issuerKey: issuerUsed.IssuerKey(),
}
err = cfg.saveCertResource(ctx, issuerUsed, certRes)
@@ -627,7 +665,9 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool
return fmt.Errorf("[%s] Obtain: saving assets: %v", name, err)
}
- log.Info("certificate obtained successfully", zap.String("identifier", name))
+ log.Info("certificate obtained successfully",
+ zap.String("identifier", name),
+ zap.String("issuer", issuerUsed.IssuerKey()))
certKey := certRes.NamesKey()
@@ -639,6 +679,10 @@ func (cfg *Config) obtainCert(ctx context.Context, name string, interactive bool
"private_key_path": StorageKeys.SitePrivateKey(issuerKey, certKey),
"certificate_path": StorageKeys.SiteCert(issuerKey, certKey),
"metadata_path": StorageKeys.SiteMeta(issuerKey, certKey),
+ "csr_pem": pem.EncodeToMemory(&pem.Block{
+ Type: "CERTIFICATE REQUEST",
+ Bytes: csr.Raw,
+ }),
})
return nil
@@ -723,6 +767,10 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
return fmt.Errorf("no issuers configured; impossible to renew or check existing certificate in storage")
}
+ log := cfg.Logger.Named("renew")
+
+ name = cfg.transformSubject(ctx, log, name)
+
// ensure storage is writeable and readable
// TODO: this is not necessary every time; should only perform check once every so often for each storage, which may require some global state...
err := cfg.checkStorage(ctx)
@@ -730,8 +778,6 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
return fmt.Errorf("failed storage check: %v - storage is probably misconfigured", err)
}
- log := cfg.Logger.Named("renew")
-
log.Info("acquiring lock", zap.String("identifier", name))
// ensure idempotency of the renew operation for this name
@@ -760,7 +806,7 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
}
// check if renew is still needed - might have been renewed while waiting for lock
- timeLeft, needsRenew := cfg.managedCertNeedsRenewal(certRes)
+ timeLeft, leaf, needsRenew := cfg.managedCertNeedsRenewal(certRes, false)
if !needsRenew {
if force {
log.Info("certificate does not need to be renewed, but renewal is being forced",
@@ -807,7 +853,7 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
}
}
- csr, err := cfg.generateCSR(privateKey, []string{name})
+ csr, err := cfg.generateCSR(privateKey, []string{name}, false)
if err != nil {
return err
}
@@ -817,6 +863,18 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
var issuerUsed Issuer
var issuerKeys []string
for _, issuer := range cfg.Issuers {
+ // TODO: ZeroSSL's API currently requires CommonName to be set, and requires it be
+ // distinct from SANs. If this was a cert it would violate the BRs, but their certs
+ // are compliant, so their CSR requirements just needlessly add friction, complexity,
+ // and inefficiency for clients. CommonName has been deprecated for 25+ years.
+ useCSR := csr
+ if _, ok := issuer.(*ZeroSSLIssuer); ok {
+ useCSR, err = cfg.generateCSR(privateKey, []string{name}, true)
+ if err != nil {
+ return err
+ }
+ }
+
issuerKeys = append(issuerKeys, issuer.IssuerKey())
if prechecker, ok := issuer.(PreChecker); ok {
err = prechecker.PreCheck(ctx, []string{name}, interactive)
@@ -825,7 +883,19 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
}
}
- issuedCert, err = issuer.Issue(ctx, csr)
+ // if we're renewing with the same ACME CA as before, have the ACME
+ // client tell the server we are replacing a certificate (but doing
+ // this on the wrong CA, or when the CA doesn't recognize the certID,
+ // can fail the order)
+ if acmeData, err := certRes.getACMEData(); err == nil && acmeData.CA != "" {
+ if acmeIss, ok := issuer.(*ACMEIssuer); ok {
+ if acmeIss.CA == acmeData.CA {
+ ctx = context.WithValue(ctx, ctxKeyARIReplaces, leaf)
+ }
+ }
+ }
+
+ issuedCert, err = issuer.Issue(ctx, useCSR)
if err == nil {
issuerUsed = issuer
break
@@ -858,11 +928,15 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
issuerKey := issuerUsed.IssuerKey()
// success - immediately save the renewed certificate resource
+ metaJSON, err := json.Marshal(issuedCert.Metadata)
+ if err != nil {
+ log.Error("unable to encode certificate metadata", zap.Error(err))
+ }
newCertRes := CertificateResource{
SANs: namesFromCSR(csr),
CertificatePEM: issuedCert.Certificate,
PrivateKeyPEM: certRes.PrivateKeyPEM,
- IssuerData: issuedCert.Metadata,
+ IssuerData: metaJSON,
issuerKey: issuerKey,
}
err = cfg.saveCertResource(ctx, issuerUsed, newCertRes)
@@ -870,7 +944,9 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
return fmt.Errorf("[%s] Renew: saving assets: %v", name, err)
}
- log.Info("certificate renewed successfully", zap.String("identifier", name))
+ log.Info("certificate renewed successfully",
+ zap.String("identifier", name),
+ zap.String("issuer", issuerKey))
certKey := newCertRes.NamesKey()
@@ -883,6 +959,10 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
"private_key_path": StorageKeys.SitePrivateKey(issuerKey, certKey),
"certificate_path": StorageKeys.SiteCert(issuerKey, certKey),
"metadata_path": StorageKeys.SiteMeta(issuerKey, certKey),
+ "csr_pem": pem.EncodeToMemory(&pem.Block{
+ Type: "CERTIFICATE REQUEST",
+ Bytes: csr.Raw,
+ }),
})
return nil
@@ -897,10 +977,16 @@ func (cfg *Config) renewCert(ctx context.Context, name string, force, interactiv
return err
}
-func (cfg *Config) generateCSR(privateKey crypto.PrivateKey, sans []string) (*x509.CertificateRequest, error) {
+// generateCSR generates a CSR for the given SANs. If useCN is true, CommonName will get the first SAN (TODO: this is only a temporary hack for ZeroSSL API support).
+func (cfg *Config) generateCSR(privateKey crypto.PrivateKey, sans []string, useCN bool) (*x509.CertificateRequest, error) {
csrTemplate := new(x509.CertificateRequest)
for _, name := range sans {
+ // TODO: This is a temporary hack to support ZeroSSL API...
+ if useCN && csrTemplate.Subject.CommonName == "" && len(name) <= 64 {
+ csrTemplate.Subject.CommonName = name
+ continue
+ }
if ip := net.ParseIP(name); ip != nil {
csrTemplate.IPAddresses = append(csrTemplate.IPAddresses, ip)
} else if strings.Contains(name, "@") {
@@ -1052,6 +1138,19 @@ func (cfg *Config) getChallengeInfo(ctx context.Context, identifier string) (Cha
return Challenge{Challenge: chalInfo}, true, nil
}
+func (cfg *Config) transformSubject(ctx context.Context, logger *zap.Logger, name string) string {
+ if cfg.SubjectTransformer == nil {
+ return name
+ }
+ transformedName := cfg.SubjectTransformer(ctx, name)
+ if logger != nil && transformedName != name {
+ logger.Debug("transformed subject name",
+ zap.String("original", name),
+ zap.String("transformed", transformedName))
+ }
+ return transformedName
+}
+
// checkStorage tests the storage by writing random bytes
// to a random key, and then loading those bytes and
// comparing the loaded value. If this fails, the provided
@@ -1137,14 +1236,19 @@ func (cfg *Config) lockKey(op, domainName string) string {
// managedCertNeedsRenewal returns true if certRes is expiring soon or already expired,
// or if the process of decoding the cert and checking its expiration returned an error.
-func (cfg *Config) managedCertNeedsRenewal(certRes CertificateResource) (time.Duration, bool) {
+// If there wasn't an error, the leaf cert is also returned, so it can be reused if
+// necessary, since we are parsing the PEM bundle anyway.
+func (cfg *Config) managedCertNeedsRenewal(certRes CertificateResource, emitLogs bool) (time.Duration, *x509.Certificate, bool) {
certChain, err := parseCertsFromPEMBundle(certRes.CertificatePEM)
- if err != nil {
- return 0, true
+ if err != nil || len(certChain) == 0 {
+ return 0, nil, true
+ }
+ var ari acme.RenewalInfo
+ if ariPtr, err := certRes.getARI(); err == nil && ariPtr != nil {
+ ari = *ariPtr
}
remaining := time.Until(expiresAt(certChain[0]))
- needsRenew := currentlyInRenewalWindow(certChain[0].NotBefore, expiresAt(certChain[0]), cfg.RenewalWindowRatio)
- return remaining, needsRenew
+ return remaining, certChain[0], cfg.certNeedsRenewal(certChain[0], ari, emitLogs)
}
func (cfg *Config) emit(ctx context.Context, eventName string, data map[string]any) error {
@@ -1173,6 +1277,10 @@ type OCSPConfig struct {
// embedded in certificates. Mapping to an empty
// URL will disable OCSP from that responder.
ResponderOverrides map[string]string
+
+ // Optionally specify a function that can return the URL
+ // for an HTTP proxy to use for OCSP-related HTTP requests.
+ HTTPProxy func(*http.Request) (*url.URL, error)
}
// certIssueLockOp is the name of the operation used
diff --git a/vendor/github.com/caddyserver/certmagic/crypto.go b/vendor/github.com/caddyserver/certmagic/crypto.go
index 5855ad75..879f6aee 100644
--- a/vendor/github.com/caddyserver/certmagic/crypto.go
+++ b/vendor/github.com/caddyserver/certmagic/crypto.go
@@ -280,6 +280,11 @@ func hashCertificateChain(certChain [][]byte) string {
func namesFromCSR(csr *x509.CertificateRequest) []string {
var nameSet []string
+ // TODO: CommonName should not be used (it has been deprecated for 25+ years,
+ // but ZeroSSL CA still requires it to be filled out and not overlap SANs...)
+ if csr.Subject.CommonName != "" {
+ nameSet = append(nameSet, csr.Subject.CommonName)
+ }
nameSet = append(nameSet, csr.DNSNames...)
nameSet = append(nameSet, csr.EmailAddresses...)
for _, v := range csr.IPAddresses {
diff --git a/vendor/github.com/caddyserver/certmagic/dnsutil.go b/vendor/github.com/caddyserver/certmagic/dnsutil.go
index fc93dc2a..81fc192e 100644
--- a/vendor/github.com/caddyserver/certmagic/dnsutil.go
+++ b/vendor/github.com/caddyserver/certmagic/dnsutil.go
@@ -9,6 +9,7 @@ import (
"time"
"github.com/miekg/dns"
+ "go.uber.org/zap"
)
// Code in this file adapted from go-acme/lego, July 2020:
@@ -19,19 +20,21 @@ import (
// findZoneByFQDN determines the zone apex for the given fqdn by recursing
// up the domain labels until the nameserver returns a SOA record in the
-// answer section.
-func findZoneByFQDN(fqdn string, nameservers []string) (string, error) {
+// answer section. The logger must be non-nil.
+func findZoneByFQDN(logger *zap.Logger, fqdn string, nameservers []string) (string, error) {
if !strings.HasSuffix(fqdn, ".") {
fqdn += "."
}
- soa, err := lookupSoaByFqdn(fqdn, nameservers)
+ soa, err := lookupSoaByFqdn(logger, fqdn, nameservers)
if err != nil {
return "", err
}
return soa.zone, nil
}
-func lookupSoaByFqdn(fqdn string, nameservers []string) (*soaCacheEntry, error) {
+func lookupSoaByFqdn(logger *zap.Logger, fqdn string, nameservers []string) (*soaCacheEntry, error) {
+ logger = logger.Named("soa_lookup")
+
if !strings.HasSuffix(fqdn, ".") {
fqdn += "."
}
@@ -41,10 +44,11 @@ func lookupSoaByFqdn(fqdn string, nameservers []string) (*soaCacheEntry, error)
// prefer cached version if fresh
if ent := fqdnSOACache[fqdn]; ent != nil && !ent.isExpired() {
+ logger.Debug("using cached SOA result", zap.String("entry", ent.zone))
return ent, nil
}
- ent, err := fetchSoaByFqdn(fqdn, nameservers)
+ ent, err := fetchSoaByFqdn(logger, fqdn, nameservers)
if err != nil {
return nil, err
}
@@ -62,7 +66,7 @@ func lookupSoaByFqdn(fqdn string, nameservers []string) (*soaCacheEntry, error)
return ent, nil
}
-func fetchSoaByFqdn(fqdn string, nameservers []string) (*soaCacheEntry, error) {
+func fetchSoaByFqdn(logger *zap.Logger, fqdn string, nameservers []string) (*soaCacheEntry, error) {
var err error
var in *dns.Msg
@@ -77,6 +81,7 @@ func fetchSoaByFqdn(fqdn string, nameservers []string) (*soaCacheEntry, error) {
if in == nil {
continue
}
+ logger.Debug("fetched SOA", zap.String("msg", in.String()))
switch in.Rcode {
case dns.RcodeSuccess:
@@ -210,36 +215,46 @@ func populateNameserverPorts(servers []string) {
}
}
-// checkDNSPropagation checks if the expected TXT record has been propagated to all authoritative nameservers.
-func checkDNSPropagation(fqdn, value string, resolvers []string) (bool, error) {
+// checkDNSPropagation checks if the expected record has been propagated to all authoritative nameservers.
+func checkDNSPropagation(logger *zap.Logger, fqdn string, recType uint16, expectedValue string, checkAuthoritativeServers bool, resolvers []string) (bool, error) {
+ logger = logger.Named("propagation")
+
if !strings.HasSuffix(fqdn, ".") {
fqdn += "."
}
- // Initial attempt to resolve at the recursive NS
- r, err := dnsQuery(fqdn, dns.TypeTXT, resolvers, true)
- if err != nil {
- return false, err
+ // Initial attempt to resolve at the recursive NS - but do not actually
+ // dereference (follow) a CNAME record if we are targeting a CNAME record
+ // itself
+ if recType != dns.TypeCNAME {
+ r, err := dnsQuery(fqdn, recType, resolvers, true)
+ if err != nil {
+ return false, fmt.Errorf("CNAME dns query: %v", err)
+ }
+ if r.Rcode == dns.RcodeSuccess {
+ fqdn = updateDomainWithCName(r, fqdn)
+ }
}
- if r.Rcode == dns.RcodeSuccess {
- fqdn = updateDomainWithCName(r, fqdn)
+ if checkAuthoritativeServers {
+ authoritativeServers, err := lookupNameservers(logger, fqdn, resolvers)
+ if err != nil {
+ return false, fmt.Errorf("looking up authoritative nameservers: %v", err)
+ }
+ populateNameserverPorts(authoritativeServers)
+ resolvers = authoritativeServers
}
+ logger.Debug("checking authoritative nameservers", zap.Strings("resolvers", resolvers))
- authoritativeNss, err := lookupNameservers(fqdn, resolvers)
- if err != nil {
- return false, err
- }
-
- return checkAuthoritativeNss(fqdn, value, authoritativeNss)
+ return checkAuthoritativeNss(fqdn, recType, expectedValue, resolvers)
}
-// checkAuthoritativeNss queries each of the given nameservers for the expected TXT record.
-func checkAuthoritativeNss(fqdn, value string, nameservers []string) (bool, error) {
+// checkAuthoritativeNss queries each of the given nameservers for the expected record.
+func checkAuthoritativeNss(fqdn string, recType uint16, expectedValue string, nameservers []string) (bool, error) {
for _, ns := range nameservers {
- r, err := dnsQuery(fqdn, dns.TypeTXT, []string{net.JoinHostPort(ns, "53")}, true)
+ r, err := dnsQuery(fqdn, recType, []string{ns}, true)
if err != nil {
- return false, err
+ return false, fmt.Errorf("querying authoritative nameservers: %v", err)
}
if r.Rcode != dns.RcodeSuccess {
@@ -252,37 +267,43 @@ func checkAuthoritativeNss(fqdn, value string, nameservers []string) (bool, erro
return false, fmt.Errorf("NS %s returned %s for %s", ns, dns.RcodeToString[r.Rcode], fqdn)
}
- var found bool
for _, rr := range r.Answer {
- if txt, ok := rr.(*dns.TXT); ok {
- record := strings.Join(txt.Txt, "")
- if record == value {
- found = true
- break
+ switch recType {
+ case dns.TypeTXT:
+ if txt, ok := rr.(*dns.TXT); ok {
+ record := strings.Join(txt.Txt, "")
+ if record == expectedValue {
+ return true, nil
+ }
}
+ case dns.TypeCNAME:
+ if cname, ok := rr.(*dns.CNAME); ok {
+ // TODO: whether a DNS provider assumes a trailing dot or not varies, and we may have to standardize this in libdns packages
+ if strings.TrimSuffix(cname.Target, ".") == strings.TrimSuffix(expectedValue, ".") {
+ return true, nil
+ }
+ }
+ default:
+ return false, fmt.Errorf("unsupported record type: %d", recType)
}
}
-
- if !found {
- return false, nil
- }
}
- return true, nil
+ return false, nil
}
// lookupNameservers returns the authoritative nameservers for the given fqdn.
-func lookupNameservers(fqdn string, resolvers []string) ([]string, error) {
+func lookupNameservers(logger *zap.Logger, fqdn string, resolvers []string) ([]string, error) {
var authoritativeNss []string
- zone, err := findZoneByFQDN(fqdn, resolvers)
+ zone, err := findZoneByFQDN(logger, fqdn, resolvers)
if err != nil {
- return nil, fmt.Errorf("could not determine the zone: %w", err)
+ return nil, fmt.Errorf("could not determine the zone for '%s': %w", fqdn, err)
}
r, err := dnsQuery(zone, dns.TypeNS, resolvers, true)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("querying NS resolver for zone '%s' recursively: %v", zone, err)
}
for _, rr := range r.Answer {
diff --git a/vendor/github.com/caddyserver/certmagic/filestorage.go b/vendor/github.com/caddyserver/certmagic/filestorage.go
index 8144ae9d..f6f13603 100644
--- a/vendor/github.com/caddyserver/certmagic/filestorage.go
+++ b/vendor/github.com/caddyserver/certmagic/filestorage.go
@@ -92,7 +92,7 @@ func (s *FileStorage) Load(_ context.Context, key string) ([]byte, error) {
// Delete deletes the value at key.
func (s *FileStorage) Delete(_ context.Context, key string) error {
- return os.Remove(s.Filename(key))
+ return os.RemoveAll(s.Filename(key))
}
// List returns all keys that match prefix.
diff --git a/vendor/github.com/caddyserver/certmagic/handshake.go b/vendor/github.com/caddyserver/certmagic/handshake.go
index 9c923f69..fd576995 100644
--- a/vendor/github.com/caddyserver/certmagic/handshake.go
+++ b/vendor/github.com/caddyserver/certmagic/handshake.go
@@ -25,7 +25,7 @@ import (
"sync"
"time"
- "github.com/mholt/acmez"
+ "github.com/mholt/acmez/v2"
"go.uber.org/zap"
"golang.org/x/crypto/ocsp"
)
@@ -65,24 +65,27 @@ func (cfg *Config) GetCertificateWithContext(ctx context.Context, clientHello *t
ctx = context.WithValue(ctx, ClientHelloInfoCtxKey, clientHello)
// special case: serve up the certificate for a TLS-ALPN ACME challenge
- // (https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05)
- for _, proto := range clientHello.SupportedProtos {
- if proto == acmez.ACMETLS1Protocol {
- challengeCert, distributed, err := cfg.getTLSALPNChallengeCert(clientHello)
- if err != nil {
- cfg.Logger.Error("tls-alpn challenge",
- zap.String("remote_addr", clientHello.Conn.RemoteAddr().String()),
- zap.String("server_name", clientHello.ServerName),
- zap.Error(err))
- return nil, err
- }
- cfg.Logger.Info("served key authentication certificate",
+ // (https://www.rfc-editor.org/rfc/rfc8737.html)
+ // "The ACME server MUST provide an ALPN extension with the single protocol
+ // name "acme-tls/1" and an SNI extension containing only the domain name
+ // being validated during the TLS handshake."
+ if clientHello.ServerName != "" &&
+ len(clientHello.SupportedProtos) == 1 &&
+ clientHello.SupportedProtos[0] == acmez.ACMETLS1Protocol {
+ challengeCert, distributed, err := cfg.getTLSALPNChallengeCert(clientHello)
+ if err != nil {
+ cfg.Logger.Error("tls-alpn challenge",
+ zap.String("remote_addr", clientHello.Conn.RemoteAddr().String()),
zap.String("server_name", clientHello.ServerName),
- zap.String("challenge", "tls-alpn-01"),
- zap.String("remote", clientHello.Conn.RemoteAddr().String()),
- zap.Bool("distributed", distributed))
- return challengeCert, nil
+ zap.Error(err))
+ return nil, err
}
+ cfg.Logger.Info("served key authentication certificate",
+ zap.String("server_name", clientHello.ServerName),
+ zap.String("challenge", "tls-alpn-01"),
+ zap.String("remote", clientHello.Conn.RemoteAddr().String()),
+ zap.Bool("distributed", distributed))
+ return challengeCert, nil
}
// get the certificate and serve it up
@@ -120,7 +123,7 @@ func (cfg *Config) getCertificateFromCache(hello *tls.ClientHelloInfo) (cert Cer
}
}
- // fall back to a "default" certificate, if specified
+ // use a "default" certificate by name, if specified
if cfg.DefaultServerName != "" {
normDefault := normalizedName(cfg.DefaultServerName)
cert, defaulted = cfg.selectCert(hello, normDefault)
@@ -316,13 +319,6 @@ func (cfg *Config) getCertDuringHandshake(ctx context.Context, hello *tls.Client
}()
}
- // Make sure a certificate is allowed for the given name. If not, it doesn't
- // make sense to try loading one from storage (issue #185), getting it from a
- // certificate manager, or obtaining one from an issuer.
- if err := cfg.checkIfCertShouldBeObtained(ctx, name, false); err != nil {
- return Certificate{}, fmt.Errorf("certificate is not allowed for server name %s: %w", name, err)
- }
-
// If an external Manager is configured, try to get it from them.
// Only continue to use our own logic if it returns empty+nil.
externalCert, err := cfg.getCertFromAnyCertManager(ctx, hello, logger)
@@ -333,6 +329,12 @@ func (cfg *Config) getCertDuringHandshake(ctx context.Context, hello *tls.Client
return externalCert, nil
}
+ // Make sure a certificate is allowed for the given name. If not, it doesn't make sense
+ // to try loading one from storage (issue #185) or obtaining one from an issuer.
+ if err := cfg.checkIfCertShouldBeObtained(ctx, name, false); err != nil {
+ return Certificate{}, fmt.Errorf("certificate is not allowed for server name %s: %w", name, err)
+ }
+
// We might be able to load or obtain a needed certificate. Load from
// storage if OnDemand is enabled, or if there is the possibility that
// a statically-managed cert was evicted from a full cache.
@@ -547,11 +549,11 @@ func (cfg *Config) obtainOnDemandCertificate(ctx context.Context, hello *tls.Cli
//
// This function is safe for use by multiple concurrent goroutines.
func (cfg *Config) handshakeMaintenance(ctx context.Context, hello *tls.ClientHelloInfo, cert Certificate) (Certificate, error) {
- log := cfg.Logger.Named("on_demand")
+ logger := cfg.Logger.Named("on_demand")
// Check OCSP staple validity
if cert.ocsp != nil && !freshOCSP(cert.ocsp) {
- log.Debug("OCSP response needs refreshing",
+ logger.Debug("OCSP response needs refreshing",
zap.Strings("identifiers", cert.Names),
zap.Int("ocsp_status", cert.ocsp.Status),
zap.Time("this_update", cert.ocsp.ThisUpdate),
@@ -561,12 +563,12 @@ func (cfg *Config) handshakeMaintenance(ctx context.Context, hello *tls.ClientHe
if err != nil {
// An error with OCSP stapling is not the end of the world, and in fact, is
// quite common considering not all certs have issuer URLs that support it.
- log.Warn("stapling OCSP",
+ logger.Warn("stapling OCSP",
zap.String("server_name", hello.ServerName),
zap.Strings("sans", cert.Names),
zap.Error(err))
} else {
- log.Debug("successfully stapled new OCSP response",
+ logger.Debug("successfully stapled new OCSP response",
zap.Strings("identifiers", cert.Names),
zap.Int("ocsp_status", cert.ocsp.Status),
zap.Time("this_update", cert.ocsp.ThisUpdate),
@@ -579,10 +581,20 @@ func (cfg *Config) handshakeMaintenance(ctx context.Context, hello *tls.ClientHe
cfg.certCache.mu.Unlock()
}
+ // Check ARI status
+ if cert.ari.NeedsRefresh() {
+ // we ignore the second return value here because we go on to check renewal status below regardless
+ var err error
+ cert, _, err = cfg.updateARI(ctx, cert, logger)
+ if err != nil {
+ logger.Error("updated ARI", zap.Error(err))
+ }
+ }
+
// We attempt to replace any certificates that were revoked.
// Crucially, this happens OUTSIDE a lock on the certCache.
if certShouldBeForceRenewed(cert) {
- log.Warn("on-demand certificate's OCSP status is REVOKED; will try to forcefully renew",
+ logger.Warn("on-demand certificate's OCSP status is REVOKED; will try to forcefully renew",
zap.Strings("identifiers", cert.Names),
zap.Int("ocsp_status", cert.ocsp.Status),
zap.Time("revoked_at", cert.ocsp.RevokedAt),
@@ -592,14 +604,13 @@ func (cfg *Config) handshakeMaintenance(ctx context.Context, hello *tls.ClientHe
}
// Check cert expiration
- if currentlyInRenewalWindow(cert.Leaf.NotBefore, expiresAt(cert.Leaf), cfg.RenewalWindowRatio) {
+ if cfg.certNeedsRenewal(cert.Leaf, cert.ari, true) {
// Check if the certificate still exists on disk. If not, we need to obtain a new one.
// This can happen if the certificate was cleaned up by the storage cleaner, but still
// remains in the in-memory cache.
if !cfg.storageHasCertResourcesAnyIssuer(ctx, cert.Names[0]) {
- log.Debug("certificate not found on disk; obtaining new certificate",
+ logger.Debug("certificate not found on disk; obtaining new certificate",
zap.Strings("identifiers", cert.Names))
-
return cfg.obtainOnDemandCertificate(ctx, hello)
}
// Otherwise, renew the certificate.
@@ -621,7 +632,7 @@ func (cfg *Config) handshakeMaintenance(ctx context.Context, hello *tls.ClientHe
//
// This function is safe for use by multiple concurrent goroutines.
func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.ClientHelloInfo, currentCert Certificate) (Certificate, error) {
- log := logWithRemote(cfg.Logger.Named("on_demand"), hello)
+ logger := logWithRemote(cfg.Logger.Named("on_demand"), hello)
name := cfg.getNameFromClientHello(hello)
timeLeft := time.Until(expiresAt(currentCert.Leaf))
@@ -638,7 +649,7 @@ func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.Clien
// renewing it, so we might as well serve what we have without blocking, UNLESS
// we're forcing renewal, in which case the current certificate is not usable
if timeLeft > 0 && !revoked {
- log.Debug("certificate expires soon but is already being renewed; serving current certificate",
+ logger.Debug("certificate expires soon but is already being renewed; serving current certificate",
zap.Strings("subjects", currentCert.Names),
zap.Duration("remaining", timeLeft))
return currentCert, nil
@@ -647,7 +658,7 @@ func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.Clien
// otherwise, we'll have to wait for the renewal to finish so we don't serve
// a revoked or expired certificate
- log.Debug("certificate has expired, but is already being renewed; waiting for renewal to complete",
+ logger.Debug("certificate has expired, but is already being renewed; waiting for renewal to complete",
zap.Strings("subjects", currentCert.Names),
zap.Time("expired", expiresAt(currentCert.Leaf)),
zap.Bool("revoked", revoked))
@@ -678,7 +689,7 @@ func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.Clien
obtainCertWaitChansMu.Unlock()
}
- log = log.With(
+ logger = logger.With(
zap.String("server_name", name),
zap.Strings("subjects", currentCert.Names),
zap.Time("expiration", expiresAt(currentCert.Leaf)),
@@ -699,19 +710,19 @@ func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.Clien
cfg.certCache.mu.Unlock()
unblockWaiters()
- if log != nil {
- log.Error("certificate should not be obtained", zap.Error(err))
+ if logger != nil {
+ logger.Error("certificate should not be obtained", zap.Error(err))
}
return Certificate{}, err
}
- log.Info("attempting certificate renewal")
+ logger.Info("attempting certificate renewal")
// otherwise, renew with issuer, etc.
var newCert Certificate
if revoked {
- newCert, err = cfg.forceRenew(ctx, log, currentCert)
+ newCert, err = cfg.forceRenew(ctx, logger, currentCert)
} else {
err = cfg.RenewCertAsync(ctx, name, false)
if err == nil {
@@ -726,7 +737,7 @@ func (cfg *Config) renewDynamicCertificate(ctx context.Context, hello *tls.Clien
unblockWaiters()
if err != nil {
- log.Error("renewing and reloading certificate", zap.String("server_name", name), zap.Error(err))
+ logger.Error("renewing and reloading certificate", zap.String("server_name", name), zap.Error(err))
}
return newCert, err
@@ -753,16 +764,16 @@ func (cfg *Config) getCertFromAnyCertManager(ctx context.Context, hello *tls.Cli
return Certificate{}, nil
}
- var upstreamCert *tls.Certificate
-
// try all the GetCertificate methods on external managers; use first one that returns a certificate
+ var upstreamCert *tls.Certificate
+ var err error
for i, certManager := range cfg.OnDemand.Managers {
- var err error
upstreamCert, err = certManager.GetCertificate(ctx, hello)
if err != nil {
- logger.Error("getting certificate from external certificate manager",
+ logger.Error("external certificate manager",
zap.String("sni", hello.ServerName),
- zap.Int("cert_manager", i),
+ zap.String("cert_manager", fmt.Sprintf("%T", certManager)),
+ zap.Int("cert_manager_idx", i),
zap.Error(err))
continue
}
@@ -770,14 +781,16 @@ func (cfg *Config) getCertFromAnyCertManager(ctx context.Context, hello *tls.Cli
break
}
}
+ if err != nil {
+ return Certificate{}, fmt.Errorf("external certificate manager indicated that it is unable to yield certificate: %v", err)
+ }
if upstreamCert == nil {
logger.Debug("all external certificate managers yielded no certificates and no errors", zap.String("sni", hello.ServerName))
return Certificate{}, nil
}
var cert Certificate
- err := fillCertFromLeaf(&cert, *upstreamCert)
- if err != nil {
+ if err = fillCertFromLeaf(&cert, *upstreamCert); err != nil {
return Certificate{}, fmt.Errorf("external certificate manager: %s: filling cert from leaf: %v", hello.ServerName, err)
}
@@ -822,10 +835,13 @@ func (cfg *Config) getTLSALPNChallengeCert(clientHello *tls.ClientHelloInfo) (*t
// getNameFromClientHello returns a normalized form of hello.ServerName.
// If hello.ServerName is empty (i.e. client did not use SNI), then the
// associated connection's local address is used to extract an IP address.
-func (*Config) getNameFromClientHello(hello *tls.ClientHelloInfo) string {
+func (cfg *Config) getNameFromClientHello(hello *tls.ClientHelloInfo) string {
if name := normalizedName(hello.ServerName); name != "" {
return name
}
+ if cfg.DefaultServerName != "" {
+ return normalizedName(cfg.DefaultServerName)
+ }
return localIPFromConn(hello.Conn)
}
diff --git a/vendor/github.com/caddyserver/certmagic/httphandler.go b/vendor/github.com/caddyserver/certmagic/httphandlers.go
similarity index 61%
rename from vendor/github.com/caddyserver/certmagic/httphandler.go
rename to vendor/github.com/caddyserver/certmagic/httphandlers.go
index fc2a8804..f2dde422 100644
--- a/vendor/github.com/caddyserver/certmagic/httphandler.go
+++ b/vendor/github.com/caddyserver/certmagic/httphandlers.go
@@ -16,9 +16,10 @@ package certmagic
import (
"net/http"
+ "net/url"
"strings"
- "github.com/mholt/acmez/acme"
+ "github.com/mholt/acmez/v2/acme"
"go.uber.org/zap"
)
@@ -91,7 +92,7 @@ func solveHTTPChallenge(logger *zap.Logger, w http.ResponseWriter, r *http.Reque
challengeReqPath := challenge.HTTP01ResourcePath()
if r.URL.Path == challengeReqPath &&
strings.EqualFold(hostOnly(r.Host), challenge.Identifier.Value) && // mitigate DNS rebinding attacks
- r.Method == "GET" {
+ r.Method == http.MethodGet {
w.Header().Add("Content-Type", "text/plain")
w.Write([]byte(challenge.KeyAuthorization))
r.Close = true
@@ -116,7 +117,94 @@ func SolveHTTPChallenge(logger *zap.Logger, w http.ResponseWriter, r *http.Reque
// LooksLikeHTTPChallenge returns true if r looks like an ACME
// HTTP challenge request from an ACME server.
func LooksLikeHTTPChallenge(r *http.Request) bool {
- return r.Method == "GET" && strings.HasPrefix(r.URL.Path, challengeBasePath)
+ return r.Method == http.MethodGet &&
+ strings.HasPrefix(r.URL.Path, acmeHTTPChallengeBasePath)
}
-const challengeBasePath = "/.well-known/acme-challenge"
+// LooksLikeZeroSSLHTTPValidation returns true if the request appears to be
+// domain validation from a ZeroSSL/Sectigo CA. NOTE: This API is
+// non-standard and is subject to change.
+func LooksLikeZeroSSLHTTPValidation(r *http.Request) bool {
+ return r.Method == http.MethodGet &&
+ strings.HasPrefix(r.URL.Path, zerosslHTTPValidationBasePath)
+}
+
+// HTTPValidationHandler wraps the ZeroSSL HTTP validation handler such that
+// it can pass verification checks from ZeroSSL's API.
+//
+// If a request is not a ZeroSSL HTTP validation request, h will be invoked.
+func (iss *ZeroSSLIssuer) HTTPValidationHandler(h http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ if iss.HandleZeroSSLHTTPValidation(w, r) {
+ return
+ }
+ h.ServeHTTP(w, r)
+ })
+}
+
+// HandleZeroSSLHTTPValidation is to ZeroSSL API HTTP validation requests like HandleHTTPChallenge
+// is to ACME HTTP challenge requests.
+func (iss *ZeroSSLIssuer) HandleZeroSSLHTTPValidation(w http.ResponseWriter, r *http.Request) bool {
+ if iss == nil {
+ return false
+ }
+ if !LooksLikeZeroSSLHTTPValidation(r) {
+ return false
+ }
+ return iss.distributedHTTPValidationAnswer(w, r)
+}
+
+func (iss *ZeroSSLIssuer) distributedHTTPValidationAnswer(w http.ResponseWriter, r *http.Request) bool {
+ if iss == nil {
+ return false
+ }
+ logger := iss.Logger
+ if logger == nil {
+ logger = zap.NewNop()
+ }
+ host := hostOnly(r.Host)
+ valInfo, distributed, err := iss.getDistributedValidationInfo(r.Context(), host)
+ if err != nil {
+ logger.Error("looking up info for HTTP validation",
+ zap.String("host", host),
+ zap.String("remote_addr", r.RemoteAddr),
+ zap.String("user_agent", r.Header.Get("User-Agent")),
+ zap.Error(err))
+ return false
+ }
+ return answerHTTPValidation(logger, w, r, valInfo, distributed)
+}
+
+func answerHTTPValidation(logger *zap.Logger, rw http.ResponseWriter, req *http.Request, valInfo acme.Challenge, distributed bool) bool {
+ // ensure URL matches
+ validationURL, err := url.Parse(valInfo.URL)
+ if err != nil {
+ logger.Error("got invalid URL from CA",
+ zap.String("file_validation_url", valInfo.URL),
+ zap.Error(err))
+ rw.WriteHeader(http.StatusInternalServerError)
+ return true
+ }
+ if req.URL.Path != validationURL.Path {
+ rw.WriteHeader(http.StatusNotFound)
+ return true
+ }
+
+ rw.Header().Add("Content-Type", "text/plain")
+ req.Close = true
+
+ rw.Write([]byte(valInfo.Token))
+
+ logger.Info("served HTTP validation credential",
+ zap.String("validation_path", valInfo.URL),
+ zap.String("challenge", "http-01"),
+ zap.String("remote", req.RemoteAddr),
+ zap.Bool("distributed", distributed))
+
+ return true
+}
+
+const (
+ acmeHTTPChallengeBasePath = "/.well-known/acme-challenge"
+ zerosslHTTPValidationBasePath = "/.well-known/pki-validation/"
+)
diff --git a/vendor/github.com/caddyserver/certmagic/maintain.go b/vendor/github.com/caddyserver/certmagic/maintain.go
index 9ffb7310..848447bd 100644
--- a/vendor/github.com/caddyserver/certmagic/maintain.go
+++ b/vendor/github.com/caddyserver/certmagic/maintain.go
@@ -27,7 +27,7 @@ import (
"strings"
"time"
- "github.com/mholt/acmez/acme"
+ "github.com/mholt/acmez/v2/acme"
"go.uber.org/zap"
"golang.org/x/crypto/ocsp"
)
@@ -92,7 +92,7 @@ func (certCache *Cache) maintainAssets(panicCount int) {
func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
log := certCache.logger.Named("maintenance")
- // configs will hold a map of certificate name to the config
+ // configs will hold a map of certificate hash to the config
// to use when managing that certificate
configs := make(map[string]*Config)
@@ -102,7 +102,7 @@ func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
// words, our first iteration through the certificate cache does NOT
// perform any operations--only queues them--so that more fine-grained
// write locks may be obtained during the actual operations.
- var renewQueue, reloadQueue, deleteQueue []Certificate
+ var renewQueue, reloadQueue, deleteQueue, ariQueue certList
certCache.mu.RLock()
for certKey, cert := range certCache.cache {
@@ -135,22 +135,28 @@ func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
continue
}
+ // ACME-specific: see if if ACME Renewal Info (ARI) window needs refreshing
+ if cert.ari.NeedsRefresh() {
+ configs[cert.hash] = cfg
+ ariQueue = append(ariQueue, cert)
+ }
+
// if time is up or expires soon, we need to try to renew it
if cert.NeedsRenewal(cfg) {
- configs[cert.Names[0]] = cfg
+ configs[cert.hash] = cfg
// see if the certificate in storage has already been renewed, possibly by another
// instance that didn't coordinate with this one; if so, just load it (this
// might happen if another instance already renewed it - kinda sloppy but checking disk
// first is a simple way to possibly drastically reduce rate limit problems)
- storedCertExpiring, err := cfg.managedCertInStorageExpiresSoon(ctx, cert)
+ storedCertNeedsRenew, err := cfg.managedCertInStorageNeedsRenewal(ctx, cert)
if err != nil {
// hmm, weird, but not a big deal, maybe it was deleted or something
log.Warn("error while checking if stored certificate is also expiring soon",
zap.Strings("identifiers", cert.Names),
zap.Error(err))
- } else if !storedCertExpiring {
- // if the certificate is NOT expiring soon and there was no error, then we
+ } else if !storedCertNeedsRenew {
+ // if the certificate does NOT need renewal and there was no error, then we
// are good to just reload the certificate from storage instead of repeating
// a likely-unnecessary renewal procedure
reloadQueue = append(reloadQueue, cert)
@@ -161,11 +167,30 @@ func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
// NOTE: It is super-important to note that the TLS-ALPN challenge requires
// a write lock on the cache in order to complete its challenge, so it is extra
// vital that this renew operation does not happen inside our read lock!
- renewQueue = append(renewQueue, cert)
+ renewQueue.insert(cert)
}
}
certCache.mu.RUnlock()
+ // Update ARI, and then for any certs where the ARI window changed,
+ // be sure to queue them for renewal if necessary
+ for _, cert := range ariQueue {
+ cfg := configs[cert.hash]
+ cert, changed, err := cfg.updateARI(ctx, cert, log)
+ if err != nil {
+ log.Error("updating ARI", zap.Error(err))
+ }
+ if changed && cert.NeedsRenewal(cfg) {
+ // it's theoretically possible that another instance already got the memo
+ // on the changed ARI and even renewed the cert already, and thus doing it
+ // here is wasteful, but I have never heard of this happening in reality,
+ // so to save some cycles for now I think we'll just queue it for renewal
+ // (notice how we use 'insert' to avoid duplicates, in case it was already
+ // scheduled for renewal anyway)
+ renewQueue.insert(cert)
+ }
+ }
+
// Reload certificates that merely need to be updated in memory
for _, oldCert := range reloadQueue {
timeLeft := expiresAt(oldCert.Leaf).Sub(time.Now().UTC())
@@ -173,7 +198,7 @@ func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
zap.Strings("identifiers", oldCert.Names),
zap.Duration("remaining", timeLeft))
- cfg := configs[oldCert.Names[0]]
+ cfg := configs[oldCert.hash]
// crucially, this happens OUTSIDE a lock on the certCache
_, err := cfg.reloadManagedCertificate(ctx, oldCert)
@@ -187,7 +212,7 @@ func (certCache *Cache) RenewManagedCertificates(ctx context.Context) error {
// Renewal queue
for _, oldCert := range renewQueue {
- cfg := configs[oldCert.Names[0]]
+ cfg := configs[oldCert.hash]
err := certCache.queueRenewalTask(ctx, oldCert, cfg)
if err != nil {
log.Error("queueing renewal task",
@@ -390,6 +415,171 @@ func (certCache *Cache) updateOCSPStaples(ctx context.Context) {
}
}
+// storageHasNewerARI returns true if the configured storage has ARI that is newer
+// than that of a certificate that is already loaded, along with the value from
+// storage.
+func (cfg *Config) storageHasNewerARI(ctx context.Context, cert Certificate) (bool, acme.RenewalInfo, error) {
+ storedCertData, err := cfg.loadStoredACMECertificateMetadata(ctx, cert)
+ if err != nil || storedCertData.RenewalInfo == nil {
+ return false, acme.RenewalInfo{}, err
+ }
+ // prefer stored info if it has a window and the loaded one doesn't,
+ // or if the one in storage has a later RetryAfter (though I suppose
+ // it's not guaranteed, typically those will move forward in time)
+ if (!cert.ari.HasWindow() && storedCertData.RenewalInfo.HasWindow()) ||
+ storedCertData.RenewalInfo.RetryAfter.After(*cert.ari.RetryAfter) {
+ return true, *storedCertData.RenewalInfo, nil
+ }
+ return false, acme.RenewalInfo{}, nil
+}
+
+// loadStoredACMECertificateMetadata loads the stored ACME certificate data
+// from the cert's sidecar JSON file.
+func (cfg *Config) loadStoredACMECertificateMetadata(ctx context.Context, cert Certificate) (acme.Certificate, error) {
+ metaBytes, err := cfg.Storage.Load(ctx, StorageKeys.SiteMeta(cert.issuerKey, cert.Names[0]))
+ if err != nil {
+ return acme.Certificate{}, fmt.Errorf("loading cert metadata: %w", err)
+ }
+
+ var certRes CertificateResource
+ if err = json.Unmarshal(metaBytes, &certRes); err != nil {
+ return acme.Certificate{}, fmt.Errorf("unmarshaling cert metadata: %w", err)
+ }
+
+ var acmeCert acme.Certificate
+ if err = json.Unmarshal(certRes.IssuerData, &acmeCert); err != nil {
+ return acme.Certificate{}, fmt.Errorf("unmarshaling potential ACME issuer metadata: %v", err)
+ }
+
+ return acmeCert, nil
+}
+
+// updateARI updates the cert's ACME renewal info, first by checking storage for a newer
+// one, or getting it from the CA if needed. The updated info is stored in storage and
+// updated in the cache. The certificate with the updated ARI is returned. If true is
+// returned, the ARI window or selected time has changed, and the caller should check if
+// the cert needs to be renewed now, even if there is an error.
+func (cfg *Config) updateARI(ctx context.Context, cert Certificate, logger *zap.Logger) (updatedCert Certificate, changed bool, err error) {
+ logger = logger.With(
+ zap.Strings("identifiers", cert.Names),
+ zap.String("cert_hash", cert.hash),
+ zap.String("ari_unique_id", cert.ari.UniqueIdentifier),
+ zap.Time("cert_expiry", cert.Leaf.NotAfter))
+
+ updatedCert = cert
+ oldARI := cert.ari
+
+ // see if the stored value has been refreshed already by another instance
+ gotNewARI, newARI, err := cfg.storageHasNewerARI(ctx, cert)
+
+ // when we're all done, log if something about the schedule is different
+ // ("WARN" level because ARI window changing may be a sign of external trouble
+ // and we want to draw their attention to a potential explanation URL)
+ defer func() {
+ changed = !newARI.SameWindow(oldARI)
+
+ if changed {
+ logger.Warn("ARI window or selected renewal time changed",
+ zap.Time("prev_start", oldARI.SuggestedWindow.Start),
+ zap.Time("next_start", newARI.SuggestedWindow.Start),
+ zap.Time("prev_end", oldARI.SuggestedWindow.End),
+ zap.Time("next_end", newARI.SuggestedWindow.End),
+ zap.Time("prev_selected_time", oldARI.SelectedTime),
+ zap.Time("next_selected_time", newARI.SelectedTime),
+ zap.String("explanation_url", newARI.ExplanationURL))
+ }
+ }()
+
+ if err == nil && gotNewARI {
+ // great, storage has a newer one we can use
+ cfg.certCache.mu.Lock()
+ updatedCert = cfg.certCache.cache[cert.hash]
+ updatedCert.ari = newARI
+ cfg.certCache.cache[cert.hash] = updatedCert
+ cfg.certCache.mu.Unlock()
+ logger.Info("reloaded ARI with newer one in storage",
+ zap.Timep("next_refresh", newARI.RetryAfter),
+ zap.Time("renewal_time", newARI.SelectedTime))
+ return
+ }
+
+ if err != nil {
+ logger.Error("error while checking storage for updated ARI; updating ARI now", zap.Error(err))
+ }
+
+ // of the issuers configured, hopefully one of them is the ACME CA we got the cert from
+ for _, iss := range cfg.Issuers {
+ if acmeIss, ok := iss.(*ACMEIssuer); ok {
+ newARI, err = acmeIss.getRenewalInfo(ctx, cert) // be sure to use existing newARI variable so we can compare against old value in the defer
+ if err != nil {
+ // could be anything, but a common error might simply be the "wrong" ACME CA
+ // (meaning, different from the one that issued the cert, thus the only one
+ // that would have any ARI for it) if multiple ACME CAs are configured
+ logger.Error("failed updating renewal info from ACME CA",
+ zap.String("issuer", iss.IssuerKey()),
+ zap.Error(err))
+ continue
+ }
+
+ // when we get the latest ARI, the acme package will select a time within the window
+ // for us; of course, since it's random, it's likely different from the previously-
+ // selected time; but if the window doesn't change, there's no need to change the
+ // selected time (the acme package doesn't know the previous window to know better)
+ // ... so if the window hasn't changed we'll just put back the selected time
+ if newARI.SameWindow(oldARI) && !oldARI.SelectedTime.IsZero() {
+ newARI.SelectedTime = oldARI.SelectedTime
+ }
+
+ // then store the updated ARI (even if the window didn't change, the Retry-After
+ // likely did) in cache and storage
+
+ // be sure we get the cert from the cache while inside a lock to avoid logical races
+ cfg.certCache.mu.Lock()
+ updatedCert = cfg.certCache.cache[cert.hash]
+ updatedCert.ari = newARI
+ cfg.certCache.cache[cert.hash] = updatedCert
+ cfg.certCache.mu.Unlock()
+
+ // update the ARI value in storage
+ var certData acme.Certificate
+ certData, err = cfg.loadStoredACMECertificateMetadata(ctx, cert)
+ if err != nil {
+ err = fmt.Errorf("got new ARI from %s, but failed loading stored certificate metadata: %v", iss.IssuerKey(), err)
+ return
+ }
+ certData.RenewalInfo = &newARI
+ var certDataBytes, certResBytes []byte
+ certDataBytes, err = json.Marshal(certData)
+ if err != nil {
+ err = fmt.Errorf("got new ARI from %s, but failed marshaling certificate ACME metadata: %v", iss.IssuerKey(), err)
+ return
+ }
+ certResBytes, err = json.MarshalIndent(CertificateResource{
+ SANs: cert.Names,
+ IssuerData: certDataBytes,
+ }, "", "\t")
+ if err != nil {
+ err = fmt.Errorf("got new ARI from %s, but could not re-encode certificate metadata: %v", iss.IssuerKey(), err)
+ return
+ }
+ if err = cfg.Storage.Store(ctx, StorageKeys.SiteMeta(cert.issuerKey, cert.Names[0]), certResBytes); err != nil {
+ err = fmt.Errorf("got new ARI from %s, but could not store it with certificate metadata: %v", iss.IssuerKey(), err)
+ return
+ }
+
+ logger.Info("updated ACME renewal information",
+ zap.Time("selected_time", newARI.SelectedTime),
+ zap.Timep("next_update", newARI.RetryAfter),
+ zap.String("explanation_url", newARI.ExplanationURL))
+
+ return
+ }
+ }
+
+ err = fmt.Errorf("could not fully update ACME renewal info: either no ACME issuer configured for certificate, or all failed (make sure the ACME CA that issued the certificate is configured)")
+ return
+}
+
// CleanStorageOptions specifies how to clean up a storage unit.
type CleanStorageOptions struct {
// Optional custom logger.
@@ -452,7 +642,7 @@ func CleanStorage(ctx context.Context, storage Storage, opts CleanStorageOptions
lastTLSClean := lastClean["tls"]
if time.Since(lastTLSClean.Timestamp) < opts.Interval {
nextTime := time.Now().Add(opts.Interval)
- opts.Logger.Warn("storage cleaning happened too recently; skipping for now",
+ opts.Logger.Info("storage cleaning happened too recently; skipping for now",
zap.String("instance", lastTLSClean.InstanceID),
zap.Time("try_again", nextTime),
zap.Duration("try_again_in", time.Until(nextTime)),
@@ -725,6 +915,19 @@ func certShouldBeForceRenewed(cert Certificate) bool {
cert.ocsp.Status == ocsp.Revoked
}
+type certList []Certificate
+
+// insert appends cert to the list if it is not already in the list.
+// Efficiency: O(n)
+func (certs *certList) insert(cert Certificate) {
+ for _, c := range *certs {
+ if c.hash == cert.hash {
+ return
+ }
+ }
+ *certs = append(*certs, cert)
+}
+
const (
// DefaultRenewCheckInterval is how often to check certificates for expiration.
// Scans are very lightweight, so this can be semi-frequent. This default should
diff --git a/vendor/github.com/caddyserver/certmagic/ocsp.go b/vendor/github.com/caddyserver/certmagic/ocsp.go
index 57135eed..fe6dbb8f 100644
--- a/vendor/github.com/caddyserver/certmagic/ocsp.go
+++ b/vendor/github.com/caddyserver/certmagic/ocsp.go
@@ -168,12 +168,24 @@ func getOCSPForCert(ocspConfig OCSPConfig, bundle []byte) ([]byte, *ocsp.Respons
return nil, nil, fmt.Errorf("override disables querying OCSP responder: %v", issuedCert.OCSPServer[0])
}
+ // configure HTTP client if necessary
+ httpClient := http.DefaultClient
+ if ocspConfig.HTTPProxy != nil {
+ httpClient = &http.Client{
+ Transport: &http.Transport{
+ Proxy: ocspConfig.HTTPProxy,
+ },
+ Timeout: 30 * time.Second,
+ }
+ }
+
+ // get issuer certificate if needed
if len(certificates) == 1 {
if len(issuedCert.IssuingCertificateURL) == 0 {
return nil, nil, fmt.Errorf("no URL to issuing certificate")
}
- resp, err := http.Get(issuedCert.IssuingCertificateURL[0])
+ resp, err := httpClient.Get(issuedCert.IssuingCertificateURL[0])
if err != nil {
return nil, nil, fmt.Errorf("getting issuer certificate: %v", err)
}
@@ -202,7 +214,7 @@ func getOCSPForCert(ocspConfig OCSPConfig, bundle []byte) ([]byte, *ocsp.Respons
}
reader := bytes.NewReader(ocspReq)
- req, err := http.Post(respURL, "application/ocsp-request", reader)
+ req, err := httpClient.Post(respURL, "application/ocsp-request", reader)
if err != nil {
return nil, nil, fmt.Errorf("making OCSP request: %v", err)
}
diff --git a/vendor/github.com/caddyserver/certmagic/solvers.go b/vendor/github.com/caddyserver/certmagic/solvers.go
index 51ef096b..557f17bd 100644
--- a/vendor/github.com/caddyserver/certmagic/solvers.go
+++ b/vendor/github.com/caddyserver/certmagic/solvers.go
@@ -30,9 +30,10 @@ import (
"time"
"github.com/libdns/libdns"
- "github.com/mholt/acmez"
- "github.com/mholt/acmez/acme"
+ "github.com/mholt/acmez/v2"
+ "github.com/mholt/acmez/v2/acme"
"github.com/miekg/dns"
+ "go.uber.org/zap"
)
// httpSolver solves the HTTP challenge. It must be
@@ -46,9 +47,9 @@ import (
// can access the keyAuth material is by loading it
// from storage, which is done by distributedSolver.
type httpSolver struct {
- closed int32 // accessed atomically
- acmeIssuer *ACMEIssuer
- address string
+ closed int32 // accessed atomically
+ handler http.Handler
+ address string
}
// Present starts an HTTP server if none is already listening on s.address.
@@ -88,7 +89,7 @@ func (s *httpSolver) serve(ctx context.Context, si *solverInfo) {
}()
defer close(si.done)
httpServer := &http.Server{
- Handler: s.acmeIssuer.HTTPChallengeHandler(http.NewServeMux()),
+ Handler: s.handler,
BaseContext: func(listener net.Listener) context.Context { return ctx },
}
httpServer.SetKeepAlivesEnabled(false)
@@ -250,9 +251,92 @@ func (s *tlsALPNSolver) CleanUp(_ context.Context, chal acme.Challenge) error {
// DNS provider APIs and implementations of the libdns interfaces must also
// support multiple same-named TXT records.
type DNS01Solver struct {
+ DNSManager
+}
+
+// Present creates the DNS TXT record for the given ACME challenge.
+func (s *DNS01Solver) Present(ctx context.Context, challenge acme.Challenge) error {
+ dnsName := challenge.DNS01TXTRecordName()
+ if s.OverrideDomain != "" {
+ dnsName = s.OverrideDomain
+ }
+ keyAuth := challenge.DNS01KeyAuthorization()
+
+ zrec, err := s.DNSManager.createRecord(ctx, dnsName, "TXT", keyAuth)
+ if err != nil {
+ return err
+ }
+
+ // remember the record and zone we got so we can clean up more efficiently
+ s.saveDNSPresentMemory(dnsPresentMemory{
+ dnsName: dnsName,
+ zoneRec: zrec,
+ })
+
+ return nil
+}
+
+// Wait blocks until the TXT record created in Present() appears in
+// authoritative lookups, i.e. until it has propagated, or until
+// timeout, whichever is first.
+func (s *DNS01Solver) Wait(ctx context.Context, challenge acme.Challenge) error {
+ // prepare for the checks by determining what to look for
+ dnsName := challenge.DNS01TXTRecordName()
+ if s.OverrideDomain != "" {
+ dnsName = s.OverrideDomain
+ }
+ keyAuth := challenge.DNS01KeyAuthorization()
+
+ // wait for the record to propagate
+ memory, err := s.getDNSPresentMemory(dnsName, "TXT", keyAuth)
+ if err != nil {
+ return err
+ }
+ return s.DNSManager.wait(ctx, memory.zoneRec)
+}
+
+// CleanUp deletes the DNS TXT record created in Present().
+//
+// We ignore the context because cleanup is often/likely performed after
+// a context cancellation, and properly-implemented DNS providers should
+// honor cancellation, which would result in cleanup being aborted.
+// Cleanup must always occur.
+func (s *DNS01Solver) CleanUp(ctx context.Context, challenge acme.Challenge) error {
+ dnsName := challenge.DNS01TXTRecordName()
+ if s.OverrideDomain != "" {
+ dnsName = s.OverrideDomain
+ }
+ keyAuth := challenge.DNS01KeyAuthorization()
+
+ // always forget about the record so we don't leak memory
+ defer s.deleteDNSPresentMemory(dnsName, keyAuth)
+
+ // recall the record we created and zone we looked up
+ memory, err := s.getDNSPresentMemory(dnsName, "TXT", keyAuth)
+ if err != nil {
+ return err
+ }
+
+ if err := s.DNSManager.cleanUpRecord(ctx, memory.zoneRec); err != nil {
+ return err
+ }
+ return nil
+}
+
+// DNSManager is a type that makes libdns providers usable for performing
+// DNS verification. See https://github.com/libdns/libdns
+//
+// Note that records may be manipulated concurrently by some clients (such as
+// acmez, which CertMagic uses), meaning that multiple records may be created
+// in a DNS zone simultaneously, and in some cases distinct records of the same
+// type may have the same name. For example, solving ACME challenges for both example.com
+// and *.example.com create a TXT record named _acme_challenge.example.com,
+// but with different tokens as their values. This solver distinguishes between
+// different records with the same type and name by looking at their values.
+type DNSManager struct {
// The implementation that interacts with the DNS
// provider to set or delete records. (REQUIRED)
- DNSProvider ACMEDNSProvider
+ DNSProvider DNSProvider
// The TTL for the temporary challenge records.
TTL time.Duration
@@ -274,6 +358,9 @@ type DNS01Solver struct {
// that the solver doesn't follow CNAME/NS record.
OverrideDomain string
+ // An optional logger.
+ Logger *zap.Logger
+
// Remember DNS records while challenges are active; i.e.
// records we have presented and not yet cleaned up.
// This lets us clean them up quickly and efficiently.
@@ -285,83 +372,81 @@ type DNS01Solver struct {
// the value of their TXT records, which should contain
// unique challenge tokens.
// See https://github.com/caddyserver/caddy/issues/3474.
- txtRecords map[string][]dnsPresentMemory
- txtRecordsMu sync.Mutex
+ records map[string][]dnsPresentMemory
+ recordsMu sync.Mutex
}
-// Present creates the DNS TXT record for the given ACME challenge.
-func (s *DNS01Solver) Present(ctx context.Context, challenge acme.Challenge) error {
- dnsName := challenge.DNS01TXTRecordName()
- if s.OverrideDomain != "" {
- dnsName = s.OverrideDomain
- }
- keyAuth := challenge.DNS01KeyAuthorization()
+func (m *DNSManager) createRecord(ctx context.Context, dnsName, recordType, recordValue string) (zoneRecord, error) {
+ logger := m.logger()
- zone, err := findZoneByFQDN(dnsName, recursiveNameservers(s.Resolvers))
+ zone, err := findZoneByFQDN(logger, dnsName, recursiveNameservers(m.Resolvers))
if err != nil {
- return fmt.Errorf("could not determine zone for domain %q: %v", dnsName, err)
+ return zoneRecord{}, fmt.Errorf("could not determine zone for domain %q: %v", dnsName, err)
}
-
rec := libdns.Record{
- Type: "TXT",
+ Type: recordType,
Name: libdns.RelativeName(dnsName+".", zone),
- Value: keyAuth,
- TTL: s.TTL,
+ Value: recordValue,
+ TTL: m.TTL,
}
- results, err := s.DNSProvider.AppendRecords(ctx, zone, []libdns.Record{rec})
+ logger.Debug("creating DNS record",
+ zap.String("dns_name", dnsName),
+ zap.String("zone", zone),
+ zap.String("record_name", rec.Name),
+ zap.String("record_type", rec.Type),
+ zap.String("record_value", rec.Value),
+ zap.Duration("record_ttl", rec.TTL))
+
+ results, err := m.DNSProvider.AppendRecords(ctx, zone, []libdns.Record{rec})
if err != nil {
- return fmt.Errorf("adding temporary record for zone %q: %w", zone, err)
+ return zoneRecord{}, fmt.Errorf("adding temporary record for zone %q: %w", zone, err)
}
if len(results) != 1 {
- return fmt.Errorf("expected one record, got %d: %v", len(results), results)
+ return zoneRecord{}, fmt.Errorf("expected one record, got %d: %v", len(results), results)
}
- // remember the record and zone we got so we can clean up more efficiently
- s.saveDNSPresentMemory(dnsPresentMemory{
- dnsZone: zone,
- dnsName: dnsName,
- rec: results[0],
- })
-
- return nil
+ return zoneRecord{zone, results[0]}, nil
}
-// Wait blocks until the TXT record created in Present() appears in
+// wait blocks until the TXT record created in Present() appears in
// authoritative lookups, i.e. until it has propagated, or until
// timeout, whichever is first.
-func (s *DNS01Solver) Wait(ctx context.Context, challenge acme.Challenge) error {
+func (m *DNSManager) wait(ctx context.Context, zrec zoneRecord) error {
+ logger := m.logger()
+
// if configured to, pause before doing propagation checks
// (even if they are disabled, the wait might be desirable on its own)
- if s.PropagationDelay > 0 {
+ if m.PropagationDelay > 0 {
select {
- case <-time.After(s.PropagationDelay):
+ case <-time.After(m.PropagationDelay):
case <-ctx.Done():
return ctx.Err()
}
}
// skip propagation checks if configured to do so
- if s.PropagationTimeout == -1 {
+ if m.PropagationTimeout == -1 {
return nil
}
- // prepare for the checks by determining what to look for
- dnsName := challenge.DNS01TXTRecordName()
- if s.OverrideDomain != "" {
- dnsName = s.OverrideDomain
- }
- keyAuth := challenge.DNS01KeyAuthorization()
-
// timings
- timeout := s.PropagationTimeout
+ timeout := m.PropagationTimeout
if timeout == 0 {
timeout = defaultDNSPropagationTimeout
}
const interval = 2 * time.Second
// how we'll do the checks
- resolvers := recursiveNameservers(s.Resolvers)
+ checkAuthoritativeServers := len(m.Resolvers) == 0
+ resolvers := recursiveNameservers(m.Resolvers)
+
+ recType := dns.TypeTXT
+ if zrec.record.Type == "CNAME" {
+ recType = dns.TypeCNAME
+ }
+
+ absName := libdns.AbsoluteName(zrec.record.Name, zrec.zone)
var err error
start := time.Now()
@@ -371,10 +456,17 @@ func (s *DNS01Solver) Wait(ctx context.Context, challenge acme.Challenge) error
case <-ctx.Done():
return ctx.Err()
}
+
+ logger.Debug("checking DNS propagation",
+ zap.String("fqdn", absName),
+ zap.String("record_type", zrec.record.Type),
+ zap.String("expected_value", zrec.record.Value),
+ zap.Strings("resolvers", resolvers))
+
var ready bool
- ready, err = checkDNSPropagation(dnsName, keyAuth, resolvers)
+ ready, err = checkDNSPropagation(logger, absName, recType, zrec.record.Value, checkAuthoritativeServers, resolvers)
if err != nil {
- return fmt.Errorf("checking DNS propagation of %q: %w", dnsName, err)
+ return fmt.Errorf("checking DNS propagation of %q (relative=%s zone=%s resolvers=%v): %w", absName, zrec.record.Name, zrec.zone, resolvers, err)
}
if ready {
return nil
@@ -384,101 +476,110 @@ func (s *DNS01Solver) Wait(ctx context.Context, challenge acme.Challenge) error
return fmt.Errorf("timed out waiting for record to fully propagate; verify DNS provider configuration is correct - last error: %v", err)
}
+type zoneRecord struct {
+ zone string
+ record libdns.Record
+}
+
// CleanUp deletes the DNS TXT record created in Present().
//
// We ignore the context because cleanup is often/likely performed after
// a context cancellation, and properly-implemented DNS providers should
// honor cancellation, which would result in cleanup being aborted.
// Cleanup must always occur.
-func (s *DNS01Solver) CleanUp(_ context.Context, challenge acme.Challenge) error {
- dnsName := challenge.DNS01TXTRecordName()
- if s.OverrideDomain != "" {
- dnsName = s.OverrideDomain
- }
- keyAuth := challenge.DNS01KeyAuthorization()
-
- // always forget about the record so we don't leak memory
- defer s.deleteDNSPresentMemory(dnsName, keyAuth)
-
- // recall the record we created and zone we looked up
- memory, err := s.getDNSPresentMemory(dnsName, keyAuth)
- if err != nil {
- return err
- }
+func (m *DNSManager) cleanUpRecord(_ context.Context, zrec zoneRecord) error {
+ logger := m.logger()
// clean up the record - use a different context though, since
// one common reason cleanup is performed is because a context
// was canceled, and if so, any HTTP requests by this provider
// should fail if the provider is properly implemented
// (see issue #200)
- timeout := s.PropagationTimeout
+ timeout := m.PropagationTimeout
if timeout <= 0 {
timeout = defaultDNSPropagationTimeout
}
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
- _, err = s.DNSProvider.DeleteRecords(ctx, memory.dnsZone, []libdns.Record{memory.rec})
- if err != nil {
- return fmt.Errorf("deleting temporary record for name %q in zone %q: %w", memory.dnsName, memory.dnsZone, err)
- }
+ logger.Debug("deleting DNS record",
+ zap.String("zone", zrec.zone),
+ zap.String("record_id", zrec.record.ID),
+ zap.String("record_name", zrec.record.Name),
+ zap.String("record_type", zrec.record.Type),
+ zap.String("record_value", zrec.record.Value))
+
+ _, err := m.DNSProvider.DeleteRecords(ctx, zrec.zone, []libdns.Record{zrec.record})
+ if err != nil {
+ return fmt.Errorf("deleting temporary record for name %q in zone %q: %w", zrec.zone, zrec.record, err)
+ }
return nil
}
+func (m *DNSManager) logger() *zap.Logger {
+ logger := m.Logger
+ if logger == nil {
+ logger = zap.NewNop()
+ }
+ return logger.Named("dns_manager")
+}
+
const defaultDNSPropagationTimeout = 2 * time.Minute
+// dnsPresentMemory associates a created DNS record with its zone
+// (since libdns Records are zone-relative and do not include zone).
type dnsPresentMemory struct {
- dnsZone string
dnsName string
- rec libdns.Record
+ zoneRec zoneRecord
}
-func (s *DNS01Solver) saveDNSPresentMemory(mem dnsPresentMemory) {
- s.txtRecordsMu.Lock()
- if s.txtRecords == nil {
- s.txtRecords = make(map[string][]dnsPresentMemory)
+func (s *DNSManager) saveDNSPresentMemory(mem dnsPresentMemory) {
+ s.recordsMu.Lock()
+ if s.records == nil {
+ s.records = make(map[string][]dnsPresentMemory)
}
- s.txtRecords[mem.dnsName] = append(s.txtRecords[mem.dnsName], mem)
- s.txtRecordsMu.Unlock()
+ s.records[mem.dnsName] = append(s.records[mem.dnsName], mem)
+ s.recordsMu.Unlock()
}
-func (s *DNS01Solver) getDNSPresentMemory(dnsName, keyAuth string) (dnsPresentMemory, error) {
- s.txtRecordsMu.Lock()
- defer s.txtRecordsMu.Unlock()
+func (s *DNSManager) getDNSPresentMemory(dnsName, recType, value string) (dnsPresentMemory, error) {
+ s.recordsMu.Lock()
+ defer s.recordsMu.Unlock()
var memory dnsPresentMemory
- for _, mem := range s.txtRecords[dnsName] {
- if mem.rec.Value == keyAuth {
+ for _, mem := range s.records[dnsName] {
+ if mem.zoneRec.record.Type == recType && mem.zoneRec.record.Value == value {
memory = mem
break
}
}
- if memory.rec.Name == "" {
+ if memory.zoneRec.record.Name == "" {
return dnsPresentMemory{}, fmt.Errorf("no memory of presenting a DNS record for %q (usually OK if presenting also failed)", dnsName)
}
return memory, nil
}
-func (s *DNS01Solver) deleteDNSPresentMemory(dnsName, keyAuth string) {
- s.txtRecordsMu.Lock()
- defer s.txtRecordsMu.Unlock()
+func (s *DNSManager) deleteDNSPresentMemory(dnsName, keyAuth string) {
+ s.recordsMu.Lock()
+ defer s.recordsMu.Unlock()
- for i, mem := range s.txtRecords[dnsName] {
- if mem.rec.Value == keyAuth {
- s.txtRecords[dnsName] = append(s.txtRecords[dnsName][:i], s.txtRecords[dnsName][i+1:]...)
+ for i, mem := range s.records[dnsName] {
+ if mem.zoneRec.record.Value == keyAuth {
+ s.records[dnsName] = append(s.records[dnsName][:i], s.records[dnsName][i+1:]...)
return
}
}
}
-// ACMEDNSProvider defines the set of operations required for
-// ACME challenges. A DNS provider must be able to append and
-// delete records in order to solve ACME challenges. Find one
-// you can use at https://github.com/libdns. If your provider
-// isn't implemented yet, feel free to contribute!
-type ACMEDNSProvider interface {
+// DNSProvider defines the set of operations required for
+// ACME challenges or other sorts of domain verification.
+// A DNS provider must be able to append and delete records
+// in order to solve ACME challenges. Find one you can use
+// at https://github.com/libdns. If your provider isn't
+// implemented yet, feel free to contribute!
+type DNSProvider interface {
libdns.RecordAppender
libdns.RecordDeleter
}
diff --git a/vendor/github.com/caddyserver/certmagic/storage.go b/vendor/github.com/caddyserver/certmagic/storage.go
index 3d88f2e0..faf73153 100644
--- a/vendor/github.com/caddyserver/certmagic/storage.go
+++ b/vendor/github.com/caddyserver/certmagic/storage.go
@@ -289,7 +289,7 @@ func acquireLock(ctx context.Context, storage Storage, lockKey string) error {
}
func releaseLock(ctx context.Context, storage Storage, lockKey string) error {
- err := storage.Unlock(context.TODO(), lockKey) // TODO: in Go 1.21, use WithoutCancel (see #247)
+ err := storage.Unlock(context.WithoutCancel(ctx), lockKey)
if err == nil {
locksMu.Lock()
delete(locks, lockKey)
diff --git a/vendor/github.com/caddyserver/certmagic/zerosslissuer.go b/vendor/github.com/caddyserver/certmagic/zerosslissuer.go
new file mode 100644
index 00000000..b9ffa7d7
--- /dev/null
+++ b/vendor/github.com/caddyserver/certmagic/zerosslissuer.go
@@ -0,0 +1,304 @@
+// Copyright 2015 Matthew Holt
+//
+// 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 certmagic
+
+import (
+ "context"
+ "crypto/x509"
+ "encoding/json"
+ "fmt"
+ "net"
+ "net/http"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/caddyserver/zerossl"
+ "github.com/mholt/acmez/v2"
+ "github.com/mholt/acmez/v2/acme"
+ "go.uber.org/zap"
+)
+
+// ZeroSSLIssuer can get certificates from ZeroSSL's API. (To use ZeroSSL's ACME
+// endpoint, use the ACMEIssuer instead.) Note that use of the API is restricted
+// by payment tier.
+type ZeroSSLIssuer struct {
+ // The API key (or "access key") for using the ZeroSSL API.
+ // REQUIRED.
+ APIKey string
+
+ // How many days the certificate should be valid for.
+ ValidityDays int
+
+ // The host to bind to when opening a listener for
+ // verifying domain names (or IPs).
+ ListenHost string
+
+ // If HTTP is forwarded from port 80, specify the
+ // forwarded port here.
+ AltHTTPPort int
+
+ // To use CNAME validation instead of HTTP
+ // validation, set this field.
+ CNAMEValidation *DNSManager
+
+ // Where to store verification material temporarily.
+ // Set this on all instances in a cluster to the same
+ // value to enable distributed verification.
+ Storage Storage
+
+ // An optional (but highly recommended) logger.
+ Logger *zap.Logger
+}
+
+// Issue obtains a certificate for the given csr.
+func (iss *ZeroSSLIssuer) Issue(ctx context.Context, csr *x509.CertificateRequest) (*IssuedCertificate, error) {
+ client := iss.getClient()
+
+ identifiers := namesFromCSR(csr)
+ if len(identifiers) == 0 {
+ return nil, fmt.Errorf("no identifiers on CSR")
+ }
+
+ logger := iss.Logger
+ if logger == nil {
+ logger = zap.NewNop()
+ }
+ logger = logger.With(zap.Strings("identifiers", identifiers))
+
+ logger.Info("creating certificate")
+
+ cert, err := client.CreateCertificate(ctx, csr, iss.ValidityDays)
+ if err != nil {
+ return nil, fmt.Errorf("creating certificate: %v", err)
+ }
+
+ logger = logger.With(zap.String("cert_id", cert.ID))
+ logger.Info("created certificate")
+
+ defer func(certID string) {
+ if err != nil {
+ err := client.CancelCertificate(context.WithoutCancel(ctx), certID)
+ if err == nil {
+ logger.Info("canceled certificate")
+ } else {
+ logger.Error("unable to cancel certificate", zap.Error(err))
+ }
+ }
+ }(cert.ID)
+
+ var verificationMethod zerossl.VerificationMethod
+
+ if iss.CNAMEValidation == nil {
+ verificationMethod = zerossl.HTTPVerification
+ logger = logger.With(zap.String("verification_method", string(verificationMethod)))
+
+ httpVerifier := &httpSolver{
+ address: net.JoinHostPort(iss.ListenHost, strconv.Itoa(iss.getHTTPPort())),
+ handler: iss.HTTPValidationHandler(http.NewServeMux()),
+ }
+
+ var solver acmez.Solver = httpVerifier
+ if iss.Storage != nil {
+ solver = distributedSolver{
+ storage: iss.Storage,
+ storageKeyIssuerPrefix: iss.IssuerKey(),
+ solver: httpVerifier,
+ }
+ }
+
+ // since the distributed solver was originally designed for ACME,
+ // the API is geared around ACME challenges. ZeroSSL's HTTP validation
+ // is very similar to the HTTP challenge, but not quite compatible,
+ // so we kind of shim the ZeroSSL validation data into a Challenge
+ // object... it is not a perfect use of this type but it's pretty close
+ valInfo := cert.Validation.OtherMethods[identifiers[0]]
+ fakeChallenge := acme.Challenge{
+ Identifier: acme.Identifier{
+ Value: identifiers[0], // used for storage key
+ },
+ URL: valInfo.FileValidationURLHTTP,
+ Token: strings.Join(cert.Validation.OtherMethods[identifiers[0]].FileValidationContent, "\n"),
+ }
+ if err = solver.Present(ctx, fakeChallenge); err != nil {
+ return nil, fmt.Errorf("presenting validation file for verification: %v", err)
+ }
+ defer solver.CleanUp(ctx, fakeChallenge)
+ } else {
+ verificationMethod = zerossl.CNAMEVerification
+ logger = logger.With(zap.String("verification_method", string(verificationMethod)))
+
+ // create the CNAME record(s)
+ records := make(map[string]zoneRecord, len(cert.Validation.OtherMethods))
+ for name, verifyInfo := range cert.Validation.OtherMethods {
+ zr, err := iss.CNAMEValidation.createRecord(ctx, verifyInfo.CnameValidationP1, "CNAME", verifyInfo.CnameValidationP2)
+ if err != nil {
+ return nil, fmt.Errorf("creating CNAME record: %v", err)
+ }
+ defer func(name string, zr zoneRecord) {
+ if err := iss.CNAMEValidation.cleanUpRecord(ctx, zr); err != nil {
+ logger.Warn("cleaning up temporary validation record failed",
+ zap.String("dns_name", name),
+ zap.Error(err))
+ }
+ }(name, zr)
+ records[name] = zr
+ }
+
+ // wait for them to propagate
+ for name, zr := range records {
+ if err := iss.CNAMEValidation.wait(ctx, zr); err != nil {
+ // allow it, since the CA will ultimately decide, but definitely log it
+ logger.Warn("failed CNAME record propagation check", zap.String("domain", name), zap.Error(err))
+ }
+ }
+ }
+
+ logger.Info("validating identifiers")
+
+ cert, err = client.VerifyIdentifiers(ctx, cert.ID, verificationMethod, nil)
+ if err != nil {
+ return nil, fmt.Errorf("verifying identifiers: %v", err)
+ }
+
+ switch cert.Status {
+ case "pending_validation":
+ logger.Info("validations succeeded; waiting for certificate to be issued")
+
+ cert, err = iss.waitForCertToBeIssued(ctx, client, cert)
+ if err != nil {
+ return nil, fmt.Errorf("waiting for certificate to be issued: %v", err)
+ }
+ case "issued":
+ logger.Info("validations succeeded; downloading certificate bundle")
+ default:
+ return nil, fmt.Errorf("unexpected certificate status: %s", cert.Status)
+ }
+
+ bundle, err := client.DownloadCertificate(ctx, cert.ID, false)
+ if err != nil {
+ return nil, fmt.Errorf("downloading certificate: %v", err)
+ }
+
+ logger.Info("successfully downloaded issued certificate")
+
+ return &IssuedCertificate{
+ Certificate: []byte(bundle.CertificateCrt + bundle.CABundleCrt),
+ Metadata: cert,
+ }, nil
+}
+
+func (*ZeroSSLIssuer) waitForCertToBeIssued(ctx context.Context, client zerossl.Client, cert zerossl.CertificateObject) (zerossl.CertificateObject, error) {
+ ticker := time.NewTicker(5 * time.Second)
+ defer ticker.Stop()
+
+ for {
+ select {
+ case <-ctx.Done():
+ return cert, ctx.Err()
+ case <-ticker.C:
+ var err error
+ cert, err = client.GetCertificate(ctx, cert.ID)
+ if err != nil {
+ return cert, err
+ }
+ if cert.Status == "issued" {
+ return cert, nil
+ }
+ if cert.Status != "pending_validation" {
+ return cert, fmt.Errorf("unexpected certificate status: %s", cert.Status)
+ }
+ }
+ }
+}
+
+func (iss *ZeroSSLIssuer) getClient() zerossl.Client {
+ return zerossl.Client{AccessKey: iss.APIKey}
+}
+
+func (iss *ZeroSSLIssuer) getHTTPPort() int {
+ useHTTPPort := HTTPChallengePort
+ if HTTPPort > 0 && HTTPPort != HTTPChallengePort {
+ useHTTPPort = HTTPPort
+ }
+ if iss.AltHTTPPort > 0 {
+ useHTTPPort = iss.AltHTTPPort
+ }
+ return useHTTPPort
+}
+
+// IssuerKey returns the unique issuer key for ZeroSSL.
+func (iss *ZeroSSLIssuer) IssuerKey() string { return zerosslIssuerKey }
+
+// Revoke revokes the given certificate. Only do this if there is a security or trust
+// concern with the certificate.
+func (iss *ZeroSSLIssuer) Revoke(ctx context.Context, cert CertificateResource, reason int) error {
+ r := zerossl.UnspecifiedReason
+ switch reason {
+ case acme.ReasonKeyCompromise:
+ r = zerossl.KeyCompromise
+ case acme.ReasonAffiliationChanged:
+ r = zerossl.AffiliationChanged
+ case acme.ReasonSuperseded:
+ r = zerossl.Superseded
+ case acme.ReasonCessationOfOperation:
+ r = zerossl.CessationOfOperation
+ default:
+ return fmt.Errorf("unsupported reason: %d", reason)
+ }
+ var certObj zerossl.CertificateObject
+ if err := json.Unmarshal(cert.IssuerData, &certObj); err != nil {
+ return err
+ }
+ return iss.getClient().RevokeCertificate(ctx, certObj.ID, r)
+}
+
+func (iss *ZeroSSLIssuer) getDistributedValidationInfo(ctx context.Context, identifier string) (acme.Challenge, bool, error) {
+ ds := distributedSolver{
+ storage: iss.Storage,
+ storageKeyIssuerPrefix: StorageKeys.Safe(iss.IssuerKey()),
+ }
+ tokenKey := ds.challengeTokensKey(identifier)
+
+ valObjectBytes, err := iss.Storage.Load(ctx, tokenKey)
+ if err != nil {
+ return acme.Challenge{}, false, fmt.Errorf("opening distributed challenge token file %s: %v", tokenKey, err)
+ }
+
+ if len(valObjectBytes) == 0 {
+ return acme.Challenge{}, false, fmt.Errorf("no information found to solve challenge for identifier: %s", identifier)
+ }
+
+ // since the distributed solver's API is geared around ACME challenges,
+ // we crammed the validation info into a Challenge object
+ var chal acme.Challenge
+ if err = json.Unmarshal(valObjectBytes, &chal); err != nil {
+ return acme.Challenge{}, false, fmt.Errorf("decoding HTTP validation token file %s (corrupted?): %v", tokenKey, err)
+ }
+
+ return chal, true, nil
+}
+
+const (
+ zerosslAPIBase = "https://" + zerossl.BaseURL + "/acme"
+ zerosslValidationPathPrefix = "/.well-known/pki-validation/"
+ zerosslIssuerKey = "zerossl"
+)
+
+// Interface guards
+var (
+ _ Issuer = (*ZeroSSLIssuer)(nil)
+ _ Revoker = (*ZeroSSLIssuer)(nil)
+)
diff --git a/vendor/github.com/caddyserver/zerossl/.gitignore b/vendor/github.com/caddyserver/zerossl/.gitignore
new file mode 100644
index 00000000..9daa723c
--- /dev/null
+++ b/vendor/github.com/caddyserver/zerossl/.gitignore
@@ -0,0 +1,2 @@
+_gitignore
+.DS_Store
\ No newline at end of file
diff --git a/vendor/github.com/caddyserver/zerossl/LICENSE b/vendor/github.com/caddyserver/zerossl/LICENSE
new file mode 100644
index 00000000..ef526264
--- /dev/null
+++ b/vendor/github.com/caddyserver/zerossl/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 Matthew Holt
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/vendor/github.com/caddyserver/zerossl/README.md b/vendor/github.com/caddyserver/zerossl/README.md
new file mode 100644
index 00000000..a50a82ad
--- /dev/null
+++ b/vendor/github.com/caddyserver/zerossl/README.md
@@ -0,0 +1,6 @@
+ZeroSSL API client [](https://pkg.go.dev/github.com/caddyserver/zerossl)
+==================
+
+This package implements the [ZeroSSL REST API](https://zerossl.com/documentation/api/) in Go.
+
+The REST API is distinct from the [ACME endpoint](https://zerossl.com/documentation/acme/), which is a standardized way of obtaining certificates.
diff --git a/vendor/github.com/caddyserver/zerossl/client.go b/vendor/github.com/caddyserver/zerossl/client.go
new file mode 100644
index 00000000..75a3de77
--- /dev/null
+++ b/vendor/github.com/caddyserver/zerossl/client.go
@@ -0,0 +1,170 @@
+package zerossl
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "strings"
+ "time"
+)
+
+// Client acts as a ZeroSSL API client. It facilitates ZeroSSL certificate operations.
+type Client struct {
+ // REQUIRED: Your ZeroSSL account access key.
+ AccessKey string `json:"access_key"`
+
+ // Optionally adjust the base URL of the API.
+ // Default: https://api.zerossl.com
+ BaseURL string `json:"base_url,omitempty"`
+
+ // Optionally configure a custom HTTP client.
+ HTTPClient *http.Client `json:"-"`
+}
+
+func (c Client) httpGet(ctx context.Context, endpoint string, qs url.Values, target any) error {
+ url := c.url(endpoint, qs)
+ return c.httpRequest(ctx, http.MethodGet, url, nil, target)
+}
+
+func (c Client) httpPost(ctx context.Context, endpoint string, qs url.Values, payload, target any) error {
+ var reqBody io.Reader
+ if payload != nil {
+ payloadJSON, err := json.Marshal(payload)
+ if err != nil {
+ return err
+ }
+ reqBody = bytes.NewReader(payloadJSON)
+ }
+ url := c.url(endpoint, qs)
+ return c.httpRequest(ctx, http.MethodPost, url, reqBody, target)
+}
+
+func (c Client) httpRequest(ctx context.Context, method, reqURL string, reqBody io.Reader, target any) error {
+ r, err := http.NewRequestWithContext(ctx, method, reqURL, reqBody)
+ if err != nil {
+ return err
+ }
+ if reqBody != nil {
+ r.Header.Set("Content-Type", "application/json")
+ }
+
+ resp, err := c.httpClient().Do(r)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ // because the ZeroSSL API doesn't use HTTP status codes to indicate an error,
+ // nor does each response body have a consistent way of detecting success/error,
+ // we have to implement a hack: download the entire response body and try
+ // decoding it as JSON in a way that errors if there's any unknown fields
+ // (such as "success"), because if there is an unkown field, either our model
+ // is outdated, or there was an error payload in the response instead of the
+ // expected structure, so we then try again to decode to an error struct
+ respBytes, err := io.ReadAll(io.LimitReader(resp.Body, 1024*1024*2))
+ if err != nil {
+ return fmt.Errorf("failed reading response body: %v", err)
+ }
+
+ // assume success first by trying to decode payload into output target
+ dec := json.NewDecoder(bytes.NewReader(respBytes))
+ dec.DisallowUnknownFields() // important hacky hack so we can detect an error payload
+ originalDecodeErr := dec.Decode(&target)
+ if originalDecodeErr == nil {
+ return nil
+ }
+
+ // could have gotten any kind of error, really; but assuming valid JSON,
+ // most likely it is an error payload
+ var apiError APIError
+ if err := json.NewDecoder(bytes.NewReader(respBytes)).Decode(&apiError); err != nil {
+ return fmt.Errorf("request succeeded, but decoding JSON response failed: %v (raw=%s)", err, respBytes)
+ }
+
+ // successfully got an error! or did we?
+ if apiError.Success {
+ return apiError // ummm... why are we getting an error if it was successful ??? is this not really an error?
+ }
+
+ // remove access_key from URL so it doesn't leak into logs
+ u, err := url.Parse(reqURL)
+ if err != nil {
+ reqURL = fmt.Sprintf("", err)
+ }
+ if u != nil {
+ q, err := url.ParseQuery(u.RawQuery)
+ if err == nil {
+ q.Set(accessKeyParam, "redacted")
+ u.RawQuery = q.Encode()
+ reqURL = u.String()
+ }
+ }
+
+ return fmt.Errorf("%s %s: HTTP %d: %v (raw=%s decode_error=%v)", method, reqURL, resp.StatusCode, apiError, respBytes, originalDecodeErr)
+}
+
+func (c Client) url(endpoint string, qs url.Values) string {
+ baseURL := c.BaseURL
+ if baseURL == "" {
+ baseURL = BaseURL
+ }
+
+ // for consistency, ensure endpoint starts with /
+ // and base URL does NOT end with /.
+ if !strings.HasPrefix(endpoint, "/") {
+ endpoint = "/" + endpoint
+ }
+ baseURL = strings.TrimSuffix(baseURL, "/")
+
+ if qs == nil {
+ qs = url.Values{}
+ }
+ qs.Set(accessKeyParam, c.AccessKey)
+
+ return fmt.Sprintf("%s%s?%s", baseURL, endpoint, qs.Encode())
+}
+
+func (c Client) httpClient() *http.Client {
+ if c.HTTPClient != nil {
+ return c.HTTPClient
+ }
+ return httpClient
+}
+
+var httpClient = &http.Client{
+ Timeout: 2 * time.Minute,
+}
+
+// anyBool is a hacky type that accepts true or 1 (or their string variants),
+// or "yes" or "y", and any casing variants of the same, as a boolean true when
+// unmarshaling JSON. Everything else is boolean false.
+//
+// This is needed due to type inconsistencies in ZeroSSL's API with "success" values.
+type anyBool bool
+
+// UnmarshalJSON satisfies json.Unmarshaler according to
+// this type's documentation.
+func (ab *anyBool) UnmarshalJSON(b []byte) error {
+ if len(b) == 0 {
+ return io.EOF
+ }
+ switch strings.ToLower(string(b)) {
+ case `true`, `"true"`, `1`, `"1"`, `"yes"`, `"y"`:
+ *ab = true
+ }
+ return nil
+}
+
+// MarshalJSON marshals ab to either true or false.
+func (ab *anyBool) MarshalJSON() ([]byte, error) {
+ if ab != nil && *ab {
+ return []byte("true"), nil
+ }
+ return []byte("false"), nil
+}
+
+const accessKeyParam = "access_key"
diff --git a/vendor/github.com/caddyserver/zerossl/endpoints.go b/vendor/github.com/caddyserver/zerossl/endpoints.go
new file mode 100644
index 00000000..3fabd44a
--- /dev/null
+++ b/vendor/github.com/caddyserver/zerossl/endpoints.go
@@ -0,0 +1,270 @@
+package zerossl
+
+import (
+ "context"
+ "crypto/x509"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "strconv"
+ "strings"
+)
+
+// CreateCertificate creates a certificate. After creating a certificate, its identifiers must be verified before
+// the certificate can be downloaded. The CSR must have been fully created using x509.CreateCertificateRequest
+// (its Raw field must be filled out).
+func (c Client) CreateCertificate(ctx context.Context, csr *x509.CertificateRequest, validityDays int) (CertificateObject, error) {
+ payload := struct {
+ CertificateDomains string `json:"certificate_domains"`
+ CertificateCSR string `json:"certificate_csr"`
+ CertificateValidityDays int `json:"certificate_validity_days,omitempty"`
+ StrictDomains int `json:"strict_domains,omitempty"`
+ ReplacementForCertificate string `json:"replacement_for_certificate,omitempty"`
+ }{
+ CertificateDomains: strings.Join(identifiersFromCSR(csr), ","),
+ CertificateCSR: csr2pem(csr.Raw),
+ CertificateValidityDays: validityDays,
+ StrictDomains: 1,
+ }
+
+ var result CertificateObject
+ if err := c.httpPost(ctx, "/certificates", nil, payload, &result); err != nil {
+ return CertificateObject{}, err
+ }
+
+ return result, nil
+}
+
+// VerifyIdentifiers tells ZeroSSL that you are ready to prove control over your domain/IP using the method specified.
+// The credentials from CreateCertificate must be used to verify identifiers. At least one email is required if using
+// email verification method.
+func (c Client) VerifyIdentifiers(ctx context.Context, certificateID string, method VerificationMethod, emails []string) (CertificateObject, error) {
+ payload := struct {
+ ValidationMethod VerificationMethod `json:"validation_method"`
+ ValidationEmail string `json:"validation_email,omitempty"`
+ }{
+ ValidationMethod: method,
+ }
+ if method == EmailVerification && len(emails) > 0 {
+ payload.ValidationEmail = strings.Join(emails, ",")
+ }
+
+ endpoint := fmt.Sprintf("/certificates/%s/challenges", url.QueryEscape(certificateID))
+
+ var result CertificateObject
+ if err := c.httpPost(ctx, endpoint, nil, payload, &result); err != nil {
+ return CertificateObject{}, err
+ }
+
+ return result, nil
+}
+
+// DownloadCertificateFile writes the certificate bundle as a zip file to the provided output writer.
+func (c Client) DownloadCertificateFile(ctx context.Context, certificateID string, includeCrossSigned bool, output io.Writer) error {
+ endpoint := fmt.Sprintf("/certificates/%s/download", url.QueryEscape(certificateID))
+
+ qs := url.Values{}
+ if includeCrossSigned {
+ qs.Set("include_cross_signed", "1")
+ }
+
+ url := c.url(endpoint, qs)
+ r, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
+ if err != nil {
+ return err
+ }
+
+ resp, err := c.httpClient().Do(r)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != http.StatusOK {
+ return fmt.Errorf("unexpected status code: HTTP %d", resp.StatusCode)
+ }
+
+ if _, err := io.Copy(output, resp.Body); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (c Client) DownloadCertificate(ctx context.Context, certificateID string, includeCrossSigned bool) (CertificateBundle, error) {
+ endpoint := fmt.Sprintf("/certificates/%s/download/return", url.QueryEscape(certificateID))
+
+ qs := url.Values{}
+ if includeCrossSigned {
+ qs.Set("include_cross_signed", "1")
+ }
+
+ var result CertificateBundle
+ if err := c.httpGet(ctx, endpoint, qs, &result); err != nil {
+ return CertificateBundle{}, err
+ }
+
+ return result, nil
+}
+
+func (c Client) GetCertificate(ctx context.Context, certificateID string) (CertificateObject, error) {
+ endpoint := fmt.Sprintf("/certificates/%s", url.QueryEscape(certificateID))
+
+ var result CertificateObject
+ if err := c.httpGet(ctx, endpoint, nil, &result); err != nil {
+ return CertificateObject{}, err
+ }
+
+ return result, nil
+}
+
+// ListCertificateParameters specifies how to search or list certificates on the account.
+// An empty set of parameters will return no results.
+type ListCertificatesParameters struct {
+ // Return certificates with this status.
+ Status string
+
+ // Return these types of certificates.
+ Type string
+
+ // The CommonName or SAN.
+ Search string
+
+ // The page number. Default: 1
+ Page int
+
+ // How many per page. Default: 100
+ Limit int
+}
+
+func (c Client) ListCertificates(ctx context.Context, params ListCertificatesParameters) (CertificateList, error) {
+ qs := url.Values{}
+ if params.Status != "" {
+ qs.Set("certificate_status", params.Status)
+ }
+ if params.Type != "" {
+ qs.Set("certificate_type", params.Type)
+ }
+ if params.Search != "" {
+ qs.Set("search", params.Search)
+ }
+ if params.Limit != 0 {
+ qs.Set("limit", strconv.Itoa(params.Limit))
+ }
+ if params.Page != 0 {
+ qs.Set("page", strconv.Itoa(params.Page))
+ }
+
+ var result CertificateList
+ if err := c.httpGet(ctx, "/certificates", qs, &result); err != nil {
+ return CertificateList{}, err
+ }
+
+ return result, nil
+}
+
+func (c Client) VerificationStatus(ctx context.Context, certificateID string) (ValidationStatus, error) {
+ endpoint := fmt.Sprintf("/certificates/%s/status", url.QueryEscape(certificateID))
+
+ var result ValidationStatus
+ if err := c.httpGet(ctx, endpoint, nil, &result); err != nil {
+ return ValidationStatus{}, err
+ }
+
+ return result, nil
+}
+
+func (c Client) ResendVerificationEmail(ctx context.Context, certificateID string) error {
+ endpoint := fmt.Sprintf("/certificates/%s/challenges/email", url.QueryEscape(certificateID))
+
+ var result struct {
+ Success anyBool `json:"success"`
+ }
+ if err := c.httpGet(ctx, endpoint, nil, &result); err != nil {
+ return err
+ }
+
+ if !result.Success {
+ return fmt.Errorf("got %v without any error status", result)
+ }
+
+ return nil
+}
+
+// Only revoke a certificate if the private key is compromised, the certificate was a mistake, or
+// the identifiers are no longer in use. Do not revoke a certificate when renewing it.
+func (c Client) RevokeCertificate(ctx context.Context, certificateID string, reason RevocationReason) error {
+ endpoint := fmt.Sprintf("/certificates/%s/revoke", url.QueryEscape(certificateID))
+
+ qs := url.Values{"reason": []string{string(reason)}}
+
+ var result struct {
+ Success anyBool `json:"success"`
+ }
+ if err := c.httpGet(ctx, endpoint, qs, &result); err != nil {
+ return err
+ }
+
+ if !result.Success {
+ return fmt.Errorf("got %v without any error status", result)
+ }
+
+ return nil
+}
+
+// CancelCertificate cancels a certificate that has not been issued yet (is in draft or pending_validation state).
+func (c Client) CancelCertificate(ctx context.Context, certificateID string) error {
+ endpoint := fmt.Sprintf("/certificates/%s/cancel", url.QueryEscape(certificateID))
+
+ var result struct {
+ Success anyBool `json:"success"`
+ }
+ if err := c.httpPost(ctx, endpoint, nil, nil, &result); err != nil {
+ return err
+ }
+
+ if !result.Success {
+ return fmt.Errorf("got %v without any error status", result)
+ }
+
+ return nil
+}
+
+// ValidateCSR sends the CSR to ZeroSSL for validation. Pass in the ASN.1 DER-encoded bytes;
+// this is found in x509.CertificateRequest.Raw after calling x5p9.CreateCertificateRequest.
+func (c Client) ValidateCSR(ctx context.Context, csrASN1DER []byte) error {
+ payload := struct {
+ CSR string `json:"csr"`
+ }{
+ CSR: csr2pem(csrASN1DER),
+ }
+
+ var result struct {
+ Valid bool `json:"valid"`
+ Error any `json:"error"`
+ }
+ if err := c.httpPost(ctx, "/validation/csr", nil, payload, &result); err != nil {
+ return err
+ }
+
+ if !result.Valid {
+ return fmt.Errorf("invalid CSR: %v", result.Error)
+ }
+ return nil
+}
+
+func (c Client) GenerateEABCredentials(ctx context.Context) (keyID, hmacKey string, err error) {
+ var result struct {
+ APIError
+ EABKID string `json:"eab_kid"`
+ EABHMACKey string `json:"eab_hmac_key"`
+ }
+ err = c.httpPost(ctx, "/acme/eab-credentials", nil, nil, &result)
+ if err != nil {
+ return
+ }
+ if !result.Success {
+ err = fmt.Errorf("failed to create EAB credentials: %v", result.APIError)
+ }
+ return result.EABKID, result.EABHMACKey, err
+}
diff --git a/vendor/github.com/caddyserver/zerossl/models.go b/vendor/github.com/caddyserver/zerossl/models.go
new file mode 100644
index 00000000..80475f0e
--- /dev/null
+++ b/vendor/github.com/caddyserver/zerossl/models.go
@@ -0,0 +1,94 @@
+package zerossl
+
+import "fmt"
+
+type APIError struct {
+ Success anyBool `json:"success"`
+ ErrorInfo struct {
+ Code int `json:"code"`
+ Type string `json:"type"`
+
+ // for domain verification only; each domain is grouped into its
+ // www and non-www variant for CNAME validation, or its URL
+ // for HTTP validation
+ Details map[string]map[string]ValidationError `json:"details"`
+ } `json:"error"`
+}
+
+func (ae APIError) Error() string {
+ if ae.ErrorInfo.Code == 0 && ae.ErrorInfo.Type == "" && len(ae.ErrorInfo.Details) == 0 {
+ return ""
+ }
+ return fmt.Sprintf("API error %d: %s (details=%v)",
+ ae.ErrorInfo.Code, ae.ErrorInfo.Type, ae.ErrorInfo.Details)
+}
+
+type ValidationError struct {
+ CNAMEValidationError
+ HTTPValidationError
+}
+
+type CNAMEValidationError struct {
+ CNAMEFound int `json:"cname_found"`
+ RecordCorrect int `json:"record_correct"`
+ TargetHost string `json:"target_host"`
+ TargetRecord string `json:"target_record"`
+ ActualRecord string `json:"actual_record"`
+}
+
+type HTTPValidationError struct {
+ FileFound int `json:"file_found"`
+ Error bool `json:"error"`
+ ErrorSlug string `json:"error_slug"`
+ ErrorInfo string `json:"error_info"`
+}
+
+type CertificateObject struct {
+ ID string `json:"id"` // "certificate hash"
+ Type string `json:"type"`
+ CommonName string `json:"common_name"`
+ AdditionalDomains string `json:"additional_domains"`
+ Created string `json:"created"`
+ Expires string `json:"expires"`
+ Status string `json:"status"`
+ ValidationType *string `json:"validation_type,omitempty"`
+ ValidationEmails *string `json:"validation_emails,omitempty"`
+ ReplacementFor string `json:"replacement_for,omitempty"`
+ FingerprintSHA1 *string `json:"fingerprint_sha1"`
+ BrandValidation any `json:"brand_validation"`
+ Validation *struct {
+ EmailValidation map[string][]string `json:"email_validation,omitempty"`
+ OtherMethods map[string]ValidationObject `json:"other_methods,omitempty"`
+ } `json:"validation,omitempty"`
+}
+
+type ValidationObject struct {
+ FileValidationURLHTTP string `json:"file_validation_url_http"`
+ FileValidationURLHTTPS string `json:"file_validation_url_https"`
+ FileValidationContent []string `json:"file_validation_content"`
+ CnameValidationP1 string `json:"cname_validation_p1"`
+ CnameValidationP2 string `json:"cname_validation_p2"`
+}
+
+type CertificateBundle struct {
+ CertificateCrt string `json:"certificate.crt"`
+ CABundleCrt string `json:"ca_bundle.crt"`
+}
+
+type CertificateList struct {
+ TotalCount int `json:"total_count"`
+ ResultCount int `json:"result_count"`
+ Page string `json:"page"` // don't ask me why this is a string
+ Limit int `json:"limit"`
+ ACMEUsageLevel string `json:"acmeUsageLevel"`
+ ACMELocked bool `json:"acmeLocked"`
+ Results []CertificateObject `json:"results"`
+}
+
+type ValidationStatus struct {
+ ValidationCompleted int `json:"validation_completed"`
+ Details map[string]struct {
+ Method string `json:"method"`
+ Status string `json:"status"`
+ } `json:"details"`
+}
diff --git a/vendor/github.com/caddyserver/zerossl/zerossl.go b/vendor/github.com/caddyserver/zerossl/zerossl.go
new file mode 100644
index 00000000..7585334a
--- /dev/null
+++ b/vendor/github.com/caddyserver/zerossl/zerossl.go
@@ -0,0 +1,64 @@
+// Package zerossl implements the ZeroSSL REST API.
+// See the API documentation on the ZeroSSL website: https://zerossl.com/documentation/api/
+package zerossl
+
+import (
+ "crypto/x509"
+ "encoding/base64"
+ "fmt"
+)
+
+// The base URL to the ZeroSSL API.
+const BaseURL = "https://api.zerossl.com"
+
+// ListAllCertificates returns parameters that lists all the certificates on the account;
+// be sure to set Page and Limit if paginating.
+func ListAllCertificates() ListCertificatesParameters {
+ return ListCertificatesParameters{
+ Status: "draft,pending_validation,issued,cancelled,revoked,expired",
+ }
+}
+
+func identifiersFromCSR(csr *x509.CertificateRequest) []string {
+ var identifiers []string
+ if csr.Subject.CommonName != "" {
+ // deprecated for like 20 years, but oh well
+ identifiers = append(identifiers, csr.Subject.CommonName)
+ }
+ identifiers = append(identifiers, csr.DNSNames...)
+ identifiers = append(identifiers, csr.EmailAddresses...)
+ for _, ip := range csr.IPAddresses {
+ identifiers = append(identifiers, ip.String())
+ }
+ for _, uri := range csr.URIs {
+ identifiers = append(identifiers, uri.String())
+ }
+ return identifiers
+}
+
+func csr2pem(csrASN1DER []byte) string {
+ return fmt.Sprintf("-----BEGIN CERTIFICATE REQUEST-----\n%s\n-----END CERTIFICATE REQUEST-----",
+ base64.StdEncoding.EncodeToString(csrASN1DER))
+}
+
+// VerificationMethod represents a way of verifying identifiers with ZeroSSL.
+type VerificationMethod string
+
+// Verification methods.
+const (
+ EmailVerification VerificationMethod = "EMAIL"
+ CNAMEVerification VerificationMethod = "CNAME_CSR_HASH"
+ HTTPVerification VerificationMethod = "HTTP_CSR_HASH"
+ HTTPSVerification VerificationMethod = "HTTPS_CSR_HASH"
+)
+
+// RevocationReason represents various reasons for revoking a certificate.
+type RevocationReason string
+
+const (
+ UnspecifiedReason RevocationReason = "unspecified" // default
+ KeyCompromise RevocationReason = "keyCompromise" // lost control of private key
+ AffiliationChanged RevocationReason = "affiliationChanged" // identify information changed
+ Superseded RevocationReason = "Superseded" // certificate replaced -- do not revoke for this reason, however
+ CessationOfOperation RevocationReason = "cessationOfOperation" // domains are no longer in use
+)
diff --git a/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
index b4800567..42bf32aa 100644
--- a/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
+++ b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
@@ -9,6 +9,8 @@ func Render(doc []byte) []byte {
renderer := NewRoffRenderer()
return blackfriday.Run(doc,
- []blackfriday.Option{blackfriday.WithRenderer(renderer),
- blackfriday.WithExtensions(renderer.GetExtensions())}...)
+ []blackfriday.Option{
+ blackfriday.WithRenderer(renderer),
+ blackfriday.WithExtensions(renderer.GetExtensions()),
+ }...)
}
diff --git a/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
index be2b3436..8a290f19 100644
--- a/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
+++ b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
@@ -1,6 +1,8 @@
package md2man
import (
+ "bufio"
+ "bytes"
"fmt"
"io"
"os"
@@ -20,34 +22,35 @@ type roffRenderer struct {
}
const (
- titleHeader = ".TH "
- topLevelHeader = "\n\n.SH "
- secondLevelHdr = "\n.SH "
- otherHeader = "\n.SS "
- crTag = "\n"
- emphTag = "\\fI"
- emphCloseTag = "\\fP"
- strongTag = "\\fB"
- strongCloseTag = "\\fP"
- breakTag = "\n.br\n"
- paraTag = "\n.PP\n"
- hruleTag = "\n.ti 0\n\\l'\\n(.lu'\n"
- linkTag = "\n\\[la]"
- linkCloseTag = "\\[ra]"
- codespanTag = "\\fB\\fC"
- codespanCloseTag = "\\fR"
- codeTag = "\n.PP\n.RS\n\n.nf\n"
- codeCloseTag = "\n.fi\n.RE\n"
- quoteTag = "\n.PP\n.RS\n"
- quoteCloseTag = "\n.RE\n"
- listTag = "\n.RS\n"
- listCloseTag = "\n.RE\n"
- dtTag = "\n.TP\n"
- dd2Tag = "\n"
- tableStart = "\n.TS\nallbox;\n"
- tableEnd = ".TE\n"
- tableCellStart = "T{\n"
- tableCellEnd = "\nT}\n"
+ titleHeader = ".TH "
+ topLevelHeader = "\n\n.SH "
+ secondLevelHdr = "\n.SH "
+ otherHeader = "\n.SS "
+ crTag = "\n"
+ emphTag = "\\fI"
+ emphCloseTag = "\\fP"
+ strongTag = "\\fB"
+ strongCloseTag = "\\fP"
+ breakTag = "\n.br\n"
+ paraTag = "\n.PP\n"
+ hruleTag = "\n.ti 0\n\\l'\\n(.lu'\n"
+ linkTag = "\n\\[la]"
+ linkCloseTag = "\\[ra]"
+ codespanTag = "\\fB"
+ codespanCloseTag = "\\fR"
+ codeTag = "\n.EX\n"
+ codeCloseTag = ".EE\n" // Do not prepend a newline character since code blocks, by definition, include a newline already (or at least as how blackfriday gives us on).
+ quoteTag = "\n.PP\n.RS\n"
+ quoteCloseTag = "\n.RE\n"
+ listTag = "\n.RS\n"
+ listCloseTag = "\n.RE\n"
+ dtTag = "\n.TP\n"
+ dd2Tag = "\n"
+ tableStart = "\n.TS\nallbox;\n"
+ tableEnd = ".TE\n"
+ tableCellStart = "T{\n"
+ tableCellEnd = "\nT}\n"
+ tablePreprocessor = `'\" t`
)
// NewRoffRenderer creates a new blackfriday Renderer for generating roff documents
@@ -74,6 +77,16 @@ func (r *roffRenderer) GetExtensions() blackfriday.Extensions {
// RenderHeader handles outputting the header at document start
func (r *roffRenderer) RenderHeader(w io.Writer, ast *blackfriday.Node) {
+ // We need to walk the tree to check if there are any tables.
+ // If there are, we need to enable the roff table preprocessor.
+ ast.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
+ if node.Type == blackfriday.Table {
+ out(w, tablePreprocessor+"\n")
+ return blackfriday.Terminate
+ }
+ return blackfriday.GoToNext
+ })
+
// disable hyphenation
out(w, ".nh\n")
}
@@ -86,8 +99,7 @@ func (r *roffRenderer) RenderFooter(w io.Writer, ast *blackfriday.Node) {
// RenderNode is called for each node in a markdown document; based on the node
// type the equivalent roff output is sent to the writer
func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
-
- var walkAction = blackfriday.GoToNext
+ walkAction := blackfriday.GoToNext
switch node.Type {
case blackfriday.Text:
@@ -109,9 +121,16 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering
out(w, strongCloseTag)
}
case blackfriday.Link:
- if !entering {
- out(w, linkTag+string(node.LinkData.Destination)+linkCloseTag)
+ // Don't render the link text for automatic links, because this
+ // will only duplicate the URL in the roff output.
+ // See https://daringfireball.net/projects/markdown/syntax#autolink
+ if !bytes.Equal(node.LinkData.Destination, node.FirstChild.Literal) {
+ out(w, string(node.FirstChild.Literal))
}
+ // Hyphens in a link must be escaped to avoid word-wrap in the rendered man page.
+ escapedLink := strings.ReplaceAll(string(node.LinkData.Destination), "-", "\\-")
+ out(w, linkTag+escapedLink+linkCloseTag)
+ walkAction = blackfriday.SkipChildren
case blackfriday.Image:
// ignore images
walkAction = blackfriday.SkipChildren
@@ -160,6 +179,11 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering
r.handleTableCell(w, node, entering)
case blackfriday.HTMLSpan:
// ignore other HTML tags
+ case blackfriday.HTMLBlock:
+ if bytes.HasPrefix(node.Literal, []byte(" 00:02:19,376) limits secondLine
// length to exactly 29 characters.
if len(secondLine) != 29 {
@@ -325,14 +320,12 @@ func Srt(in []byte, _ uint32) bool {
if strings.Contains(secondLine, ".") {
return false
}
- // For Go <1.17, comma is not recognised as a decimal separator by `time.Parse`.
- secondLine = strings.ReplaceAll(secondLine, ",", ".")
// Second line must be a time range.
ts := strings.Split(secondLine, " --> ")
if len(ts) != 2 {
return false
}
- const layout = "15:04:05.000"
+ const layout = "15:04:05,000"
t0, err := time.Parse(layout, ts[0])
if err != nil {
return false
@@ -345,8 +338,9 @@ func Srt(in []byte, _ uint32) bool {
return false
}
+ line, _ = scanLine(raw)
// A third line must exist and not be empty. This is the actual subtitle text.
- return s.Scan() && len(s.Bytes()) != 0
+ return len(line) != 0
}
// Vtt matches a Web Video Text Tracks (WebVTT) file. See
@@ -373,3 +367,15 @@ func Vtt(raw []byte, limit uint32) bool {
return bytes.Equal(raw, []byte{0xEF, 0xBB, 0xBF, 0x57, 0x45, 0x42, 0x56, 0x54, 0x54}) || // UTF-8 BOM and "WEBVTT"
bytes.Equal(raw, []byte{0x57, 0x45, 0x42, 0x56, 0x54, 0x54}) // "WEBVTT"
}
+
+// dropCR drops a terminal \r from the data.
+func dropCR(data []byte) []byte {
+ if len(data) > 0 && data[len(data)-1] == '\r' {
+ return data[0 : len(data)-1]
+ }
+ return data
+}
+func scanLine(b []byte) (line, remainder []byte) {
+ line, remainder, _ = bytes.Cut(b, []byte("\n"))
+ return dropCR(line), remainder
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/text_csv.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/text_csv.go
index 84ed6492..af256438 100644
--- a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/text_csv.go
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/text_csv.go
@@ -18,7 +18,7 @@ func Tsv(raw []byte, limit uint32) bool {
}
func sv(in []byte, comma rune, limit uint32) bool {
- r := csv.NewReader(dropLastLine(in, limit))
+ r := csv.NewReader(bytes.NewReader(dropLastLine(in, limit)))
r.Comma = comma
r.ReuseRecord = true
r.LazyQuotes = true
@@ -44,20 +44,14 @@ func sv(in []byte, comma rune, limit uint32) bool {
// mimetype limits itself to ReadLimit bytes when performing a detection.
// This means, for file formats like CSV for NDJSON, the last line of the input
// can be an incomplete line.
-func dropLastLine(b []byte, cutAt uint32) io.Reader {
- if cutAt == 0 {
- return bytes.NewReader(b)
+func dropLastLine(b []byte, readLimit uint32) []byte {
+ if readLimit == 0 || uint32(len(b)) < readLimit {
+ return b
}
- if uint32(len(b)) >= cutAt {
- for i := cutAt - 1; i > 0; i-- {
- if b[i] == '\n' {
- return bytes.NewReader(b[:i])
- }
+ for i := len(b) - 1; i > 0; i-- {
+ if b[i] == '\n' {
+ return b[:i]
}
-
- // No newline was found between the 0 index and cutAt.
- return bytes.NewReader(b[:cutAt])
}
-
- return bytes.NewReader(b)
+ return b
}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/mimetype.go b/vendor/github.com/gabriel-vasile/mimetype/mimetype.go
index 1b5909b7..d8d512b8 100644
--- a/vendor/github.com/gabriel-vasile/mimetype/mimetype.go
+++ b/vendor/github.com/gabriel-vasile/mimetype/mimetype.go
@@ -7,14 +7,15 @@ package mimetype
import (
"io"
- "io/ioutil"
"mime"
"os"
"sync/atomic"
)
+var defaultLimit uint32 = 3072
+
// readLimit is the maximum number of bytes from the input used when detecting.
-var readLimit uint32 = 3072
+var readLimit uint32 = defaultLimit
// Detect returns the MIME type found from the provided byte slice.
//
@@ -48,7 +49,7 @@ func DetectReader(r io.Reader) (*MIME, error) {
// Using atomic because readLimit can be written at the same time in other goroutine.
l := atomic.LoadUint32(&readLimit)
if l == 0 {
- in, err = ioutil.ReadAll(r)
+ in, err = io.ReadAll(r)
if err != nil {
return errMIME, err
}
@@ -103,6 +104,7 @@ func EqualsAny(s string, mimes ...string) bool {
// SetLimit sets the maximum number of bytes read from input when detecting the MIME type.
// Increasing the limit provides better detection for file formats which store
// their magical numbers towards the end of the file: docx, pptx, xlsx, etc.
+// During detection data is read in a single block of size limit, i.e. it is not buffered.
// A limit of 0 means the whole input file will be used.
func SetLimit(limit uint32) {
// Using atomic because readLimit can be read at the same time in other goroutine.
diff --git a/vendor/github.com/go-playground/validator/v10/README.md b/vendor/github.com/go-playground/validator/v10/README.md
index a6e1d0b5..e9b2b37f 100644
--- a/vendor/github.com/go-playground/validator/v10/README.md
+++ b/vendor/github.com/go-playground/validator/v10/README.md
@@ -1,7 +1,7 @@
Package validator
=================
[](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
+
[](https://travis-ci.org/go-playground/validator)
[](https://coveralls.io/github/go-playground/validator?branch=master)
[](https://goreportcard.com/report/github.com/go-playground/validator)
diff --git a/vendor/github.com/go-playground/validator/v10/baked_in.go b/vendor/github.com/go-playground/validator/v10/baked_in.go
index 95f56e00..f622c622 100644
--- a/vendor/github.com/go-playground/validator/v10/baked_in.go
+++ b/vendor/github.com/go-playground/validator/v10/baked_in.go
@@ -64,8 +64,9 @@ var (
// defines a common or complex set of validation(s) to simplify
// adding validation to structs.
bakedInAliases = map[string]string{
- "iscolor": "hexcolor|rgb|rgba|hsl|hsla",
- "country_code": "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric",
+ "iscolor": "hexcolor|rgb|rgba|hsl|hsla",
+ "country_code": "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric",
+ "eu_country_code": "iso3166_1_alpha2_eu|iso3166_1_alpha3_eu|iso3166_1_alpha_numeric_eu",
}
// bakedInValidators is the default map of ValidationFunc
@@ -133,6 +134,7 @@ var (
"urn_rfc2141": isUrnRFC2141, // RFC 2141
"file": isFile,
"filepath": isFilePath,
+ "base32": isBase32,
"base64": isBase64,
"base64url": isBase64URL,
"base64rawurl": isBase64RawURL,
@@ -216,8 +218,11 @@ var (
"datetime": isDatetime,
"timezone": isTimeZone,
"iso3166_1_alpha2": isIso3166Alpha2,
+ "iso3166_1_alpha2_eu": isIso3166Alpha2EU,
"iso3166_1_alpha3": isIso3166Alpha3,
+ "iso3166_1_alpha3_eu": isIso3166Alpha3EU,
"iso3166_1_alpha_numeric": isIso3166AlphaNumeric,
+ "iso3166_1_alpha_numeric_eu": isIso3166AlphaNumericEU,
"iso3166_2": isIso31662,
"iso4217": isIso4217,
"iso4217_numeric": isIso4217Numeric,
@@ -1399,6 +1404,11 @@ func isPostcodeByIso3166Alpha2Field(fl FieldLevel) bool {
return reg.MatchString(field.String())
}
+// isBase32 is the validation function for validating if the current field's value is a valid base 32.
+func isBase32(fl FieldLevel) bool {
+ return base32Regex.MatchString(fl.Field().String())
+}
+
// isBase64 is the validation function for validating if the current field's value is a valid base 64.
func isBase64(fl FieldLevel) bool {
return base64Regex.MatchString(fl.Field().String())
@@ -2762,12 +2772,24 @@ func isIso3166Alpha2(fl FieldLevel) bool {
return iso3166_1_alpha2[val]
}
+// isIso3166Alpha2EU is the validation function for validating if the current field's value is a valid iso3166-1 alpha-2 European Union country code.
+func isIso3166Alpha2EU(fl FieldLevel) bool {
+ val := fl.Field().String()
+ return iso3166_1_alpha2_eu[val]
+}
+
// isIso3166Alpha3 is the validation function for validating if the current field's value is a valid iso3166-1 alpha-3 country code.
func isIso3166Alpha3(fl FieldLevel) bool {
val := fl.Field().String()
return iso3166_1_alpha3[val]
}
+// isIso3166Alpha3EU is the validation function for validating if the current field's value is a valid iso3166-1 alpha-3 European Union country code.
+func isIso3166Alpha3EU(fl FieldLevel) bool {
+ val := fl.Field().String()
+ return iso3166_1_alpha3_eu[val]
+}
+
// isIso3166AlphaNumeric is the validation function for validating if the current field's value is a valid iso3166-1 alpha-numeric country code.
func isIso3166AlphaNumeric(fl FieldLevel) bool {
field := fl.Field()
@@ -2790,6 +2812,28 @@ func isIso3166AlphaNumeric(fl FieldLevel) bool {
return iso3166_1_alpha_numeric[code]
}
+// isIso3166AlphaNumericEU is the validation function for validating if the current field's value is a valid iso3166-1 alpha-numeric European Union country code.
+func isIso3166AlphaNumericEU(fl FieldLevel) bool {
+ field := fl.Field()
+
+ var code int
+ switch field.Kind() {
+ case reflect.String:
+ i, err := strconv.Atoi(field.String())
+ if err != nil {
+ return false
+ }
+ code = i % 1000
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ code = int(field.Int() % 1000)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ code = int(field.Uint() % 1000)
+ default:
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+ }
+ return iso3166_1_alpha_numeric_eu[code]
+}
+
// isIso31662 is the validation function for validating if the current field's value is a valid iso3166-2 code.
func isIso31662(fl FieldLevel) bool {
val := fl.Field().String()
diff --git a/vendor/github.com/go-playground/validator/v10/country_codes.go b/vendor/github.com/go-playground/validator/v10/country_codes.go
index 0119f057..e507149d 100644
--- a/vendor/github.com/go-playground/validator/v10/country_codes.go
+++ b/vendor/github.com/go-playground/validator/v10/country_codes.go
@@ -54,6 +54,15 @@ var iso3166_1_alpha2 = map[string]bool{
"EH": true, "YE": true, "ZM": true, "ZW": true, "XK": true,
}
+var iso3166_1_alpha2_eu = map[string]bool{
+ "AT": true, "BE": true, "BG": true, "HR": true, "CY": true,
+ "CZ": true, "DK": true, "EE": true, "FI": true, "FR": true,
+ "DE": true, "GR": true, "HU": true, "IE": true, "IT": true,
+ "LV": true, "LT": true, "LU": true, "MT": true, "NL": true,
+ "PL": true, "PT": true, "RO": true, "SK": true, "SI": true,
+ "ES": true, "SE": true,
+}
+
var iso3166_1_alpha3 = map[string]bool{
// see: https://www.iso.org/iso-3166-country-codes.html
"AFG": true, "ALB": true, "DZA": true, "ASM": true, "AND": true,
@@ -107,6 +116,15 @@ var iso3166_1_alpha3 = map[string]bool{
"VNM": true, "VGB": true, "VIR": true, "WLF": true, "ESH": true,
"YEM": true, "ZMB": true, "ZWE": true, "ALA": true, "UNK": true,
}
+
+var iso3166_1_alpha3_eu = map[string]bool{
+ "AUT": true, "BEL": true, "BGR": true, "HRV": true, "CYP": true,
+ "CZE": true, "DNK": true, "EST": true, "FIN": true, "FRA": true,
+ "DEU": true, "GRC": true, "HUN": true, "IRL": true, "ITA": true,
+ "LVA": true, "LTU": true, "LUX": true, "MLT": true, "NLD": true,
+ "POL": true, "PRT": true, "ROU": true, "SVK": true, "SVN": true,
+ "ESP": true, "SWE": true,
+}
var iso3166_1_alpha_numeric = map[int]bool{
// see: https://www.iso.org/iso-3166-country-codes.html
4: true, 8: true, 12: true, 16: true, 20: true,
@@ -161,6 +179,15 @@ var iso3166_1_alpha_numeric = map[int]bool{
887: true, 894: true, 716: true, 248: true, 153: true,
}
+var iso3166_1_alpha_numeric_eu = map[int]bool{
+ 40: true, 56: true, 100: true, 191: true, 196: true,
+ 200: true, 208: true, 233: true, 246: true, 250: true,
+ 276: true, 300: true, 348: true, 372: true, 380: true,
+ 428: true, 440: true, 442: true, 470: true, 528: true,
+ 616: true, 620: true, 642: true, 703: true, 705: true,
+ 724: true, 752: true,
+}
+
var iso3166_2 = map[string]bool{
"AD-02": true, "AD-03": true, "AD-04": true, "AD-05": true, "AD-06": true,
"AD-07": true, "AD-08": true, "AE-AJ": true, "AE-AZ": true, "AE-DU": true,
diff --git a/vendor/github.com/go-playground/validator/v10/doc.go b/vendor/github.com/go-playground/validator/v10/doc.go
index b4740918..2e8092a9 100644
--- a/vendor/github.com/go-playground/validator/v10/doc.go
+++ b/vendor/github.com/go-playground/validator/v10/doc.go
@@ -916,6 +916,15 @@ according to the RFC 2141 spec.
Usage: urn_rfc2141
+# Base32 String
+
+This validates that a string value contains a valid bas324 value.
+Although an empty string is valid base32 this will report an empty string
+as an error, if you wish to accept an empty string as valid you can use
+this with the omitempty tag.
+
+ Usage: base32
+
# Base64 String
This validates that a string value contains a valid base64 value.
diff --git a/vendor/github.com/go-playground/validator/v10/regexes.go b/vendor/github.com/go-playground/validator/v10/regexes.go
index af98d8da..f39a4667 100644
--- a/vendor/github.com/go-playground/validator/v10/regexes.go
+++ b/vendor/github.com/go-playground/validator/v10/regexes.go
@@ -17,6 +17,7 @@ const (
hslaRegexString = "^hsla\\(\\s*(?:0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$"
emailRegexString = "^(?:(?:(?:(?:[a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(?:\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|(?:(?:\\x22)(?:(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(?:\\x20|\\x09)+)?(?:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(\\x20|\\x09)+)?(?:\\x22))))@(?:(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$"
e164RegexString = "^\\+[1-9]?[0-9]{7,14}$"
+ base32RegexString = "^(?:[A-Z2-7]{8})*(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}=|[A-Z2-7]{8})$"
base64RegexString = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$"
base64URLRegexString = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2}==|[A-Za-z0-9-_]{3}=|[A-Za-z0-9-_]{4})$"
base64RawURLRegexString = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2,4})$"
@@ -31,7 +32,7 @@ const (
uUID4RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
uUID5RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-5[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
uUIDRFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
- uLIDRegexString = "^[A-HJKMNP-TV-Z0-9]{26}$"
+ uLIDRegexString = "^(?i)[A-HJKMNP-TV-Z0-9]{26}$"
md4RegexString = "^[0-9a-f]{32}$"
md5RegexString = "^[0-9a-f]{32}$"
sha256RegexString = "^[0-9a-f]{64}$"
@@ -89,6 +90,7 @@ var (
hslaRegex = regexp.MustCompile(hslaRegexString)
e164Regex = regexp.MustCompile(e164RegexString)
emailRegex = regexp.MustCompile(emailRegexString)
+ base32Regex = regexp.MustCompile(base32RegexString)
base64Regex = regexp.MustCompile(base64RegexString)
base64URLRegex = regexp.MustCompile(base64URLRegexString)
base64RawURLRegex = regexp.MustCompile(base64RawURLRegexString)
diff --git a/vendor/github.com/goccy/go-json/.codecov.yml b/vendor/github.com/goccy/go-json/.codecov.yml
new file mode 100644
index 00000000..e9813457
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/.codecov.yml
@@ -0,0 +1,32 @@
+codecov:
+ require_ci_to_pass: yes
+
+coverage:
+ precision: 2
+ round: down
+ range: "70...100"
+
+ status:
+ project:
+ default:
+ target: 70%
+ threshold: 2%
+ patch: off
+ changes: no
+
+parsers:
+ gcov:
+ branch_detection:
+ conditional: yes
+ loop: yes
+ method: no
+ macro: no
+
+comment:
+ layout: "header,diff"
+ behavior: default
+ require_changes: no
+
+ignore:
+ - internal/encoder/vm_color
+ - internal/encoder/vm_color_indent
diff --git a/vendor/github.com/goccy/go-json/.gitignore b/vendor/github.com/goccy/go-json/.gitignore
new file mode 100644
index 00000000..37828382
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/.gitignore
@@ -0,0 +1,2 @@
+cover.html
+cover.out
diff --git a/vendor/github.com/goccy/go-json/.golangci.yml b/vendor/github.com/goccy/go-json/.golangci.yml
new file mode 100644
index 00000000..977accaa
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/.golangci.yml
@@ -0,0 +1,86 @@
+run:
+ skip-files:
+ - encode_optype.go
+ - ".*_test\\.go$"
+
+linters-settings:
+ govet:
+ enable-all: true
+ disable:
+ - shadow
+
+linters:
+ enable-all: true
+ disable:
+ - dogsled
+ - dupl
+ - exhaustive
+ - exhaustivestruct
+ - errorlint
+ - forbidigo
+ - funlen
+ - gci
+ - gochecknoglobals
+ - gochecknoinits
+ - gocognit
+ - gocritic
+ - gocyclo
+ - godot
+ - godox
+ - goerr113
+ - gofumpt
+ - gomnd
+ - gosec
+ - ifshort
+ - lll
+ - makezero
+ - nakedret
+ - nestif
+ - nlreturn
+ - paralleltest
+ - testpackage
+ - thelper
+ - wrapcheck
+ - interfacer
+ - lll
+ - nakedret
+ - nestif
+ - nlreturn
+ - testpackage
+ - wsl
+ - varnamelen
+ - nilnil
+ - ireturn
+ - govet
+ - forcetypeassert
+ - cyclop
+ - containedctx
+ - revive
+ - nosnakecase
+ - exhaustruct
+ - depguard
+
+issues:
+ exclude-rules:
+ # not needed
+ - path: /*.go
+ text: "ST1003: should not use underscores in package names"
+ linters:
+ - stylecheck
+ - path: /*.go
+ text: "don't use an underscore in package name"
+ linters:
+ - golint
+ - path: rtype.go
+ linters:
+ - golint
+ - stylecheck
+ - path: error.go
+ linters:
+ - staticcheck
+
+ # Maximum issues count per one linter. Set to 0 to disable. Default is 50.
+ max-issues-per-linter: 0
+
+ # Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
+ max-same-issues: 0
diff --git a/vendor/github.com/goccy/go-json/CHANGELOG.md b/vendor/github.com/goccy/go-json/CHANGELOG.md
new file mode 100644
index 00000000..d09bb89c
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/CHANGELOG.md
@@ -0,0 +1,425 @@
+# v0.10.2 - 2023/03/20
+
+### New features
+
+* Support DebugDOT option for debugging encoder ( #440 )
+
+### Fix bugs
+
+* Fix combination of embedding structure and omitempty option ( #442 )
+
+# v0.10.1 - 2023/03/13
+
+### Fix bugs
+
+* Fix checkptr error for array decoder ( #415 )
+* Fix added buffer size check when decoding key ( #430 )
+* Fix handling of anonymous fields other than struct ( #431 )
+* Fix to not optimize when lower conversion can't handle byte-by-byte ( #432 )
+* Fix a problem that MarshalIndent does not work when UnorderedMap is specified ( #435 )
+* Fix mapDecoder.DecodeStream() for empty objects containing whitespace ( #425 )
+* Fix an issue that could not set the correct NextField for fields in the embedded structure ( #438 )
+
+# v0.10.0 - 2022/11/29
+
+### New features
+
+* Support JSON Path ( #250 )
+
+### Fix bugs
+
+* Fix marshaler for map's key ( #409 )
+
+# v0.9.11 - 2022/08/18
+
+### Fix bugs
+
+* Fix unexpected behavior when buffer ends with backslash ( #383 )
+* Fix stream decoding of escaped character ( #387 )
+
+# v0.9.10 - 2022/07/15
+
+### Fix bugs
+
+* Fix boundary exception of type caching ( #382 )
+
+# v0.9.9 - 2022/07/15
+
+### Fix bugs
+
+* Fix encoding of directed interface with typed nil ( #377 )
+* Fix embedded primitive type encoding using alias ( #378 )
+* Fix slice/array type encoding with types implementing MarshalJSON ( #379 )
+* Fix unicode decoding when the expected buffer state is not met after reading ( #380 )
+
+# v0.9.8 - 2022/06/30
+
+### Fix bugs
+
+* Fix decoding of surrogate-pair ( #365 )
+* Fix handling of embedded primitive type ( #366 )
+* Add validation of escape sequence for decoder ( #367 )
+* Fix stream tokenizing respecting UseNumber ( #369 )
+* Fix encoding when struct pointer type that implements Marshal JSON is embedded ( #375 )
+
+### Improve performance
+
+* Improve performance of linkRecursiveCode ( #368 )
+
+# v0.9.7 - 2022/04/22
+
+### Fix bugs
+
+#### Encoder
+
+* Add filtering process for encoding on slow path ( #355 )
+* Fix encoding of interface{} with pointer type ( #363 )
+
+#### Decoder
+
+* Fix map key decoder that implements UnmarshalJSON ( #353 )
+* Fix decoding of []uint8 type ( #361 )
+
+### New features
+
+* Add DebugWith option for encoder ( #356 )
+
+# v0.9.6 - 2022/03/22
+
+### Fix bugs
+
+* Correct the handling of the minimum value of int type for decoder ( #344 )
+* Fix bugs of stream decoder's bufferSize ( #349 )
+* Add a guard to use typeptr more safely ( #351 )
+
+### Improve decoder performance
+
+* Improve escapeString's performance ( #345 )
+
+### Others
+
+* Update go version for CI ( #347 )
+
+# v0.9.5 - 2022/03/04
+
+### Fix bugs
+
+* Fix panic when decoding time.Time with context ( #328 )
+* Fix reading the next character in buffer to nul consideration ( #338 )
+* Fix incorrect handling on skipValue ( #341 )
+
+### Improve decoder performance
+
+* Improve performance when a payload contains escape sequence ( #334 )
+
+# v0.9.4 - 2022/01/21
+
+* Fix IsNilForMarshaler for string type with omitempty ( #323 )
+* Fix the case where the embedded field is at the end ( #326 )
+
+# v0.9.3 - 2022/01/14
+
+* Fix logic of removing struct field for decoder ( #322 )
+
+# v0.9.2 - 2022/01/14
+
+* Add invalid decoder to delay type error judgment at decode ( #321 )
+
+# v0.9.1 - 2022/01/11
+
+* Fix encoding of MarshalText/MarshalJSON operation with head offset ( #319 )
+
+# v0.9.0 - 2022/01/05
+
+### New feature
+
+* Supports dynamic filtering of struct fields ( #314 )
+
+### Improve encoding performance
+
+* Improve map encoding performance ( #310 )
+* Optimize encoding path for escaped string ( #311 )
+* Add encoding option for performance ( #312 )
+
+### Fix bugs
+
+* Fix panic at encoding map value on 1.18 ( #310 )
+* Fix MarshalIndent for interface type ( #317 )
+
+# v0.8.1 - 2021/12/05
+
+* Fix operation conversion from PtrHead to Head in Recursive type ( #305 )
+
+# v0.8.0 - 2021/12/02
+
+* Fix embedded field conflict behavior ( #300 )
+* Refactor compiler for encoder ( #301 #302 )
+
+# v0.7.10 - 2021/10/16
+
+* Fix conversion from pointer to uint64 ( #294 )
+
+# v0.7.9 - 2021/09/28
+
+* Fix encoding of nil value about interface type that has method ( #291 )
+
+# v0.7.8 - 2021/09/01
+
+* Fix mapassign_faststr for indirect struct type ( #283 )
+* Fix encoding of not empty interface type ( #284 )
+* Fix encoding of empty struct interface type ( #286 )
+
+# v0.7.7 - 2021/08/25
+
+* Fix invalid utf8 on stream decoder ( #279 )
+* Fix buffer length bug on string stream decoder ( #280 )
+
+Thank you @orisano !!
+
+# v0.7.6 - 2021/08/13
+
+* Fix nil slice assignment ( #276 )
+* Improve error message ( #277 )
+
+# v0.7.5 - 2021/08/12
+
+* Fix encoding of embedded struct with tags ( #265 )
+* Fix encoding of embedded struct that isn't first field ( #272 )
+* Fix decoding of binary type with escaped char ( #273 )
+
+# v0.7.4 - 2021/07/06
+
+* Fix encoding of indirect layout structure ( #264 )
+
+# v0.7.3 - 2021/06/29
+
+* Fix encoding of pointer type in empty interface ( #262 )
+
+# v0.7.2 - 2021/06/26
+
+### Fix decoder
+
+* Add decoder for func type to fix decoding of nil function value ( #257 )
+* Fix stream decoding of []byte type ( #258 )
+
+### Performance
+
+* Improve decoding performance of map[string]interface{} type ( use `mapassign_faststr` ) ( #256 )
+* Improve encoding performance of empty interface type ( remove recursive calling of `vm.Run` ) ( #259 )
+
+### Benchmark
+
+* Add bytedance/sonic as benchmark target ( #254 )
+
+# v0.7.1 - 2021/06/18
+
+### Fix decoder
+
+* Fix error when unmarshal empty array ( #253 )
+
+# v0.7.0 - 2021/06/12
+
+### Support context for MarshalJSON and UnmarshalJSON ( #248 )
+
+* json.MarshalContext(context.Context, interface{}, ...json.EncodeOption) ([]byte, error)
+* json.NewEncoder(io.Writer).EncodeContext(context.Context, interface{}, ...json.EncodeOption) error
+* json.UnmarshalContext(context.Context, []byte, interface{}, ...json.DecodeOption) error
+* json.NewDecoder(io.Reader).DecodeContext(context.Context, interface{}) error
+
+```go
+type MarshalerContext interface {
+ MarshalJSON(context.Context) ([]byte, error)
+}
+
+type UnmarshalerContext interface {
+ UnmarshalJSON(context.Context, []byte) error
+}
+```
+
+### Add DecodeFieldPriorityFirstWin option ( #242 )
+
+In the default behavior, go-json, like encoding/json, will reflect the result of the last evaluation when a field with the same name exists. I've added new options to allow you to change this behavior. `json.DecodeFieldPriorityFirstWin` option reflects the result of the first evaluation if a field with the same name exists. This behavior has a performance advantage as it allows the subsequent strings to be skipped if all fields have been evaluated.
+
+### Fix encoder
+
+* Fix indent number contains recursive type ( #249 )
+* Fix encoding of using empty interface as map key ( #244 )
+
+### Fix decoder
+
+* Fix decoding fields containing escaped characters ( #237 )
+
+### Refactor
+
+* Move some tests to subdirectory ( #243 )
+* Refactor package layout for decoder ( #238 )
+
+# v0.6.1 - 2021/06/02
+
+### Fix encoder
+
+* Fix value of totalLength for encoding ( #236 )
+
+# v0.6.0 - 2021/06/01
+
+### Support Colorize option for encoding (#233)
+
+```go
+b, err := json.MarshalWithOption(v, json.Colorize(json.DefaultColorScheme))
+if err != nil {
+ ...
+}
+fmt.Println(string(b)) // print colored json
+```
+
+### Refactor
+
+* Fix opcode layout - Adjust memory layout of the opcode to 128 bytes in a 64-bit environment ( #230 )
+* Refactor encode option ( #231 )
+* Refactor escape string ( #232 )
+
+# v0.5.1 - 2021/5/20
+
+### Optimization
+
+* Add type addrShift to enable bigger encoder/decoder cache ( #213 )
+
+### Fix decoder
+
+* Keep original reference of slice element ( #229 )
+
+### Refactor
+
+* Refactor Debug mode for encoding ( #226 )
+* Generate VM sources for encoding ( #227 )
+* Refactor validator for null/true/false for decoding ( #221 )
+
+# v0.5.0 - 2021/5/9
+
+### Supports using omitempty and string tags at the same time ( #216 )
+
+### Fix decoder
+
+* Fix stream decoder for unicode char ( #215 )
+* Fix decoding of slice element ( #219 )
+* Fix calculating of buffer length for stream decoder ( #220 )
+
+### Refactor
+
+* replace skipWhiteSpace goto by loop ( #212 )
+
+# v0.4.14 - 2021/5/4
+
+### Benchmark
+
+* Add valyala/fastjson to benchmark ( #193 )
+* Add benchmark task for CI ( #211 )
+
+### Fix decoder
+
+* Fix decoding of slice with unmarshal json type ( #198 )
+* Fix decoding of null value for interface type that does not implement Unmarshaler ( #205 )
+* Fix decoding of null value to []byte by json.Unmarshal ( #206 )
+* Fix decoding of backslash char at the end of string ( #207 )
+* Fix stream decoder for null/true/false value ( #208 )
+* Fix stream decoder for slow reader ( #211 )
+
+### Performance
+
+* If cap of slice is enough, reuse slice data for compatibility with encoding/json ( #200 )
+
+# v0.4.13 - 2021/4/20
+
+### Fix json.Compact and json.Indent
+
+* Support validation the input buffer for json.Compact and json.Indent ( #189 )
+* Optimize json.Compact and json.Indent ( improve memory footprint ) ( #190 )
+
+# v0.4.12 - 2021/4/15
+
+### Fix encoder
+
+* Fix unnecessary indent for empty slice type ( #181 )
+* Fix encoding of omitempty feature for the slice or interface type ( #183 )
+* Fix encoding custom types zero values with omitempty when marshaller exists ( #187 )
+
+### Fix decoder
+
+* Fix decoder for invalid top level value ( #184 )
+* Fix decoder for invalid number value ( #185 )
+
+# v0.4.11 - 2021/4/3
+
+* Improve decoder performance for interface type
+
+# v0.4.10 - 2021/4/2
+
+### Fix encoder
+
+* Fixed a bug when encoding slice and map containing recursive structures
+* Fixed a logic to determine if indirect reference
+
+# v0.4.9 - 2021/3/29
+
+### Add debug mode
+
+If you use `json.MarshalWithOption(v, json.Debug())` and `panic` occurred in `go-json`, produces debug information to console.
+
+### Support a new feature to compatible with encoding/json
+
+- invalid UTF-8 is coerced to valid UTF-8 ( without performance down )
+
+### Fix encoder
+
+- Fixed handling of MarshalJSON of function type
+
+### Fix decoding of slice of pointer type
+
+If there is a pointer value, go-json will use it. (This behavior is necessary to achieve the ability to prioritize pre-filled values). However, since slices are reused internally, there was a bug that referred to the previous pointer value. Therefore, it is not necessary to refer to the pointer value in advance for the slice element, so we explicitly initialize slice element by `nil`.
+
+# v0.4.8 - 2021/3/21
+
+### Reduce memory usage at compile time
+
+* go-json have used about 2GB of memory at compile time, but now it can compile with about less than 550MB.
+
+### Fix any encoder's bug
+
+* Add many test cases for encoder
+* Fix composite type ( slice/array/map )
+* Fix pointer types
+* Fix encoding of MarshalJSON or MarshalText or json.Number type
+
+### Refactor encoder
+
+* Change package layout for reducing memory usage at compile
+* Remove anonymous and only operation
+* Remove root property from encodeCompileContext and opcode
+
+### Fix CI
+
+* Add Go 1.16
+* Remove Go 1.13
+* Fix `make cover` task
+
+### Number/Delim/Token/RawMessage use the types defined in encoding/json by type alias
+
+# v0.4.7 - 2021/02/22
+
+### Fix decoder
+
+* Fix decoding of deep recursive structure
+* Fix decoding of embedded unexported pointer field
+* Fix invalid test case
+* Fix decoding of invalid value
+* Fix decoding of prefilled value
+* Fix not being able to return UnmarshalTypeError when it should be returned
+* Fix decoding of null value
+* Fix decoding of type of null string
+* Use pre allocated pointer if exists it at decoding
+
+### Reduce memory usage at compile
+
+* Integrate int/int8/int16/int32/int64 and uint/uint8/uint16/uint32/uint64 operation to reduce memory usage at compile
+
+### Remove unnecessary optype
diff --git a/vendor/github.com/json-iterator/go/LICENSE b/vendor/github.com/goccy/go-json/LICENSE
similarity index 96%
rename from vendor/github.com/json-iterator/go/LICENSE
rename to vendor/github.com/goccy/go-json/LICENSE
index 2cf4f5ab..6449c8bf 100644
--- a/vendor/github.com/json-iterator/go/LICENSE
+++ b/vendor/github.com/goccy/go-json/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2016 json-iterator
+Copyright (c) 2020 Masaaki Goshima
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/github.com/goccy/go-json/Makefile b/vendor/github.com/goccy/go-json/Makefile
new file mode 100644
index 00000000..c030577d
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/Makefile
@@ -0,0 +1,39 @@
+PKG := github.com/goccy/go-json
+
+BIN_DIR := $(CURDIR)/bin
+PKGS := $(shell go list ./... | grep -v internal/cmd|grep -v test)
+COVER_PKGS := $(foreach pkg,$(PKGS),$(subst $(PKG),.,$(pkg)))
+
+COMMA := ,
+EMPTY :=
+SPACE := $(EMPTY) $(EMPTY)
+COVERPKG_OPT := $(subst $(SPACE),$(COMMA),$(COVER_PKGS))
+
+$(BIN_DIR):
+ @mkdir -p $(BIN_DIR)
+
+.PHONY: cover
+cover:
+ go test -coverpkg=$(COVERPKG_OPT) -coverprofile=cover.out ./...
+
+.PHONY: cover-html
+cover-html: cover
+ go tool cover -html=cover.out
+
+.PHONY: lint
+lint: golangci-lint
+ $(BIN_DIR)/golangci-lint run
+
+golangci-lint: | $(BIN_DIR)
+ @{ \
+ set -e; \
+ GOLANGCI_LINT_TMP_DIR=$$(mktemp -d); \
+ cd $$GOLANGCI_LINT_TMP_DIR; \
+ go mod init tmp; \
+ GOBIN=$(BIN_DIR) go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.54.2; \
+ rm -rf $$GOLANGCI_LINT_TMP_DIR; \
+ }
+
+.PHONY: generate
+generate:
+ go generate ./internal/...
diff --git a/vendor/github.com/goccy/go-json/README.md b/vendor/github.com/goccy/go-json/README.md
new file mode 100644
index 00000000..7bacc54f
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/README.md
@@ -0,0 +1,529 @@
+# go-json
+
+
+[](https://pkg.go.dev/github.com/goccy/go-json?tab=doc)
+[](https://codecov.io/gh/goccy/go-json)
+
+Fast JSON encoder/decoder compatible with encoding/json for Go
+
+
+
+# Roadmap
+
+```
+* version ( expected release date )
+
+* v0.9.0
+ |
+ | while maintaining compatibility with encoding/json, we will add convenient APIs
+ |
+ v
+* v1.0.0
+```
+
+We are accepting requests for features that will be implemented between v0.9.0 and v.1.0.0.
+If you have the API you need, please submit your issue [here](https://github.com/goccy/go-json/issues).
+
+# Features
+
+- Drop-in replacement of `encoding/json`
+- Fast ( See [Benchmark section](https://github.com/goccy/go-json#benchmarks) )
+- Flexible customization with options
+- Coloring the encoded string
+- Can propagate context.Context to `MarshalJSON` or `UnmarshalJSON`
+- Can dynamically filter the fields of the structure type-safely
+
+# Installation
+
+```
+go get github.com/goccy/go-json
+```
+
+# How to use
+
+Replace import statement from `encoding/json` to `github.com/goccy/go-json`
+
+```
+-import "encoding/json"
++import "github.com/goccy/go-json"
+```
+
+# JSON library comparison
+
+| name | encoder | decoder | compatible with `encoding/json` |
+| :----: | :------: | :-----: | :-----------------------------: |
+| encoding/json | yes | yes | N/A |
+| [json-iterator/go](https://github.com/json-iterator/go) | yes | yes | partial |
+| [easyjson](https://github.com/mailru/easyjson) | yes | yes | no |
+| [gojay](https://github.com/francoispqt/gojay) | yes | yes | no |
+| [segmentio/encoding/json](https://github.com/segmentio/encoding/tree/master/json) | yes | yes | partial |
+| [jettison](https://github.com/wI2L/jettison) | yes | no | no |
+| [simdjson-go](https://github.com/minio/simdjson-go) | no | yes | no |
+| goccy/go-json | yes | yes | yes |
+
+- `json-iterator/go` isn't compatible with `encoding/json` in many ways (e.g. https://github.com/json-iterator/go/issues/229 ), but it hasn't been supported for a long time.
+- `segmentio/encoding/json` is well supported for encoders, but some are not supported for decoder APIs such as `Token` ( streaming decode )
+
+## Other libraries
+
+- [jingo](https://github.com/bet365/jingo)
+
+I tried the benchmark but it didn't work.
+Also, it seems to panic when it receives an unexpected value because there is no error handling...
+
+- [ffjson](https://github.com/pquerna/ffjson)
+
+Benchmarking gave very slow results.
+It seems that it is assumed that the user will use the buffer pool properly.
+Also, development seems to have already stopped
+
+# Benchmarks
+
+```
+$ cd benchmarks
+$ go test -bench .
+```
+
+## Encode
+
+
+
+
+## Decode
+
+
+
+
+
+
+# Fuzzing
+
+[go-json-fuzz](https://github.com/goccy/go-json-fuzz) is the repository for fuzzing tests.
+If you run the test in this repository and find a bug, please commit to corpus to go-json-fuzz and report the issue to [go-json](https://github.com/goccy/go-json/issues).
+
+# How it works
+
+`go-json` is very fast in both encoding and decoding compared to other libraries.
+It's easier to implement by using automatic code generation for performance or by using a dedicated interface, but `go-json` dares to stick to compatibility with `encoding/json` and is the simple interface. Despite this, we are developing with the aim of being the fastest library.
+
+Here, we explain the various speed-up techniques implemented by `go-json`.
+
+## Basic technique
+
+The techniques listed here are the ones used by most of the libraries listed above.
+
+### Buffer reuse
+
+Since the only value required for the result of `json.Marshal(interface{}) ([]byte, error)` is `[]byte`, the only value that must be allocated during encoding is the return value `[]byte` .
+
+Also, as the number of allocations increases, the performance will be affected, so the number of allocations should be kept as low as possible when creating `[]byte`.
+
+Therefore, there is a technique to reduce the number of times a new buffer must be allocated by reusing the buffer used for the previous encoding by using `sync.Pool`.
+
+Finally, you allocate a buffer that is as long as the resulting buffer and copy the contents into it, you only need to allocate the buffer once in theory.
+
+```go
+type buffer struct {
+ data []byte
+}
+
+var bufPool = sync.Pool{
+ New: func() interface{} {
+ return &buffer{data: make([]byte, 0, 1024)}
+ },
+}
+
+buf := bufPool.Get().(*buffer)
+data := encode(buf.data) // reuse buf.data
+
+newBuf := make([]byte, len(data))
+copy(newBuf, buf)
+
+buf.data = data
+bufPool.Put(buf)
+```
+
+### Elimination of reflection
+
+As you know, the reflection operation is very slow.
+
+Therefore, using the fact that the address position where the type information is stored is fixed for each binary ( we call this `typeptr` ),
+we can use the address in the type information to call a pre-built optimized process.
+
+For example, you can get the address to the type information from `interface{}` as follows and you can use that information to call a process that does not have reflection.
+
+To process without reflection, pass a pointer (`unsafe.Pointer`) to the value is stored.
+
+```go
+
+type emptyInterface struct {
+ typ unsafe.Pointer
+ ptr unsafe.Pointer
+}
+
+var typeToEncoder = map[uintptr]func(unsafe.Pointer)([]byte, error){}
+
+func Marshal(v interface{}) ([]byte, error) {
+ iface := (*emptyInterface)(unsafe.Pointer(&v)
+ typeptr := uintptr(iface.typ)
+ if enc, exists := typeToEncoder[typeptr]; exists {
+ return enc(iface.ptr)
+ }
+ ...
+}
+```
+
+※ In reality, `typeToEncoder` can be referenced by multiple goroutines, so exclusive control is required.
+
+## Unique speed-up technique
+
+## Encoder
+
+### Do not escape arguments of `Marshal`
+
+`json.Marshal` and `json.Unmarshal` receive `interface{}` value and they perform type determination dynamically to process.
+In normal case, you need to use the `reflect` library to determine the type dynamically, but since `reflect.Type` is defined as `interface`, when you call the method of `reflect.Type`, The reflect's argument is escaped.
+
+Therefore, the arguments for `Marshal` and `Unmarshal` are always escaped to the heap.
+However, `go-json` can use the feature of `reflect.Type` while avoiding escaping.
+
+`reflect.Type` is defined as `interface`, but in reality `reflect.Type` is implemented only by the structure `rtype` defined in the `reflect` package.
+For this reason, to date `reflect.Type` is the same as `*reflect.rtype`.
+
+Therefore, by directly handling `*reflect.rtype`, which is an implementation of `reflect.Type`, it is possible to avoid escaping because it changes from `interface` to using `struct`.
+
+The technique for working with `*reflect.rtype` directly from `go-json` is implemented at [rtype.go](https://github.com/goccy/go-json/blob/master/internal/runtime/rtype.go)
+
+Also, the same technique is cut out as a library ( https://github.com/goccy/go-reflect )
+
+Initially this feature was the default behavior of `go-json`.
+But after careful testing, I found that I passed a large value to `json.Marshal()` and if the argument could not be assigned to the stack, it could not be properly escaped to the heap (a bug in the Go compiler).
+
+Therefore, this feature will be provided as an **optional** until this issue is resolved.
+
+To use it, add `NoEscape` like `MarshalNoEscape()`
+
+### Encoding using opcode sequence
+
+I explained that you can use `typeptr` to call a pre-built process from type information.
+
+In other libraries, this dedicated process is processed by making it an function calling like anonymous function, but function calls are inherently slow processes and should be avoided as much as possible.
+
+Therefore, `go-json` adopted the Instruction-based execution processing system, which is also used to implement virtual machines for programming language.
+
+If it is the first type to encode, create the opcode ( instruction ) sequence required for encoding.
+From the second time onward, use `typeptr` to get the cached pre-built opcode sequence and encode it based on it. An example of the opcode sequence is shown below.
+
+```go
+json.Marshal(struct{
+ X int `json:"x"`
+ Y string `json:"y"`
+}{X: 1, Y: "hello"})
+```
+
+When encoding a structure like the one above, create a sequence of opcodes like this:
+
+```
+- opStructFieldHead ( `{` )
+- opStructFieldInt ( `"x": 1,` )
+- opStructFieldString ( `"y": "hello"` )
+- opStructEnd ( `}` )
+- opEnd
+```
+
+※ When processing each operation, write the letters on the right.
+
+In addition, each opcode is managed by the following structure (
+Pseudo code ).
+
+```go
+type opType int
+const (
+ opStructFieldHead opType = iota
+ opStructFieldInt
+ opStructFieldStirng
+ opStructEnd
+ opEnd
+)
+type opcode struct {
+ op opType
+ key []byte
+ next *opcode
+}
+```
+
+The process of encoding using the opcode sequence is roughly implemented as follows.
+
+```go
+func encode(code *opcode, b []byte, p unsafe.Pointer) ([]byte, error) {
+ for {
+ switch code.op {
+ case opStructFieldHead:
+ b = append(b, '{')
+ code = code.next
+ case opStructFieldInt:
+ b = append(b, code.key...)
+ b = appendInt((*int)(unsafe.Pointer(uintptr(p)+code.offset)))
+ code = code.next
+ case opStructFieldString:
+ b = append(b, code.key...)
+ b = appendString((*string)(unsafe.Pointer(uintptr(p)+code.offset)))
+ code = code.next
+ case opStructEnd:
+ b = append(b, '}')
+ code = code.next
+ case opEnd:
+ goto END
+ }
+ }
+END:
+ return b, nil
+}
+```
+
+In this way, the huge `switch-case` is used to encode by manipulating the linked list opcodes to avoid unnecessary function calls.
+
+### Opcode sequence optimization
+
+One of the advantages of encoding using the opcode sequence is the ease of optimization.
+The opcode sequence mentioned above is actually converted into the following optimized operations and used.
+
+```
+- opStructFieldHeadInt ( `{"x": 1,` )
+- opStructEndString ( `"y": "hello"}` )
+- opEnd
+```
+
+It has been reduced from 5 opcodes to 3 opcodes !
+Reducing the number of opcodees means reducing the number of branches with `switch-case`.
+In other words, the closer the number of operations is to 1, the faster the processing can be performed.
+
+In `go-json`, optimization to reduce the number of opcodes itself like the above and it speeds up by preparing opcodes with optimized paths.
+
+### Change recursive call from CALL to JMP
+
+Recursive processing is required during encoding if the type is defined recursively as follows:
+
+```go
+type T struct {
+ X int
+ U *U
+}
+
+type U struct {
+ T *T
+}
+
+b, err := json.Marshal(&T{
+ X: 1,
+ U: &U{
+ T: &T{
+ X: 2,
+ },
+ },
+})
+fmt.Println(string(b)) // {"X":1,"U":{"T":{"X":2,"U":null}}}
+```
+
+In `go-json`, recursive processing is processed by the operation type of ` opStructFieldRecursive`.
+
+In this operation, after acquiring the opcode sequence used for recursive processing, the function is **not** called recursively as it is, but the necessary values are saved by itself and implemented by moving to the next operation.
+
+The technique of implementing recursive processing with the `JMP` operation while avoiding the `CALL` operation is a famous technique for implementing a high-speed virtual machine.
+
+For more details, please refer to [the article](https://engineering.mercari.com/blog/entry/1599563768-081104c850) ( but Japanese only ).
+
+### Dispatch by typeptr from map to slice
+
+When retrieving the data cached from the type information by `typeptr`, we usually use map.
+Map requires exclusive control, so use `sync.Map` for a naive implementation.
+
+However, this is slow, so it's a good idea to use the `atomic` package for exclusive control as implemented by `segmentio/encoding/json` ( https://github.com/segmentio/encoding/blob/master/json/codec.go#L41-L55 ).
+
+This implementation slows down the set instead of speeding up the get, but it works well because of the nature of the library, it encodes much more for the same type.
+
+However, as a result of profiling, I noticed that `runtime.mapaccess2` accounts for a significant percentage of the execution time. So I thought if I could change the lookup from map to slice.
+
+There is an API named `typelinks` defined in the `runtime` package that the `reflect` package uses internally.
+This allows you to get all the type information defined in the binary at runtime.
+
+The fact that all type information can be acquired means that by constructing slices in advance with the acquired total number of type information, it is possible to look up with the value of `typeptr` without worrying about out-of-range access.
+
+However, if there is too much type information, it will use a lot of memory, so by default we will only use this optimization if the slice size fits within **2Mib** .
+
+If this approach is not available, it will fall back to the `atomic` based process described above.
+
+If you want to know more, please refer to the implementation [here](https://github.com/goccy/go-json/blob/master/internal/runtime/type.go#L36-L100)
+
+## Decoder
+
+### Dispatch by typeptr from map to slice
+
+Like the encoder, the decoder also uses typeptr to call the dedicated process.
+
+### Faster termination character inspection using NUL character
+
+In order to decode, you have to traverse the input buffer character by position.
+At that time, if you check whether the buffer has reached the end, it will be very slow.
+
+`buf` : `[]byte` type variable. holds the string passed to the decoder
+`cursor` : `int64` type variable. holds the current read position
+
+```go
+buflen := len(buf)
+for ; cursor < buflen; cursor++ { // compare cursor and buflen at all times, it is so slow.
+ switch buf[cursor] {
+ case ' ', '\n', '\r', '\t':
+ }
+}
+```
+
+Therefore, by adding the `NUL` (`\000`) character to the end of the read buffer as shown below, it is possible to check the termination character at the same time as other characters.
+
+```go
+for {
+ switch buf[cursor] {
+ case ' ', '\n', '\r', '\t':
+ case '\000':
+ return nil
+ }
+ cursor++
+}
+```
+
+### Use Boundary Check Elimination
+
+Due to the `NUL` character optimization, the Go compiler does a boundary check every time, even though `buf[cursor]` does not cause out-of-range access.
+
+Therefore, `go-json` eliminates boundary check by fetching characters for hotspot by pointer operation. For example, the following code.
+
+```go
+func char(ptr unsafe.Pointer, offset int64) byte {
+ return *(*byte)(unsafe.Pointer(uintptr(ptr) + uintptr(offset)))
+}
+
+p := (*sliceHeader)(&unsafe.Pointer(buf)).data
+for {
+ switch char(p, cursor) {
+ case ' ', '\n', '\r', '\t':
+ case '\000':
+ return nil
+ }
+ cursor++
+}
+```
+
+### Checking the existence of fields of struct using Bitmaps
+
+I found by the profiling result, in the struct decode, lookup process for field was taking a long time.
+
+For example, consider decoding a string like `{"a":1,"b":2,"c":3}` into the following structure:
+
+```go
+type T struct {
+ A int `json:"a"`
+ B int `json:"b"`
+ C int `json:"c"`
+}
+```
+
+At this time, it was found that it takes a lot of time to acquire the decoding process corresponding to the field from the field name as shown below during the decoding process.
+
+```go
+fieldName := decodeKey(buf, cursor) // "a" or "b" or "c"
+decoder, exists := fieldToDecoderMap[fieldName] // so slow
+if exists {
+ decoder(buf, cursor)
+} else {
+ skipValue(buf, cursor)
+}
+```
+
+To improve this process, `json-iterator/go` is optimized so that it can be branched by switch-case when the number of fields in the structure is 10 or less (switch-case is faster than map). However, there is a risk of hash collision because the value hashed by the FNV algorithm is used for conditional branching. Also, `gojay` processes this part at high speed by letting the library user yourself write `switch-case`.
+
+
+`go-json` considers and implements a new approach that is different from these. I call this **bitmap field optimization**.
+
+The range of values per character can be represented by `[256]byte`. Also, if the number of fields in the structure is 8 or less, `int8` type can represent the state of each field.
+In other words, it has the following structure.
+
+- Base ( 8bit ): `00000000`
+- Key "a": `00000001` ( assign key "a" to the first bit )
+- Key "b": `00000010` ( assign key "b" to the second bit )
+- Key "c": `00000100` ( assign key "c" to the third bit )
+
+Bitmap structure is the following
+
+```
+ | key index(0) |
+------------------------
+ 0 | 00000000 |
+ 1 | 00000000 |
+~~ | |
+97 (a) | 00000001 |
+98 (b) | 00000010 |
+99 (c) | 00000100 |
+~~ | |
+255 | 00000000 |
+```
+
+You can think of this as a Bitmap with a height of `256` and a width of the maximum string length in the field name.
+In other words, it can be represented by the following type .
+
+```go
+[maxFieldKeyLength][256]int8
+```
+
+When decoding a field character, check whether the corresponding character exists by referring to the pre-built bitmap like the following.
+
+```go
+var curBit int8 = math.MaxInt8 // 11111111
+
+c := char(buf, cursor)
+bit := bitmap[keyIdx][c]
+curBit &= bit
+if curBit == 0 {
+ // not found field
+}
+```
+
+If `curBit` is not `0` until the end of the field string, then the string is
+You may have hit one of the fields.
+But the possibility is that if the decoded string is shorter than the field string, you will get a false hit.
+
+- input: `{"a":1}`
+```go
+type T struct {
+ X int `json:"abc"`
+}
+```
+※ Since `a` is shorter than `abc`, it can decode to the end of the field character without `curBit` being 0.
+
+Rest assured. In this case, it doesn't matter because you can tell if you hit by comparing the string length of `a` with the string length of `abc`.
+
+Finally, calculate the position of the bit where `1` is set and get the corresponding value, and you're done.
+
+Using this technique, field lookups are possible with only bitwise operations and access to slices.
+
+`go-json` uses a similar technique for fields with 9 or more and 16 or less fields. At this time, Bitmap is constructed as `[maxKeyLen][256]int16` type.
+
+Currently, this optimization is not performed when the maximum length of the field name is long (specifically, 64 bytes or more) in addition to the limitation of the number of fields from the viewpoint of saving memory usage.
+
+### Others
+
+I have done a lot of other optimizations. I will find time to write about them. If you have any questions about what's written here or other optimizations, please visit the `#go-json` channel on `gophers.slack.com` .
+
+## Reference
+
+Regarding the story of go-json, there are the following articles in Japanese only.
+
+- https://speakerdeck.com/goccy/zui-su-falsejsonraiburariwoqiu-mete
+- https://engineering.mercari.com/blog/entry/1599563768-081104c850/
+
+# Looking for Sponsors
+
+I'm looking for sponsors this library. This library is being developed as a personal project in my spare time. If you want a quick response or problem resolution when using this library in your project, please register as a [sponsor](https://github.com/sponsors/goccy). I will cooperate as much as possible. Of course, this library is developed as an MIT license, so you can use it freely for free.
+
+# License
+
+MIT
diff --git a/vendor/github.com/goccy/go-json/color.go b/vendor/github.com/goccy/go-json/color.go
new file mode 100644
index 00000000..e80b22b4
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/color.go
@@ -0,0 +1,68 @@
+package json
+
+import (
+ "fmt"
+
+ "github.com/goccy/go-json/internal/encoder"
+)
+
+type (
+ ColorFormat = encoder.ColorFormat
+ ColorScheme = encoder.ColorScheme
+)
+
+const escape = "\x1b"
+
+type colorAttr int
+
+//nolint:deadcode,varcheck
+const (
+ fgBlackColor colorAttr = iota + 30
+ fgRedColor
+ fgGreenColor
+ fgYellowColor
+ fgBlueColor
+ fgMagentaColor
+ fgCyanColor
+ fgWhiteColor
+)
+
+//nolint:deadcode,varcheck
+const (
+ fgHiBlackColor colorAttr = iota + 90
+ fgHiRedColor
+ fgHiGreenColor
+ fgHiYellowColor
+ fgHiBlueColor
+ fgHiMagentaColor
+ fgHiCyanColor
+ fgHiWhiteColor
+)
+
+func createColorFormat(attr colorAttr) ColorFormat {
+ return ColorFormat{
+ Header: wrapColor(attr),
+ Footer: resetColor(),
+ }
+}
+
+func wrapColor(attr colorAttr) string {
+ return fmt.Sprintf("%s[%dm", escape, attr)
+}
+
+func resetColor() string {
+ return wrapColor(colorAttr(0))
+}
+
+var (
+ DefaultColorScheme = &ColorScheme{
+ Int: createColorFormat(fgHiMagentaColor),
+ Uint: createColorFormat(fgHiMagentaColor),
+ Float: createColorFormat(fgHiMagentaColor),
+ Bool: createColorFormat(fgHiYellowColor),
+ String: createColorFormat(fgHiGreenColor),
+ Binary: createColorFormat(fgHiRedColor),
+ ObjectKey: createColorFormat(fgHiCyanColor),
+ Null: createColorFormat(fgBlueColor),
+ }
+)
diff --git a/vendor/github.com/goccy/go-json/decode.go b/vendor/github.com/goccy/go-json/decode.go
new file mode 100644
index 00000000..74c6ac3b
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/decode.go
@@ -0,0 +1,263 @@
+package json
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "reflect"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/decoder"
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type Decoder struct {
+ s *decoder.Stream
+}
+
+const (
+ nul = '\000'
+)
+
+type emptyInterface struct {
+ typ *runtime.Type
+ ptr unsafe.Pointer
+}
+
+func unmarshal(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
+ src := make([]byte, len(data)+1) // append nul byte to the end
+ copy(src, data)
+
+ header := (*emptyInterface)(unsafe.Pointer(&v))
+
+ if err := validateType(header.typ, uintptr(header.ptr)); err != nil {
+ return err
+ }
+ dec, err := decoder.CompileToGetDecoder(header.typ)
+ if err != nil {
+ return err
+ }
+ ctx := decoder.TakeRuntimeContext()
+ ctx.Buf = src
+ ctx.Option.Flags = 0
+ for _, optFunc := range optFuncs {
+ optFunc(ctx.Option)
+ }
+ cursor, err := dec.Decode(ctx, 0, 0, header.ptr)
+ if err != nil {
+ decoder.ReleaseRuntimeContext(ctx)
+ return err
+ }
+ decoder.ReleaseRuntimeContext(ctx)
+ return validateEndBuf(src, cursor)
+}
+
+func unmarshalContext(ctx context.Context, data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
+ src := make([]byte, len(data)+1) // append nul byte to the end
+ copy(src, data)
+
+ header := (*emptyInterface)(unsafe.Pointer(&v))
+
+ if err := validateType(header.typ, uintptr(header.ptr)); err != nil {
+ return err
+ }
+ dec, err := decoder.CompileToGetDecoder(header.typ)
+ if err != nil {
+ return err
+ }
+ rctx := decoder.TakeRuntimeContext()
+ rctx.Buf = src
+ rctx.Option.Flags = 0
+ rctx.Option.Flags |= decoder.ContextOption
+ rctx.Option.Context = ctx
+ for _, optFunc := range optFuncs {
+ optFunc(rctx.Option)
+ }
+ cursor, err := dec.Decode(rctx, 0, 0, header.ptr)
+ if err != nil {
+ decoder.ReleaseRuntimeContext(rctx)
+ return err
+ }
+ decoder.ReleaseRuntimeContext(rctx)
+ return validateEndBuf(src, cursor)
+}
+
+var (
+ pathDecoder = decoder.NewPathDecoder()
+)
+
+func extractFromPath(path *Path, data []byte, optFuncs ...DecodeOptionFunc) ([][]byte, error) {
+ if path.path.RootSelectorOnly {
+ return [][]byte{data}, nil
+ }
+ src := make([]byte, len(data)+1) // append nul byte to the end
+ copy(src, data)
+
+ ctx := decoder.TakeRuntimeContext()
+ ctx.Buf = src
+ ctx.Option.Flags = 0
+ ctx.Option.Flags |= decoder.PathOption
+ ctx.Option.Path = path.path
+ for _, optFunc := range optFuncs {
+ optFunc(ctx.Option)
+ }
+ paths, cursor, err := pathDecoder.DecodePath(ctx, 0, 0)
+ if err != nil {
+ decoder.ReleaseRuntimeContext(ctx)
+ return nil, err
+ }
+ decoder.ReleaseRuntimeContext(ctx)
+ if err := validateEndBuf(src, cursor); err != nil {
+ return nil, err
+ }
+ return paths, nil
+}
+
+func unmarshalNoEscape(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
+ src := make([]byte, len(data)+1) // append nul byte to the end
+ copy(src, data)
+
+ header := (*emptyInterface)(unsafe.Pointer(&v))
+
+ if err := validateType(header.typ, uintptr(header.ptr)); err != nil {
+ return err
+ }
+ dec, err := decoder.CompileToGetDecoder(header.typ)
+ if err != nil {
+ return err
+ }
+
+ ctx := decoder.TakeRuntimeContext()
+ ctx.Buf = src
+ ctx.Option.Flags = 0
+ for _, optFunc := range optFuncs {
+ optFunc(ctx.Option)
+ }
+ cursor, err := dec.Decode(ctx, 0, 0, noescape(header.ptr))
+ if err != nil {
+ decoder.ReleaseRuntimeContext(ctx)
+ return err
+ }
+ decoder.ReleaseRuntimeContext(ctx)
+ return validateEndBuf(src, cursor)
+}
+
+func validateEndBuf(src []byte, cursor int64) error {
+ for {
+ switch src[cursor] {
+ case ' ', '\t', '\n', '\r':
+ cursor++
+ continue
+ case nul:
+ return nil
+ }
+ return errors.ErrSyntax(
+ fmt.Sprintf("invalid character '%c' after top-level value", src[cursor]),
+ cursor+1,
+ )
+ }
+}
+
+//nolint:staticcheck
+//go:nosplit
+func noescape(p unsafe.Pointer) unsafe.Pointer {
+ x := uintptr(p)
+ return unsafe.Pointer(x ^ 0)
+}
+
+func validateType(typ *runtime.Type, p uintptr) error {
+ if typ == nil || typ.Kind() != reflect.Ptr || p == 0 {
+ return &InvalidUnmarshalError{Type: runtime.RType2Type(typ)}
+ }
+ return nil
+}
+
+// NewDecoder returns a new decoder that reads from r.
+//
+// The decoder introduces its own buffering and may
+// read data from r beyond the JSON values requested.
+func NewDecoder(r io.Reader) *Decoder {
+ s := decoder.NewStream(r)
+ return &Decoder{
+ s: s,
+ }
+}
+
+// Buffered returns a reader of the data remaining in the Decoder's
+// buffer. The reader is valid until the next call to Decode.
+func (d *Decoder) Buffered() io.Reader {
+ return d.s.Buffered()
+}
+
+// Decode reads the next JSON-encoded value from its
+// input and stores it in the value pointed to by v.
+//
+// See the documentation for Unmarshal for details about
+// the conversion of JSON into a Go value.
+func (d *Decoder) Decode(v interface{}) error {
+ return d.DecodeWithOption(v)
+}
+
+// DecodeContext reads the next JSON-encoded value from its
+// input and stores it in the value pointed to by v with context.Context.
+func (d *Decoder) DecodeContext(ctx context.Context, v interface{}) error {
+ d.s.Option.Flags |= decoder.ContextOption
+ d.s.Option.Context = ctx
+ return d.DecodeWithOption(v)
+}
+
+func (d *Decoder) DecodeWithOption(v interface{}, optFuncs ...DecodeOptionFunc) error {
+ header := (*emptyInterface)(unsafe.Pointer(&v))
+ typ := header.typ
+ ptr := uintptr(header.ptr)
+ typeptr := uintptr(unsafe.Pointer(typ))
+ // noescape trick for header.typ ( reflect.*rtype )
+ copiedType := *(**runtime.Type)(unsafe.Pointer(&typeptr))
+
+ if err := validateType(copiedType, ptr); err != nil {
+ return err
+ }
+
+ dec, err := decoder.CompileToGetDecoder(typ)
+ if err != nil {
+ return err
+ }
+ if err := d.s.PrepareForDecode(); err != nil {
+ return err
+ }
+ s := d.s
+ for _, optFunc := range optFuncs {
+ optFunc(s.Option)
+ }
+ if err := dec.DecodeStream(s, 0, header.ptr); err != nil {
+ return err
+ }
+ s.Reset()
+ return nil
+}
+
+func (d *Decoder) More() bool {
+ return d.s.More()
+}
+
+func (d *Decoder) Token() (Token, error) {
+ return d.s.Token()
+}
+
+// DisallowUnknownFields causes the Decoder to return an error when the destination
+// is a struct and the input contains object keys which do not match any
+// non-ignored, exported fields in the destination.
+func (d *Decoder) DisallowUnknownFields() {
+ d.s.DisallowUnknownFields = true
+}
+
+func (d *Decoder) InputOffset() int64 {
+ return d.s.TotalOffset()
+}
+
+// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
+// Number instead of as a float64.
+func (d *Decoder) UseNumber() {
+ d.s.UseNumber = true
+}
diff --git a/vendor/github.com/goccy/go-json/docker-compose.yml b/vendor/github.com/goccy/go-json/docker-compose.yml
new file mode 100644
index 00000000..db40c79a
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/docker-compose.yml
@@ -0,0 +1,13 @@
+version: '2'
+services:
+ go-json:
+ image: golang:1.18
+ volumes:
+ - '.:/go/src/go-json'
+ deploy:
+ resources:
+ limits:
+ memory: 620M
+ working_dir: /go/src/go-json
+ command: |
+ sh -c "go test -c . && ls go-json.test"
diff --git a/vendor/github.com/goccy/go-json/encode.go b/vendor/github.com/goccy/go-json/encode.go
new file mode 100644
index 00000000..c5173825
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/encode.go
@@ -0,0 +1,326 @@
+package json
+
+import (
+ "context"
+ "io"
+ "os"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/encoder"
+ "github.com/goccy/go-json/internal/encoder/vm"
+ "github.com/goccy/go-json/internal/encoder/vm_color"
+ "github.com/goccy/go-json/internal/encoder/vm_color_indent"
+ "github.com/goccy/go-json/internal/encoder/vm_indent"
+)
+
+// An Encoder writes JSON values to an output stream.
+type Encoder struct {
+ w io.Writer
+ enabledIndent bool
+ enabledHTMLEscape bool
+ prefix string
+ indentStr string
+}
+
+// NewEncoder returns a new encoder that writes to w.
+func NewEncoder(w io.Writer) *Encoder {
+ return &Encoder{w: w, enabledHTMLEscape: true}
+}
+
+// Encode writes the JSON encoding of v to the stream, followed by a newline character.
+//
+// See the documentation for Marshal for details about the conversion of Go values to JSON.
+func (e *Encoder) Encode(v interface{}) error {
+ return e.EncodeWithOption(v)
+}
+
+// EncodeWithOption call Encode with EncodeOption.
+func (e *Encoder) EncodeWithOption(v interface{}, optFuncs ...EncodeOptionFunc) error {
+ ctx := encoder.TakeRuntimeContext()
+ ctx.Option.Flag = 0
+
+ err := e.encodeWithOption(ctx, v, optFuncs...)
+
+ encoder.ReleaseRuntimeContext(ctx)
+ return err
+}
+
+// EncodeContext call Encode with context.Context and EncodeOption.
+func (e *Encoder) EncodeContext(ctx context.Context, v interface{}, optFuncs ...EncodeOptionFunc) error {
+ rctx := encoder.TakeRuntimeContext()
+ rctx.Option.Flag = 0
+ rctx.Option.Flag |= encoder.ContextOption
+ rctx.Option.Context = ctx
+
+ err := e.encodeWithOption(rctx, v, optFuncs...) //nolint: contextcheck
+
+ encoder.ReleaseRuntimeContext(rctx)
+ return err
+}
+
+func (e *Encoder) encodeWithOption(ctx *encoder.RuntimeContext, v interface{}, optFuncs ...EncodeOptionFunc) error {
+ if e.enabledHTMLEscape {
+ ctx.Option.Flag |= encoder.HTMLEscapeOption
+ }
+ ctx.Option.Flag |= encoder.NormalizeUTF8Option
+ ctx.Option.DebugOut = os.Stdout
+ for _, optFunc := range optFuncs {
+ optFunc(ctx.Option)
+ }
+ var (
+ buf []byte
+ err error
+ )
+ if e.enabledIndent {
+ buf, err = encodeIndent(ctx, v, e.prefix, e.indentStr)
+ } else {
+ buf, err = encode(ctx, v)
+ }
+ if err != nil {
+ return err
+ }
+ if e.enabledIndent {
+ buf = buf[:len(buf)-2]
+ } else {
+ buf = buf[:len(buf)-1]
+ }
+ buf = append(buf, '\n')
+ if _, err := e.w.Write(buf); err != nil {
+ return err
+ }
+ return nil
+}
+
+// SetEscapeHTML specifies whether problematic HTML characters should be escaped inside JSON quoted strings.
+// The default behavior is to escape &, <, and > to \u0026, \u003c, and \u003e to avoid certain safety problems that can arise when embedding JSON in HTML.
+//
+// In non-HTML settings where the escaping interferes with the readability of the output, SetEscapeHTML(false) disables this behavior.
+func (e *Encoder) SetEscapeHTML(on bool) {
+ e.enabledHTMLEscape = on
+}
+
+// SetIndent instructs the encoder to format each subsequent encoded value as if indented by the package-level function Indent(dst, src, prefix, indent).
+// Calling SetIndent("", "") disables indentation.
+func (e *Encoder) SetIndent(prefix, indent string) {
+ if prefix == "" && indent == "" {
+ e.enabledIndent = false
+ return
+ }
+ e.prefix = prefix
+ e.indentStr = indent
+ e.enabledIndent = true
+}
+
+func marshalContext(ctx context.Context, v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) {
+ rctx := encoder.TakeRuntimeContext()
+ rctx.Option.Flag = 0
+ rctx.Option.Flag = encoder.HTMLEscapeOption | encoder.NormalizeUTF8Option | encoder.ContextOption
+ rctx.Option.Context = ctx
+ for _, optFunc := range optFuncs {
+ optFunc(rctx.Option)
+ }
+
+ buf, err := encode(rctx, v) //nolint: contextcheck
+ if err != nil {
+ encoder.ReleaseRuntimeContext(rctx)
+ return nil, err
+ }
+
+ // this line exists to escape call of `runtime.makeslicecopy` .
+ // if use `make([]byte, len(buf)-1)` and `copy(copied, buf)`,
+ // dst buffer size and src buffer size are differrent.
+ // in this case, compiler uses `runtime.makeslicecopy`, but it is slow.
+ buf = buf[:len(buf)-1]
+ copied := make([]byte, len(buf))
+ copy(copied, buf)
+
+ encoder.ReleaseRuntimeContext(rctx)
+ return copied, nil
+}
+
+func marshal(v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) {
+ ctx := encoder.TakeRuntimeContext()
+
+ ctx.Option.Flag = 0
+ ctx.Option.Flag |= (encoder.HTMLEscapeOption | encoder.NormalizeUTF8Option)
+ for _, optFunc := range optFuncs {
+ optFunc(ctx.Option)
+ }
+
+ buf, err := encode(ctx, v)
+ if err != nil {
+ encoder.ReleaseRuntimeContext(ctx)
+ return nil, err
+ }
+
+ // this line exists to escape call of `runtime.makeslicecopy` .
+ // if use `make([]byte, len(buf)-1)` and `copy(copied, buf)`,
+ // dst buffer size and src buffer size are differrent.
+ // in this case, compiler uses `runtime.makeslicecopy`, but it is slow.
+ buf = buf[:len(buf)-1]
+ copied := make([]byte, len(buf))
+ copy(copied, buf)
+
+ encoder.ReleaseRuntimeContext(ctx)
+ return copied, nil
+}
+
+func marshalNoEscape(v interface{}) ([]byte, error) {
+ ctx := encoder.TakeRuntimeContext()
+
+ ctx.Option.Flag = 0
+ ctx.Option.Flag |= (encoder.HTMLEscapeOption | encoder.NormalizeUTF8Option)
+
+ buf, err := encodeNoEscape(ctx, v)
+ if err != nil {
+ encoder.ReleaseRuntimeContext(ctx)
+ return nil, err
+ }
+
+ // this line exists to escape call of `runtime.makeslicecopy` .
+ // if use `make([]byte, len(buf)-1)` and `copy(copied, buf)`,
+ // dst buffer size and src buffer size are differrent.
+ // in this case, compiler uses `runtime.makeslicecopy`, but it is slow.
+ buf = buf[:len(buf)-1]
+ copied := make([]byte, len(buf))
+ copy(copied, buf)
+
+ encoder.ReleaseRuntimeContext(ctx)
+ return copied, nil
+}
+
+func marshalIndent(v interface{}, prefix, indent string, optFuncs ...EncodeOptionFunc) ([]byte, error) {
+ ctx := encoder.TakeRuntimeContext()
+
+ ctx.Option.Flag = 0
+ ctx.Option.Flag |= (encoder.HTMLEscapeOption | encoder.NormalizeUTF8Option | encoder.IndentOption)
+ for _, optFunc := range optFuncs {
+ optFunc(ctx.Option)
+ }
+
+ buf, err := encodeIndent(ctx, v, prefix, indent)
+ if err != nil {
+ encoder.ReleaseRuntimeContext(ctx)
+ return nil, err
+ }
+
+ buf = buf[:len(buf)-2]
+ copied := make([]byte, len(buf))
+ copy(copied, buf)
+
+ encoder.ReleaseRuntimeContext(ctx)
+ return copied, nil
+}
+
+func encode(ctx *encoder.RuntimeContext, v interface{}) ([]byte, error) {
+ b := ctx.Buf[:0]
+ if v == nil {
+ b = encoder.AppendNull(ctx, b)
+ b = encoder.AppendComma(ctx, b)
+ return b, nil
+ }
+ header := (*emptyInterface)(unsafe.Pointer(&v))
+ typ := header.typ
+
+ typeptr := uintptr(unsafe.Pointer(typ))
+ codeSet, err := encoder.CompileToGetCodeSet(ctx, typeptr)
+ if err != nil {
+ return nil, err
+ }
+
+ p := uintptr(header.ptr)
+ ctx.Init(p, codeSet.CodeLength)
+ ctx.KeepRefs = append(ctx.KeepRefs, header.ptr)
+
+ buf, err := encodeRunCode(ctx, b, codeSet)
+ if err != nil {
+ return nil, err
+ }
+ ctx.Buf = buf
+ return buf, nil
+}
+
+func encodeNoEscape(ctx *encoder.RuntimeContext, v interface{}) ([]byte, error) {
+ b := ctx.Buf[:0]
+ if v == nil {
+ b = encoder.AppendNull(ctx, b)
+ b = encoder.AppendComma(ctx, b)
+ return b, nil
+ }
+ header := (*emptyInterface)(unsafe.Pointer(&v))
+ typ := header.typ
+
+ typeptr := uintptr(unsafe.Pointer(typ))
+ codeSet, err := encoder.CompileToGetCodeSet(ctx, typeptr)
+ if err != nil {
+ return nil, err
+ }
+
+ p := uintptr(header.ptr)
+ ctx.Init(p, codeSet.CodeLength)
+ buf, err := encodeRunCode(ctx, b, codeSet)
+ if err != nil {
+ return nil, err
+ }
+
+ ctx.Buf = buf
+ return buf, nil
+}
+
+func encodeIndent(ctx *encoder.RuntimeContext, v interface{}, prefix, indent string) ([]byte, error) {
+ b := ctx.Buf[:0]
+ if v == nil {
+ b = encoder.AppendNull(ctx, b)
+ b = encoder.AppendCommaIndent(ctx, b)
+ return b, nil
+ }
+ header := (*emptyInterface)(unsafe.Pointer(&v))
+ typ := header.typ
+
+ typeptr := uintptr(unsafe.Pointer(typ))
+ codeSet, err := encoder.CompileToGetCodeSet(ctx, typeptr)
+ if err != nil {
+ return nil, err
+ }
+
+ p := uintptr(header.ptr)
+ ctx.Init(p, codeSet.CodeLength)
+ buf, err := encodeRunIndentCode(ctx, b, codeSet, prefix, indent)
+
+ ctx.KeepRefs = append(ctx.KeepRefs, header.ptr)
+
+ if err != nil {
+ return nil, err
+ }
+
+ ctx.Buf = buf
+ return buf, nil
+}
+
+func encodeRunCode(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
+ if (ctx.Option.Flag & encoder.DebugOption) != 0 {
+ if (ctx.Option.Flag & encoder.ColorizeOption) != 0 {
+ return vm_color.DebugRun(ctx, b, codeSet)
+ }
+ return vm.DebugRun(ctx, b, codeSet)
+ }
+ if (ctx.Option.Flag & encoder.ColorizeOption) != 0 {
+ return vm_color.Run(ctx, b, codeSet)
+ }
+ return vm.Run(ctx, b, codeSet)
+}
+
+func encodeRunIndentCode(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, prefix, indent string) ([]byte, error) {
+ ctx.Prefix = []byte(prefix)
+ ctx.IndentStr = []byte(indent)
+ if (ctx.Option.Flag & encoder.DebugOption) != 0 {
+ if (ctx.Option.Flag & encoder.ColorizeOption) != 0 {
+ return vm_color_indent.DebugRun(ctx, b, codeSet)
+ }
+ return vm_indent.DebugRun(ctx, b, codeSet)
+ }
+ if (ctx.Option.Flag & encoder.ColorizeOption) != 0 {
+ return vm_color_indent.Run(ctx, b, codeSet)
+ }
+ return vm_indent.Run(ctx, b, codeSet)
+}
diff --git a/vendor/github.com/goccy/go-json/error.go b/vendor/github.com/goccy/go-json/error.go
new file mode 100644
index 00000000..5b2dcee5
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/error.go
@@ -0,0 +1,41 @@
+package json
+
+import (
+ "github.com/goccy/go-json/internal/errors"
+)
+
+// Before Go 1.2, an InvalidUTF8Error was returned by Marshal when
+// attempting to encode a string value with invalid UTF-8 sequences.
+// As of Go 1.2, Marshal instead coerces the string to valid UTF-8 by
+// replacing invalid bytes with the Unicode replacement rune U+FFFD.
+//
+// Deprecated: No longer used; kept for compatibility.
+type InvalidUTF8Error = errors.InvalidUTF8Error
+
+// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
+// (The argument to Unmarshal must be a non-nil pointer.)
+type InvalidUnmarshalError = errors.InvalidUnmarshalError
+
+// A MarshalerError represents an error from calling a MarshalJSON or MarshalText method.
+type MarshalerError = errors.MarshalerError
+
+// A SyntaxError is a description of a JSON syntax error.
+type SyntaxError = errors.SyntaxError
+
+// An UnmarshalFieldError describes a JSON object key that
+// led to an unexported (and therefore unwritable) struct field.
+//
+// Deprecated: No longer used; kept for compatibility.
+type UnmarshalFieldError = errors.UnmarshalFieldError
+
+// An UnmarshalTypeError describes a JSON value that was
+// not appropriate for a value of a specific Go type.
+type UnmarshalTypeError = errors.UnmarshalTypeError
+
+// An UnsupportedTypeError is returned by Marshal when attempting
+// to encode an unsupported value type.
+type UnsupportedTypeError = errors.UnsupportedTypeError
+
+type UnsupportedValueError = errors.UnsupportedValueError
+
+type PathError = errors.PathError
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go b/vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go
new file mode 100644
index 00000000..b6876cf0
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go
@@ -0,0 +1,41 @@
+package decoder
+
+import (
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type anonymousFieldDecoder struct {
+ structType *runtime.Type
+ offset uintptr
+ dec Decoder
+}
+
+func newAnonymousFieldDecoder(structType *runtime.Type, offset uintptr, dec Decoder) *anonymousFieldDecoder {
+ return &anonymousFieldDecoder{
+ structType: structType,
+ offset: offset,
+ dec: dec,
+ }
+}
+
+func (d *anonymousFieldDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ if *(*unsafe.Pointer)(p) == nil {
+ *(*unsafe.Pointer)(p) = unsafe_New(d.structType)
+ }
+ p = *(*unsafe.Pointer)(p)
+ return d.dec.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+d.offset))
+}
+
+func (d *anonymousFieldDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ if *(*unsafe.Pointer)(p) == nil {
+ *(*unsafe.Pointer)(p) = unsafe_New(d.structType)
+ }
+ p = *(*unsafe.Pointer)(p)
+ return d.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+d.offset))
+}
+
+func (d *anonymousFieldDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ return d.dec.DecodePath(ctx, cursor, depth)
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/array.go b/vendor/github.com/goccy/go-json/internal/decoder/array.go
new file mode 100644
index 00000000..4b23ed43
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/array.go
@@ -0,0 +1,176 @@
+package decoder
+
+import (
+ "fmt"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type arrayDecoder struct {
+ elemType *runtime.Type
+ size uintptr
+ valueDecoder Decoder
+ alen int
+ structName string
+ fieldName string
+ zeroValue unsafe.Pointer
+}
+
+func newArrayDecoder(dec Decoder, elemType *runtime.Type, alen int, structName, fieldName string) *arrayDecoder {
+ // workaround to avoid checkptr errors. cannot use `*(*unsafe.Pointer)(unsafe_New(elemType))` directly.
+ zeroValuePtr := unsafe_New(elemType)
+ zeroValue := **(**unsafe.Pointer)(unsafe.Pointer(&zeroValuePtr))
+ return &arrayDecoder{
+ valueDecoder: dec,
+ elemType: elemType,
+ size: elemType.Size(),
+ alen: alen,
+ structName: structName,
+ fieldName: fieldName,
+ zeroValue: zeroValue,
+ }
+}
+
+func (d *arrayDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return errors.ErrExceededMaxDepth(s.char(), s.cursor)
+ }
+
+ for {
+ switch s.char() {
+ case ' ', '\n', '\t', '\r':
+ case 'n':
+ if err := nullBytes(s); err != nil {
+ return err
+ }
+ return nil
+ case '[':
+ idx := 0
+ s.cursor++
+ if s.skipWhiteSpace() == ']' {
+ for idx < d.alen {
+ *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue
+ idx++
+ }
+ s.cursor++
+ return nil
+ }
+ for {
+ if idx < d.alen {
+ if err := d.valueDecoder.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+uintptr(idx)*d.size)); err != nil {
+ return err
+ }
+ } else {
+ if err := s.skipValue(depth); err != nil {
+ return err
+ }
+ }
+ idx++
+ switch s.skipWhiteSpace() {
+ case ']':
+ for idx < d.alen {
+ *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue
+ idx++
+ }
+ s.cursor++
+ return nil
+ case ',':
+ s.cursor++
+ continue
+ case nul:
+ if s.read() {
+ s.cursor++
+ continue
+ }
+ goto ERROR
+ default:
+ goto ERROR
+ }
+ }
+ case nul:
+ if s.read() {
+ continue
+ }
+ goto ERROR
+ default:
+ goto ERROR
+ }
+ s.cursor++
+ }
+ERROR:
+ return errors.ErrUnexpectedEndOfJSON("array", s.totalOffset())
+}
+
+func (d *arrayDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ buf := ctx.Buf
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
+ }
+
+ for {
+ switch buf[cursor] {
+ case ' ', '\n', '\t', '\r':
+ cursor++
+ continue
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return 0, err
+ }
+ cursor += 4
+ return cursor, nil
+ case '[':
+ idx := 0
+ cursor++
+ cursor = skipWhiteSpace(buf, cursor)
+ if buf[cursor] == ']' {
+ for idx < d.alen {
+ *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue
+ idx++
+ }
+ cursor++
+ return cursor, nil
+ }
+ for {
+ if idx < d.alen {
+ c, err := d.valueDecoder.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+uintptr(idx)*d.size))
+ if err != nil {
+ return 0, err
+ }
+ cursor = c
+ } else {
+ c, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return 0, err
+ }
+ cursor = c
+ }
+ idx++
+ cursor = skipWhiteSpace(buf, cursor)
+ switch buf[cursor] {
+ case ']':
+ for idx < d.alen {
+ *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue
+ idx++
+ }
+ cursor++
+ return cursor, nil
+ case ',':
+ cursor++
+ continue
+ default:
+ return 0, errors.ErrInvalidCharacter(buf[cursor], "array", cursor)
+ }
+ }
+ default:
+ return 0, errors.ErrUnexpectedEndOfJSON("array", cursor)
+ }
+ }
+}
+
+func (d *arrayDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ return nil, 0, fmt.Errorf("json: array decoder does not support decode path")
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/assign.go b/vendor/github.com/goccy/go-json/internal/decoder/assign.go
new file mode 100644
index 00000000..c53e6ad9
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/assign.go
@@ -0,0 +1,438 @@
+package decoder
+
+import (
+ "fmt"
+ "reflect"
+ "strconv"
+)
+
+var (
+ nilValue = reflect.ValueOf(nil)
+)
+
+func AssignValue(src, dst reflect.Value) error {
+ if dst.Type().Kind() != reflect.Ptr {
+ return fmt.Errorf("invalid dst type. required pointer type: %T", dst.Type())
+ }
+ casted, err := castValue(dst.Elem().Type(), src)
+ if err != nil {
+ return err
+ }
+ dst.Elem().Set(casted)
+ return nil
+}
+
+func castValue(t reflect.Type, v reflect.Value) (reflect.Value, error) {
+ switch t.Kind() {
+ case reflect.Int:
+ vv, err := castInt(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(int(vv.Int())), nil
+ case reflect.Int8:
+ vv, err := castInt(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(int8(vv.Int())), nil
+ case reflect.Int16:
+ vv, err := castInt(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(int16(vv.Int())), nil
+ case reflect.Int32:
+ vv, err := castInt(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(int32(vv.Int())), nil
+ case reflect.Int64:
+ return castInt(v)
+ case reflect.Uint:
+ vv, err := castUint(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(uint(vv.Uint())), nil
+ case reflect.Uint8:
+ vv, err := castUint(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(uint8(vv.Uint())), nil
+ case reflect.Uint16:
+ vv, err := castUint(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(uint16(vv.Uint())), nil
+ case reflect.Uint32:
+ vv, err := castUint(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(uint32(vv.Uint())), nil
+ case reflect.Uint64:
+ return castUint(v)
+ case reflect.Uintptr:
+ vv, err := castUint(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(uintptr(vv.Uint())), nil
+ case reflect.String:
+ return castString(v)
+ case reflect.Bool:
+ return castBool(v)
+ case reflect.Float32:
+ vv, err := castFloat(v)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(float32(vv.Float())), nil
+ case reflect.Float64:
+ return castFloat(v)
+ case reflect.Array:
+ return castArray(t, v)
+ case reflect.Slice:
+ return castSlice(t, v)
+ case reflect.Map:
+ return castMap(t, v)
+ case reflect.Struct:
+ return castStruct(t, v)
+ }
+ return v, nil
+}
+
+func castInt(v reflect.Value) (reflect.Value, error) {
+ switch v.Type().Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return v, nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return reflect.ValueOf(int64(v.Uint())), nil
+ case reflect.String:
+ i64, err := strconv.ParseInt(v.String(), 10, 64)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(i64), nil
+ case reflect.Bool:
+ if v.Bool() {
+ return reflect.ValueOf(int64(1)), nil
+ }
+ return reflect.ValueOf(int64(0)), nil
+ case reflect.Float32, reflect.Float64:
+ return reflect.ValueOf(int64(v.Float())), nil
+ case reflect.Array:
+ if v.Len() > 0 {
+ return castInt(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to int64 from empty array")
+ case reflect.Slice:
+ if v.Len() > 0 {
+ return castInt(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to int64 from empty slice")
+ case reflect.Interface:
+ return castInt(reflect.ValueOf(v.Interface()))
+ case reflect.Map:
+ return nilValue, fmt.Errorf("failed to cast to int64 from map")
+ case reflect.Struct:
+ return nilValue, fmt.Errorf("failed to cast to int64 from struct")
+ case reflect.Ptr:
+ return castInt(v.Elem())
+ }
+ return nilValue, fmt.Errorf("failed to cast to int64 from %s", v.Type().Kind())
+}
+
+func castUint(v reflect.Value) (reflect.Value, error) {
+ switch v.Type().Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return reflect.ValueOf(uint64(v.Int())), nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return v, nil
+ case reflect.String:
+ u64, err := strconv.ParseUint(v.String(), 10, 64)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(u64), nil
+ case reflect.Bool:
+ if v.Bool() {
+ return reflect.ValueOf(uint64(1)), nil
+ }
+ return reflect.ValueOf(uint64(0)), nil
+ case reflect.Float32, reflect.Float64:
+ return reflect.ValueOf(uint64(v.Float())), nil
+ case reflect.Array:
+ if v.Len() > 0 {
+ return castUint(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to uint64 from empty array")
+ case reflect.Slice:
+ if v.Len() > 0 {
+ return castUint(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to uint64 from empty slice")
+ case reflect.Interface:
+ return castUint(reflect.ValueOf(v.Interface()))
+ case reflect.Map:
+ return nilValue, fmt.Errorf("failed to cast to uint64 from map")
+ case reflect.Struct:
+ return nilValue, fmt.Errorf("failed to cast to uint64 from struct")
+ case reflect.Ptr:
+ return castUint(v.Elem())
+ }
+ return nilValue, fmt.Errorf("failed to cast to uint64 from %s", v.Type().Kind())
+}
+
+func castString(v reflect.Value) (reflect.Value, error) {
+ switch v.Type().Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return reflect.ValueOf(fmt.Sprint(v.Int())), nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return reflect.ValueOf(fmt.Sprint(v.Uint())), nil
+ case reflect.String:
+ return v, nil
+ case reflect.Bool:
+ if v.Bool() {
+ return reflect.ValueOf("true"), nil
+ }
+ return reflect.ValueOf("false"), nil
+ case reflect.Float32, reflect.Float64:
+ return reflect.ValueOf(fmt.Sprint(v.Float())), nil
+ case reflect.Array:
+ if v.Len() > 0 {
+ return castString(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to string from empty array")
+ case reflect.Slice:
+ if v.Len() > 0 {
+ return castString(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to string from empty slice")
+ case reflect.Interface:
+ return castString(reflect.ValueOf(v.Interface()))
+ case reflect.Map:
+ return nilValue, fmt.Errorf("failed to cast to string from map")
+ case reflect.Struct:
+ return nilValue, fmt.Errorf("failed to cast to string from struct")
+ case reflect.Ptr:
+ return castString(v.Elem())
+ }
+ return nilValue, fmt.Errorf("failed to cast to string from %s", v.Type().Kind())
+}
+
+func castBool(v reflect.Value) (reflect.Value, error) {
+ switch v.Type().Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ switch v.Int() {
+ case 0:
+ return reflect.ValueOf(false), nil
+ case 1:
+ return reflect.ValueOf(true), nil
+ }
+ return nilValue, fmt.Errorf("failed to cast to bool from %d", v.Int())
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ switch v.Uint() {
+ case 0:
+ return reflect.ValueOf(false), nil
+ case 1:
+ return reflect.ValueOf(true), nil
+ }
+ return nilValue, fmt.Errorf("failed to cast to bool from %d", v.Uint())
+ case reflect.String:
+ b, err := strconv.ParseBool(v.String())
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(b), nil
+ case reflect.Bool:
+ return v, nil
+ case reflect.Float32, reflect.Float64:
+ switch v.Float() {
+ case 0:
+ return reflect.ValueOf(false), nil
+ case 1:
+ return reflect.ValueOf(true), nil
+ }
+ return nilValue, fmt.Errorf("failed to cast to bool from %f", v.Float())
+ case reflect.Array:
+ if v.Len() > 0 {
+ return castBool(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to string from empty array")
+ case reflect.Slice:
+ if v.Len() > 0 {
+ return castBool(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to string from empty slice")
+ case reflect.Interface:
+ return castBool(reflect.ValueOf(v.Interface()))
+ case reflect.Map:
+ return nilValue, fmt.Errorf("failed to cast to string from map")
+ case reflect.Struct:
+ return nilValue, fmt.Errorf("failed to cast to string from struct")
+ case reflect.Ptr:
+ return castBool(v.Elem())
+ }
+ return nilValue, fmt.Errorf("failed to cast to bool from %s", v.Type().Kind())
+}
+
+func castFloat(v reflect.Value) (reflect.Value, error) {
+ switch v.Type().Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return reflect.ValueOf(float64(v.Int())), nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return reflect.ValueOf(float64(v.Uint())), nil
+ case reflect.String:
+ f64, err := strconv.ParseFloat(v.String(), 64)
+ if err != nil {
+ return nilValue, err
+ }
+ return reflect.ValueOf(f64), nil
+ case reflect.Bool:
+ if v.Bool() {
+ return reflect.ValueOf(float64(1)), nil
+ }
+ return reflect.ValueOf(float64(0)), nil
+ case reflect.Float32, reflect.Float64:
+ return v, nil
+ case reflect.Array:
+ if v.Len() > 0 {
+ return castFloat(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to float64 from empty array")
+ case reflect.Slice:
+ if v.Len() > 0 {
+ return castFloat(v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to float64 from empty slice")
+ case reflect.Interface:
+ return castFloat(reflect.ValueOf(v.Interface()))
+ case reflect.Map:
+ return nilValue, fmt.Errorf("failed to cast to float64 from map")
+ case reflect.Struct:
+ return nilValue, fmt.Errorf("failed to cast to float64 from struct")
+ case reflect.Ptr:
+ return castFloat(v.Elem())
+ }
+ return nilValue, fmt.Errorf("failed to cast to float64 from %s", v.Type().Kind())
+}
+
+func castArray(t reflect.Type, v reflect.Value) (reflect.Value, error) {
+ kind := v.Type().Kind()
+ if kind == reflect.Interface {
+ return castArray(t, reflect.ValueOf(v.Interface()))
+ }
+ if kind != reflect.Slice && kind != reflect.Array {
+ return nilValue, fmt.Errorf("failed to cast to array from %s", kind)
+ }
+ if t.Elem() == v.Type().Elem() {
+ return v, nil
+ }
+ if t.Len() != v.Len() {
+ return nilValue, fmt.Errorf("failed to cast [%d]array from slice of %d length", t.Len(), v.Len())
+ }
+ ret := reflect.New(t).Elem()
+ for i := 0; i < v.Len(); i++ {
+ vv, err := castValue(t.Elem(), v.Index(i))
+ if err != nil {
+ return nilValue, err
+ }
+ ret.Index(i).Set(vv)
+ }
+ return ret, nil
+}
+
+func castSlice(t reflect.Type, v reflect.Value) (reflect.Value, error) {
+ kind := v.Type().Kind()
+ if kind == reflect.Interface {
+ return castSlice(t, reflect.ValueOf(v.Interface()))
+ }
+ if kind != reflect.Slice && kind != reflect.Array {
+ return nilValue, fmt.Errorf("failed to cast to slice from %s", kind)
+ }
+ if t.Elem() == v.Type().Elem() {
+ return v, nil
+ }
+ ret := reflect.MakeSlice(t, v.Len(), v.Len())
+ for i := 0; i < v.Len(); i++ {
+ vv, err := castValue(t.Elem(), v.Index(i))
+ if err != nil {
+ return nilValue, err
+ }
+ ret.Index(i).Set(vv)
+ }
+ return ret, nil
+}
+
+func castMap(t reflect.Type, v reflect.Value) (reflect.Value, error) {
+ ret := reflect.MakeMap(t)
+ switch v.Type().Kind() {
+ case reflect.Map:
+ iter := v.MapRange()
+ for iter.Next() {
+ key, err := castValue(t.Key(), iter.Key())
+ if err != nil {
+ return nilValue, err
+ }
+ value, err := castValue(t.Elem(), iter.Value())
+ if err != nil {
+ return nilValue, err
+ }
+ ret.SetMapIndex(key, value)
+ }
+ return ret, nil
+ case reflect.Interface:
+ return castMap(t, reflect.ValueOf(v.Interface()))
+ case reflect.Slice:
+ if v.Len() > 0 {
+ return castMap(t, v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to map from empty slice")
+ }
+ return nilValue, fmt.Errorf("failed to cast to map from %s", v.Type().Kind())
+}
+
+func castStruct(t reflect.Type, v reflect.Value) (reflect.Value, error) {
+ ret := reflect.New(t).Elem()
+ switch v.Type().Kind() {
+ case reflect.Map:
+ iter := v.MapRange()
+ for iter.Next() {
+ key := iter.Key()
+ k, err := castString(key)
+ if err != nil {
+ return nilValue, err
+ }
+ fieldName := k.String()
+ field, ok := t.FieldByName(fieldName)
+ if ok {
+ value, err := castValue(field.Type, iter.Value())
+ if err != nil {
+ return nilValue, err
+ }
+ ret.FieldByName(fieldName).Set(value)
+ }
+ }
+ return ret, nil
+ case reflect.Struct:
+ for i := 0; i < v.Type().NumField(); i++ {
+ name := v.Type().Field(i).Name
+ ret.FieldByName(name).Set(v.FieldByName(name))
+ }
+ return ret, nil
+ case reflect.Interface:
+ return castStruct(t, reflect.ValueOf(v.Interface()))
+ case reflect.Slice:
+ if v.Len() > 0 {
+ return castStruct(t, v.Index(0))
+ }
+ return nilValue, fmt.Errorf("failed to cast to struct from empty slice")
+ default:
+ return nilValue, fmt.Errorf("failed to cast to struct from %s", v.Type().Kind())
+ }
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/bool.go b/vendor/github.com/goccy/go-json/internal/decoder/bool.go
new file mode 100644
index 00000000..ba6cf5bc
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/bool.go
@@ -0,0 +1,83 @@
+package decoder
+
+import (
+ "fmt"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+)
+
+type boolDecoder struct {
+ structName string
+ fieldName string
+}
+
+func newBoolDecoder(structName, fieldName string) *boolDecoder {
+ return &boolDecoder{structName: structName, fieldName: fieldName}
+}
+
+func (d *boolDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ c := s.skipWhiteSpace()
+ for {
+ switch c {
+ case 't':
+ if err := trueBytes(s); err != nil {
+ return err
+ }
+ **(**bool)(unsafe.Pointer(&p)) = true
+ return nil
+ case 'f':
+ if err := falseBytes(s); err != nil {
+ return err
+ }
+ **(**bool)(unsafe.Pointer(&p)) = false
+ return nil
+ case 'n':
+ if err := nullBytes(s); err != nil {
+ return err
+ }
+ return nil
+ case nul:
+ if s.read() {
+ c = s.char()
+ continue
+ }
+ goto ERROR
+ }
+ break
+ }
+ERROR:
+ return errors.ErrUnexpectedEndOfJSON("bool", s.totalOffset())
+}
+
+func (d *boolDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ buf := ctx.Buf
+ cursor = skipWhiteSpace(buf, cursor)
+ switch buf[cursor] {
+ case 't':
+ if err := validateTrue(buf, cursor); err != nil {
+ return 0, err
+ }
+ cursor += 4
+ **(**bool)(unsafe.Pointer(&p)) = true
+ return cursor, nil
+ case 'f':
+ if err := validateFalse(buf, cursor); err != nil {
+ return 0, err
+ }
+ cursor += 5
+ **(**bool)(unsafe.Pointer(&p)) = false
+ return cursor, nil
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return 0, err
+ }
+ cursor += 4
+ return cursor, nil
+ }
+ return 0, errors.ErrUnexpectedEndOfJSON("bool", cursor)
+}
+
+func (d *boolDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ return nil, 0, fmt.Errorf("json: bool decoder does not support decode path")
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/bytes.go b/vendor/github.com/goccy/go-json/internal/decoder/bytes.go
new file mode 100644
index 00000000..939bf432
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/bytes.go
@@ -0,0 +1,118 @@
+package decoder
+
+import (
+ "encoding/base64"
+ "fmt"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type bytesDecoder struct {
+ typ *runtime.Type
+ sliceDecoder Decoder
+ stringDecoder *stringDecoder
+ structName string
+ fieldName string
+}
+
+func byteUnmarshalerSliceDecoder(typ *runtime.Type, structName string, fieldName string) Decoder {
+ var unmarshalDecoder Decoder
+ switch {
+ case runtime.PtrTo(typ).Implements(unmarshalJSONType):
+ unmarshalDecoder = newUnmarshalJSONDecoder(runtime.PtrTo(typ), structName, fieldName)
+ case runtime.PtrTo(typ).Implements(unmarshalTextType):
+ unmarshalDecoder = newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName)
+ default:
+ unmarshalDecoder, _ = compileUint8(typ, structName, fieldName)
+ }
+ return newSliceDecoder(unmarshalDecoder, typ, 1, structName, fieldName)
+}
+
+func newBytesDecoder(typ *runtime.Type, structName string, fieldName string) *bytesDecoder {
+ return &bytesDecoder{
+ typ: typ,
+ sliceDecoder: byteUnmarshalerSliceDecoder(typ, structName, fieldName),
+ stringDecoder: newStringDecoder(structName, fieldName),
+ structName: structName,
+ fieldName: fieldName,
+ }
+}
+
+func (d *bytesDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ bytes, err := d.decodeStreamBinary(s, depth, p)
+ if err != nil {
+ return err
+ }
+ if bytes == nil {
+ s.reset()
+ return nil
+ }
+ decodedLen := base64.StdEncoding.DecodedLen(len(bytes))
+ buf := make([]byte, decodedLen)
+ n, err := base64.StdEncoding.Decode(buf, bytes)
+ if err != nil {
+ return err
+ }
+ *(*[]byte)(p) = buf[:n]
+ s.reset()
+ return nil
+}
+
+func (d *bytesDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ bytes, c, err := d.decodeBinary(ctx, cursor, depth, p)
+ if err != nil {
+ return 0, err
+ }
+ if bytes == nil {
+ return c, nil
+ }
+ cursor = c
+ decodedLen := base64.StdEncoding.DecodedLen(len(bytes))
+ b := make([]byte, decodedLen)
+ n, err := base64.StdEncoding.Decode(b, bytes)
+ if err != nil {
+ return 0, err
+ }
+ *(*[]byte)(p) = b[:n]
+ return cursor, nil
+}
+
+func (d *bytesDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ return nil, 0, fmt.Errorf("json: []byte decoder does not support decode path")
+}
+
+func (d *bytesDecoder) decodeStreamBinary(s *Stream, depth int64, p unsafe.Pointer) ([]byte, error) {
+ c := s.skipWhiteSpace()
+ if c == '[' {
+ if d.sliceDecoder == nil {
+ return nil, &errors.UnmarshalTypeError{
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ }
+ }
+ err := d.sliceDecoder.DecodeStream(s, depth, p)
+ return nil, err
+ }
+ return d.stringDecoder.decodeStreamByte(s)
+}
+
+func (d *bytesDecoder) decodeBinary(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) ([]byte, int64, error) {
+ buf := ctx.Buf
+ cursor = skipWhiteSpace(buf, cursor)
+ if buf[cursor] == '[' {
+ if d.sliceDecoder == nil {
+ return nil, 0, &errors.UnmarshalTypeError{
+ Type: runtime.RType2Type(d.typ),
+ Offset: cursor,
+ }
+ }
+ c, err := d.sliceDecoder.Decode(ctx, cursor, depth, p)
+ if err != nil {
+ return nil, 0, err
+ }
+ return nil, c, nil
+ }
+ return d.stringDecoder.decodeByte(buf, cursor)
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/compile.go b/vendor/github.com/goccy/go-json/internal/decoder/compile.go
new file mode 100644
index 00000000..fab64376
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/compile.go
@@ -0,0 +1,487 @@
+package decoder
+
+import (
+ "encoding/json"
+ "fmt"
+ "reflect"
+ "strings"
+ "sync/atomic"
+ "unicode"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+var (
+ jsonNumberType = reflect.TypeOf(json.Number(""))
+ typeAddr *runtime.TypeAddr
+ cachedDecoderMap unsafe.Pointer // map[uintptr]decoder
+ cachedDecoder []Decoder
+)
+
+func init() {
+ typeAddr = runtime.AnalyzeTypeAddr()
+ if typeAddr == nil {
+ typeAddr = &runtime.TypeAddr{}
+ }
+ cachedDecoder = make([]Decoder, typeAddr.AddrRange>>typeAddr.AddrShift+1)
+}
+
+func loadDecoderMap() map[uintptr]Decoder {
+ p := atomic.LoadPointer(&cachedDecoderMap)
+ return *(*map[uintptr]Decoder)(unsafe.Pointer(&p))
+}
+
+func storeDecoder(typ uintptr, dec Decoder, m map[uintptr]Decoder) {
+ newDecoderMap := make(map[uintptr]Decoder, len(m)+1)
+ newDecoderMap[typ] = dec
+
+ for k, v := range m {
+ newDecoderMap[k] = v
+ }
+
+ atomic.StorePointer(&cachedDecoderMap, *(*unsafe.Pointer)(unsafe.Pointer(&newDecoderMap)))
+}
+
+func compileToGetDecoderSlowPath(typeptr uintptr, typ *runtime.Type) (Decoder, error) {
+ decoderMap := loadDecoderMap()
+ if dec, exists := decoderMap[typeptr]; exists {
+ return dec, nil
+ }
+
+ dec, err := compileHead(typ, map[uintptr]Decoder{})
+ if err != nil {
+ return nil, err
+ }
+ storeDecoder(typeptr, dec, decoderMap)
+ return dec, nil
+}
+
+func compileHead(typ *runtime.Type, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
+ switch {
+ case implementsUnmarshalJSONType(runtime.PtrTo(typ)):
+ return newUnmarshalJSONDecoder(runtime.PtrTo(typ), "", ""), nil
+ case runtime.PtrTo(typ).Implements(unmarshalTextType):
+ return newUnmarshalTextDecoder(runtime.PtrTo(typ), "", ""), nil
+ }
+ return compile(typ.Elem(), "", "", structTypeToDecoder)
+}
+
+func compile(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
+ switch {
+ case implementsUnmarshalJSONType(runtime.PtrTo(typ)):
+ return newUnmarshalJSONDecoder(runtime.PtrTo(typ), structName, fieldName), nil
+ case runtime.PtrTo(typ).Implements(unmarshalTextType):
+ return newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName), nil
+ }
+
+ switch typ.Kind() {
+ case reflect.Ptr:
+ return compilePtr(typ, structName, fieldName, structTypeToDecoder)
+ case reflect.Struct:
+ return compileStruct(typ, structName, fieldName, structTypeToDecoder)
+ case reflect.Slice:
+ elem := typ.Elem()
+ if elem.Kind() == reflect.Uint8 {
+ return compileBytes(elem, structName, fieldName)
+ }
+ return compileSlice(typ, structName, fieldName, structTypeToDecoder)
+ case reflect.Array:
+ return compileArray(typ, structName, fieldName, structTypeToDecoder)
+ case reflect.Map:
+ return compileMap(typ, structName, fieldName, structTypeToDecoder)
+ case reflect.Interface:
+ return compileInterface(typ, structName, fieldName)
+ case reflect.Uintptr:
+ return compileUint(typ, structName, fieldName)
+ case reflect.Int:
+ return compileInt(typ, structName, fieldName)
+ case reflect.Int8:
+ return compileInt8(typ, structName, fieldName)
+ case reflect.Int16:
+ return compileInt16(typ, structName, fieldName)
+ case reflect.Int32:
+ return compileInt32(typ, structName, fieldName)
+ case reflect.Int64:
+ return compileInt64(typ, structName, fieldName)
+ case reflect.Uint:
+ return compileUint(typ, structName, fieldName)
+ case reflect.Uint8:
+ return compileUint8(typ, structName, fieldName)
+ case reflect.Uint16:
+ return compileUint16(typ, structName, fieldName)
+ case reflect.Uint32:
+ return compileUint32(typ, structName, fieldName)
+ case reflect.Uint64:
+ return compileUint64(typ, structName, fieldName)
+ case reflect.String:
+ return compileString(typ, structName, fieldName)
+ case reflect.Bool:
+ return compileBool(structName, fieldName)
+ case reflect.Float32:
+ return compileFloat32(structName, fieldName)
+ case reflect.Float64:
+ return compileFloat64(structName, fieldName)
+ case reflect.Func:
+ return compileFunc(typ, structName, fieldName)
+ }
+ return newInvalidDecoder(typ, structName, fieldName), nil
+}
+
+func isStringTagSupportedType(typ *runtime.Type) bool {
+ switch {
+ case implementsUnmarshalJSONType(runtime.PtrTo(typ)):
+ return false
+ case runtime.PtrTo(typ).Implements(unmarshalTextType):
+ return false
+ }
+ switch typ.Kind() {
+ case reflect.Map:
+ return false
+ case reflect.Slice:
+ return false
+ case reflect.Array:
+ return false
+ case reflect.Struct:
+ return false
+ case reflect.Interface:
+ return false
+ }
+ return true
+}
+
+func compileMapKey(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
+ if runtime.PtrTo(typ).Implements(unmarshalTextType) {
+ return newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName), nil
+ }
+ if typ.Kind() == reflect.String {
+ return newStringDecoder(structName, fieldName), nil
+ }
+ dec, err := compile(typ, structName, fieldName, structTypeToDecoder)
+ if err != nil {
+ return nil, err
+ }
+ for {
+ switch t := dec.(type) {
+ case *stringDecoder, *interfaceDecoder:
+ return dec, nil
+ case *boolDecoder, *intDecoder, *uintDecoder, *numberDecoder:
+ return newWrappedStringDecoder(typ, dec, structName, fieldName), nil
+ case *ptrDecoder:
+ dec = t.dec
+ default:
+ return newInvalidDecoder(typ, structName, fieldName), nil
+ }
+ }
+}
+
+func compilePtr(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
+ dec, err := compile(typ.Elem(), structName, fieldName, structTypeToDecoder)
+ if err != nil {
+ return nil, err
+ }
+ return newPtrDecoder(dec, typ.Elem(), structName, fieldName), nil
+}
+
+func compileInt(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
+ return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) {
+ *(*int)(p) = int(v)
+ }), nil
+}
+
+func compileInt8(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
+ return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) {
+ *(*int8)(p) = int8(v)
+ }), nil
+}
+
+func compileInt16(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
+ return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) {
+ *(*int16)(p) = int16(v)
+ }), nil
+}
+
+func compileInt32(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
+ return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) {
+ *(*int32)(p) = int32(v)
+ }), nil
+}
+
+func compileInt64(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
+ return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) {
+ *(*int64)(p) = v
+ }), nil
+}
+
+func compileUint(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
+ return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) {
+ *(*uint)(p) = uint(v)
+ }), nil
+}
+
+func compileUint8(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
+ return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) {
+ *(*uint8)(p) = uint8(v)
+ }), nil
+}
+
+func compileUint16(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
+ return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) {
+ *(*uint16)(p) = uint16(v)
+ }), nil
+}
+
+func compileUint32(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
+ return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) {
+ *(*uint32)(p) = uint32(v)
+ }), nil
+}
+
+func compileUint64(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
+ return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) {
+ *(*uint64)(p) = v
+ }), nil
+}
+
+func compileFloat32(structName, fieldName string) (Decoder, error) {
+ return newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
+ *(*float32)(p) = float32(v)
+ }), nil
+}
+
+func compileFloat64(structName, fieldName string) (Decoder, error) {
+ return newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
+ *(*float64)(p) = v
+ }), nil
+}
+
+func compileString(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
+ if typ == runtime.Type2RType(jsonNumberType) {
+ return newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) {
+ *(*json.Number)(p) = v
+ }), nil
+ }
+ return newStringDecoder(structName, fieldName), nil
+}
+
+func compileBool(structName, fieldName string) (Decoder, error) {
+ return newBoolDecoder(structName, fieldName), nil
+}
+
+func compileBytes(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
+ return newBytesDecoder(typ, structName, fieldName), nil
+}
+
+func compileSlice(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
+ elem := typ.Elem()
+ decoder, err := compile(elem, structName, fieldName, structTypeToDecoder)
+ if err != nil {
+ return nil, err
+ }
+ return newSliceDecoder(decoder, elem, elem.Size(), structName, fieldName), nil
+}
+
+func compileArray(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
+ elem := typ.Elem()
+ decoder, err := compile(elem, structName, fieldName, structTypeToDecoder)
+ if err != nil {
+ return nil, err
+ }
+ return newArrayDecoder(decoder, elem, typ.Len(), structName, fieldName), nil
+}
+
+func compileMap(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
+ keyDec, err := compileMapKey(typ.Key(), structName, fieldName, structTypeToDecoder)
+ if err != nil {
+ return nil, err
+ }
+ valueDec, err := compile(typ.Elem(), structName, fieldName, structTypeToDecoder)
+ if err != nil {
+ return nil, err
+ }
+ return newMapDecoder(typ, typ.Key(), keyDec, typ.Elem(), valueDec, structName, fieldName), nil
+}
+
+func compileInterface(typ *runtime.Type, structName, fieldName string) (Decoder, error) {
+ return newInterfaceDecoder(typ, structName, fieldName), nil
+}
+
+func compileFunc(typ *runtime.Type, strutName, fieldName string) (Decoder, error) {
+ return newFuncDecoder(typ, strutName, fieldName), nil
+}
+
+func typeToStructTags(typ *runtime.Type) runtime.StructTags {
+ tags := runtime.StructTags{}
+ fieldNum := typ.NumField()
+ for i := 0; i < fieldNum; i++ {
+ field := typ.Field(i)
+ if runtime.IsIgnoredStructField(field) {
+ continue
+ }
+ tags = append(tags, runtime.StructTagFromField(field))
+ }
+ return tags
+}
+
+func compileStruct(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) {
+ fieldNum := typ.NumField()
+ fieldMap := map[string]*structFieldSet{}
+ typeptr := uintptr(unsafe.Pointer(typ))
+ if dec, exists := structTypeToDecoder[typeptr]; exists {
+ return dec, nil
+ }
+ structDec := newStructDecoder(structName, fieldName, fieldMap)
+ structTypeToDecoder[typeptr] = structDec
+ structName = typ.Name()
+ tags := typeToStructTags(typ)
+ allFields := []*structFieldSet{}
+ for i := 0; i < fieldNum; i++ {
+ field := typ.Field(i)
+ if runtime.IsIgnoredStructField(field) {
+ continue
+ }
+ isUnexportedField := unicode.IsLower([]rune(field.Name)[0])
+ tag := runtime.StructTagFromField(field)
+ dec, err := compile(runtime.Type2RType(field.Type), structName, field.Name, structTypeToDecoder)
+ if err != nil {
+ return nil, err
+ }
+ if field.Anonymous && !tag.IsTaggedKey {
+ if stDec, ok := dec.(*structDecoder); ok {
+ if runtime.Type2RType(field.Type) == typ {
+ // recursive definition
+ continue
+ }
+ for k, v := range stDec.fieldMap {
+ if tags.ExistsKey(k) {
+ continue
+ }
+ fieldSet := &structFieldSet{
+ dec: v.dec,
+ offset: field.Offset + v.offset,
+ isTaggedKey: v.isTaggedKey,
+ key: k,
+ keyLen: int64(len(k)),
+ }
+ allFields = append(allFields, fieldSet)
+ }
+ } else if pdec, ok := dec.(*ptrDecoder); ok {
+ contentDec := pdec.contentDecoder()
+ if pdec.typ == typ {
+ // recursive definition
+ continue
+ }
+ var fieldSetErr error
+ if isUnexportedField {
+ fieldSetErr = fmt.Errorf(
+ "json: cannot set embedded pointer to unexported struct: %v",
+ field.Type.Elem(),
+ )
+ }
+ if dec, ok := contentDec.(*structDecoder); ok {
+ for k, v := range dec.fieldMap {
+ if tags.ExistsKey(k) {
+ continue
+ }
+ fieldSet := &structFieldSet{
+ dec: newAnonymousFieldDecoder(pdec.typ, v.offset, v.dec),
+ offset: field.Offset,
+ isTaggedKey: v.isTaggedKey,
+ key: k,
+ keyLen: int64(len(k)),
+ err: fieldSetErr,
+ }
+ allFields = append(allFields, fieldSet)
+ }
+ } else {
+ fieldSet := &structFieldSet{
+ dec: pdec,
+ offset: field.Offset,
+ isTaggedKey: tag.IsTaggedKey,
+ key: field.Name,
+ keyLen: int64(len(field.Name)),
+ }
+ allFields = append(allFields, fieldSet)
+ }
+ } else {
+ fieldSet := &structFieldSet{
+ dec: dec,
+ offset: field.Offset,
+ isTaggedKey: tag.IsTaggedKey,
+ key: field.Name,
+ keyLen: int64(len(field.Name)),
+ }
+ allFields = append(allFields, fieldSet)
+ }
+ } else {
+ if tag.IsString && isStringTagSupportedType(runtime.Type2RType(field.Type)) {
+ dec = newWrappedStringDecoder(runtime.Type2RType(field.Type), dec, structName, field.Name)
+ }
+ var key string
+ if tag.Key != "" {
+ key = tag.Key
+ } else {
+ key = field.Name
+ }
+ fieldSet := &structFieldSet{
+ dec: dec,
+ offset: field.Offset,
+ isTaggedKey: tag.IsTaggedKey,
+ key: key,
+ keyLen: int64(len(key)),
+ }
+ allFields = append(allFields, fieldSet)
+ }
+ }
+ for _, set := range filterDuplicatedFields(allFields) {
+ fieldMap[set.key] = set
+ lower := strings.ToLower(set.key)
+ if _, exists := fieldMap[lower]; !exists {
+ // first win
+ fieldMap[lower] = set
+ }
+ }
+ delete(structTypeToDecoder, typeptr)
+ structDec.tryOptimize()
+ return structDec, nil
+}
+
+func filterDuplicatedFields(allFields []*structFieldSet) []*structFieldSet {
+ fieldMap := map[string][]*structFieldSet{}
+ for _, field := range allFields {
+ fieldMap[field.key] = append(fieldMap[field.key], field)
+ }
+ duplicatedFieldMap := map[string]struct{}{}
+ for k, sets := range fieldMap {
+ sets = filterFieldSets(sets)
+ if len(sets) != 1 {
+ duplicatedFieldMap[k] = struct{}{}
+ }
+ }
+
+ filtered := make([]*structFieldSet, 0, len(allFields))
+ for _, field := range allFields {
+ if _, exists := duplicatedFieldMap[field.key]; exists {
+ continue
+ }
+ filtered = append(filtered, field)
+ }
+ return filtered
+}
+
+func filterFieldSets(sets []*structFieldSet) []*structFieldSet {
+ if len(sets) == 1 {
+ return sets
+ }
+ filtered := make([]*structFieldSet, 0, len(sets))
+ for _, set := range sets {
+ if set.isTaggedKey {
+ filtered = append(filtered, set)
+ }
+ }
+ return filtered
+}
+
+func implementsUnmarshalJSONType(typ *runtime.Type) bool {
+ return typ.Implements(unmarshalJSONType) || typ.Implements(unmarshalJSONContextType)
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/compile_norace.go b/vendor/github.com/goccy/go-json/internal/decoder/compile_norace.go
new file mode 100644
index 00000000..eb7e2b13
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/compile_norace.go
@@ -0,0 +1,29 @@
+//go:build !race
+// +build !race
+
+package decoder
+
+import (
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+func CompileToGetDecoder(typ *runtime.Type) (Decoder, error) {
+ typeptr := uintptr(unsafe.Pointer(typ))
+ if typeptr > typeAddr.MaxTypeAddr {
+ return compileToGetDecoderSlowPath(typeptr, typ)
+ }
+
+ index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift
+ if dec := cachedDecoder[index]; dec != nil {
+ return dec, nil
+ }
+
+ dec, err := compileHead(typ, map[uintptr]Decoder{})
+ if err != nil {
+ return nil, err
+ }
+ cachedDecoder[index] = dec
+ return dec, nil
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/compile_race.go b/vendor/github.com/goccy/go-json/internal/decoder/compile_race.go
new file mode 100644
index 00000000..49cdda4a
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/compile_race.go
@@ -0,0 +1,37 @@
+//go:build race
+// +build race
+
+package decoder
+
+import (
+ "sync"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+var decMu sync.RWMutex
+
+func CompileToGetDecoder(typ *runtime.Type) (Decoder, error) {
+ typeptr := uintptr(unsafe.Pointer(typ))
+ if typeptr > typeAddr.MaxTypeAddr {
+ return compileToGetDecoderSlowPath(typeptr, typ)
+ }
+
+ index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift
+ decMu.RLock()
+ if dec := cachedDecoder[index]; dec != nil {
+ decMu.RUnlock()
+ return dec, nil
+ }
+ decMu.RUnlock()
+
+ dec, err := compileHead(typ, map[uintptr]Decoder{})
+ if err != nil {
+ return nil, err
+ }
+ decMu.Lock()
+ cachedDecoder[index] = dec
+ decMu.Unlock()
+ return dec, nil
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/context.go b/vendor/github.com/goccy/go-json/internal/decoder/context.go
new file mode 100644
index 00000000..cb2ffdaf
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/context.go
@@ -0,0 +1,254 @@
+package decoder
+
+import (
+ "sync"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+)
+
+type RuntimeContext struct {
+ Buf []byte
+ Option *Option
+}
+
+var (
+ runtimeContextPool = sync.Pool{
+ New: func() interface{} {
+ return &RuntimeContext{
+ Option: &Option{},
+ }
+ },
+ }
+)
+
+func TakeRuntimeContext() *RuntimeContext {
+ return runtimeContextPool.Get().(*RuntimeContext)
+}
+
+func ReleaseRuntimeContext(ctx *RuntimeContext) {
+ runtimeContextPool.Put(ctx)
+}
+
+var (
+ isWhiteSpace = [256]bool{}
+)
+
+func init() {
+ isWhiteSpace[' '] = true
+ isWhiteSpace['\n'] = true
+ isWhiteSpace['\t'] = true
+ isWhiteSpace['\r'] = true
+}
+
+func char(ptr unsafe.Pointer, offset int64) byte {
+ return *(*byte)(unsafe.Pointer(uintptr(ptr) + uintptr(offset)))
+}
+
+func skipWhiteSpace(buf []byte, cursor int64) int64 {
+ for isWhiteSpace[buf[cursor]] {
+ cursor++
+ }
+ return cursor
+}
+
+func skipObject(buf []byte, cursor, depth int64) (int64, error) {
+ braceCount := 1
+ for {
+ switch buf[cursor] {
+ case '{':
+ braceCount++
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
+ }
+ case '}':
+ depth--
+ braceCount--
+ if braceCount == 0 {
+ return cursor + 1, nil
+ }
+ case '[':
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
+ }
+ case ']':
+ depth--
+ case '"':
+ for {
+ cursor++
+ switch buf[cursor] {
+ case '\\':
+ cursor++
+ if buf[cursor] == nul {
+ return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor)
+ }
+ case '"':
+ goto SWITCH_OUT
+ case nul:
+ return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor)
+ }
+ }
+ case nul:
+ return 0, errors.ErrUnexpectedEndOfJSON("object of object", cursor)
+ }
+ SWITCH_OUT:
+ cursor++
+ }
+}
+
+func skipArray(buf []byte, cursor, depth int64) (int64, error) {
+ bracketCount := 1
+ for {
+ switch buf[cursor] {
+ case '[':
+ bracketCount++
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
+ }
+ case ']':
+ bracketCount--
+ depth--
+ if bracketCount == 0 {
+ return cursor + 1, nil
+ }
+ case '{':
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
+ }
+ case '}':
+ depth--
+ case '"':
+ for {
+ cursor++
+ switch buf[cursor] {
+ case '\\':
+ cursor++
+ if buf[cursor] == nul {
+ return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor)
+ }
+ case '"':
+ goto SWITCH_OUT
+ case nul:
+ return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor)
+ }
+ }
+ case nul:
+ return 0, errors.ErrUnexpectedEndOfJSON("array of object", cursor)
+ }
+ SWITCH_OUT:
+ cursor++
+ }
+}
+
+func skipValue(buf []byte, cursor, depth int64) (int64, error) {
+ for {
+ switch buf[cursor] {
+ case ' ', '\t', '\n', '\r':
+ cursor++
+ continue
+ case '{':
+ return skipObject(buf, cursor+1, depth+1)
+ case '[':
+ return skipArray(buf, cursor+1, depth+1)
+ case '"':
+ for {
+ cursor++
+ switch buf[cursor] {
+ case '\\':
+ cursor++
+ if buf[cursor] == nul {
+ return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor)
+ }
+ case '"':
+ return cursor + 1, nil
+ case nul:
+ return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor)
+ }
+ }
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ for {
+ cursor++
+ if floatTable[buf[cursor]] {
+ continue
+ }
+ break
+ }
+ return cursor, nil
+ case 't':
+ if err := validateTrue(buf, cursor); err != nil {
+ return 0, err
+ }
+ cursor += 4
+ return cursor, nil
+ case 'f':
+ if err := validateFalse(buf, cursor); err != nil {
+ return 0, err
+ }
+ cursor += 5
+ return cursor, nil
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return 0, err
+ }
+ cursor += 4
+ return cursor, nil
+ default:
+ return cursor, errors.ErrUnexpectedEndOfJSON("null", cursor)
+ }
+ }
+}
+
+func validateTrue(buf []byte, cursor int64) error {
+ if cursor+3 >= int64(len(buf)) {
+ return errors.ErrUnexpectedEndOfJSON("true", cursor)
+ }
+ if buf[cursor+1] != 'r' {
+ return errors.ErrInvalidCharacter(buf[cursor+1], "true", cursor)
+ }
+ if buf[cursor+2] != 'u' {
+ return errors.ErrInvalidCharacter(buf[cursor+2], "true", cursor)
+ }
+ if buf[cursor+3] != 'e' {
+ return errors.ErrInvalidCharacter(buf[cursor+3], "true", cursor)
+ }
+ return nil
+}
+
+func validateFalse(buf []byte, cursor int64) error {
+ if cursor+4 >= int64(len(buf)) {
+ return errors.ErrUnexpectedEndOfJSON("false", cursor)
+ }
+ if buf[cursor+1] != 'a' {
+ return errors.ErrInvalidCharacter(buf[cursor+1], "false", cursor)
+ }
+ if buf[cursor+2] != 'l' {
+ return errors.ErrInvalidCharacter(buf[cursor+2], "false", cursor)
+ }
+ if buf[cursor+3] != 's' {
+ return errors.ErrInvalidCharacter(buf[cursor+3], "false", cursor)
+ }
+ if buf[cursor+4] != 'e' {
+ return errors.ErrInvalidCharacter(buf[cursor+4], "false", cursor)
+ }
+ return nil
+}
+
+func validateNull(buf []byte, cursor int64) error {
+ if cursor+3 >= int64(len(buf)) {
+ return errors.ErrUnexpectedEndOfJSON("null", cursor)
+ }
+ if buf[cursor+1] != 'u' {
+ return errors.ErrInvalidCharacter(buf[cursor+1], "null", cursor)
+ }
+ if buf[cursor+2] != 'l' {
+ return errors.ErrInvalidCharacter(buf[cursor+2], "null", cursor)
+ }
+ if buf[cursor+3] != 'l' {
+ return errors.ErrInvalidCharacter(buf[cursor+3], "null", cursor)
+ }
+ return nil
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/float.go b/vendor/github.com/goccy/go-json/internal/decoder/float.go
new file mode 100644
index 00000000..9b2eb8b3
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/float.go
@@ -0,0 +1,170 @@
+package decoder
+
+import (
+ "strconv"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+)
+
+type floatDecoder struct {
+ op func(unsafe.Pointer, float64)
+ structName string
+ fieldName string
+}
+
+func newFloatDecoder(structName, fieldName string, op func(unsafe.Pointer, float64)) *floatDecoder {
+ return &floatDecoder{op: op, structName: structName, fieldName: fieldName}
+}
+
+var (
+ floatTable = [256]bool{
+ '0': true,
+ '1': true,
+ '2': true,
+ '3': true,
+ '4': true,
+ '5': true,
+ '6': true,
+ '7': true,
+ '8': true,
+ '9': true,
+ '.': true,
+ 'e': true,
+ 'E': true,
+ '+': true,
+ '-': true,
+ }
+
+ validEndNumberChar = [256]bool{
+ nul: true,
+ ' ': true,
+ '\t': true,
+ '\r': true,
+ '\n': true,
+ ',': true,
+ ':': true,
+ '}': true,
+ ']': true,
+ }
+)
+
+func floatBytes(s *Stream) []byte {
+ start := s.cursor
+ for {
+ s.cursor++
+ if floatTable[s.char()] {
+ continue
+ } else if s.char() == nul {
+ if s.read() {
+ s.cursor-- // for retry current character
+ continue
+ }
+ }
+ break
+ }
+ return s.buf[start:s.cursor]
+}
+
+func (d *floatDecoder) decodeStreamByte(s *Stream) ([]byte, error) {
+ for {
+ switch s.char() {
+ case ' ', '\n', '\t', '\r':
+ s.cursor++
+ continue
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return floatBytes(s), nil
+ case 'n':
+ if err := nullBytes(s); err != nil {
+ return nil, err
+ }
+ return nil, nil
+ case nul:
+ if s.read() {
+ continue
+ }
+ goto ERROR
+ default:
+ goto ERROR
+ }
+ }
+ERROR:
+ return nil, errors.ErrUnexpectedEndOfJSON("float", s.totalOffset())
+}
+
+func (d *floatDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
+ for {
+ switch buf[cursor] {
+ case ' ', '\n', '\t', '\r':
+ cursor++
+ continue
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ start := cursor
+ cursor++
+ for floatTable[buf[cursor]] {
+ cursor++
+ }
+ num := buf[start:cursor]
+ return num, cursor, nil
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return nil, 0, err
+ }
+ cursor += 4
+ return nil, cursor, nil
+ default:
+ return nil, 0, errors.ErrUnexpectedEndOfJSON("float", cursor)
+ }
+ }
+}
+
+func (d *floatDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ bytes, err := d.decodeStreamByte(s)
+ if err != nil {
+ return err
+ }
+ if bytes == nil {
+ return nil
+ }
+ str := *(*string)(unsafe.Pointer(&bytes))
+ f64, err := strconv.ParseFloat(str, 64)
+ if err != nil {
+ return errors.ErrSyntax(err.Error(), s.totalOffset())
+ }
+ d.op(p, f64)
+ return nil
+}
+
+func (d *floatDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ buf := ctx.Buf
+ bytes, c, err := d.decodeByte(buf, cursor)
+ if err != nil {
+ return 0, err
+ }
+ if bytes == nil {
+ return c, nil
+ }
+ cursor = c
+ if !validEndNumberChar[buf[cursor]] {
+ return 0, errors.ErrUnexpectedEndOfJSON("float", cursor)
+ }
+ s := *(*string)(unsafe.Pointer(&bytes))
+ f64, err := strconv.ParseFloat(s, 64)
+ if err != nil {
+ return 0, errors.ErrSyntax(err.Error(), cursor)
+ }
+ d.op(p, f64)
+ return cursor, nil
+}
+
+func (d *floatDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ buf := ctx.Buf
+ bytes, c, err := d.decodeByte(buf, cursor)
+ if err != nil {
+ return nil, 0, err
+ }
+ if bytes == nil {
+ return [][]byte{nullbytes}, c, nil
+ }
+ return [][]byte{bytes}, c, nil
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/func.go b/vendor/github.com/goccy/go-json/internal/decoder/func.go
new file mode 100644
index 00000000..4cc12ca8
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/func.go
@@ -0,0 +1,146 @@
+package decoder
+
+import (
+ "bytes"
+ "fmt"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type funcDecoder struct {
+ typ *runtime.Type
+ structName string
+ fieldName string
+}
+
+func newFuncDecoder(typ *runtime.Type, structName, fieldName string) *funcDecoder {
+ fnDecoder := &funcDecoder{typ, structName, fieldName}
+ return fnDecoder
+}
+
+func (d *funcDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ s.skipWhiteSpace()
+ start := s.cursor
+ if err := s.skipValue(depth); err != nil {
+ return err
+ }
+ src := s.buf[start:s.cursor]
+ if len(src) > 0 {
+ switch src[0] {
+ case '"':
+ return &errors.UnmarshalTypeError{
+ Value: "string",
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ }
+ case '[':
+ return &errors.UnmarshalTypeError{
+ Value: "array",
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ }
+ case '{':
+ return &errors.UnmarshalTypeError{
+ Value: "object",
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ }
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return &errors.UnmarshalTypeError{
+ Value: "number",
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ }
+ case 'n':
+ if err := nullBytes(s); err != nil {
+ return err
+ }
+ *(*unsafe.Pointer)(p) = nil
+ return nil
+ case 't':
+ if err := trueBytes(s); err == nil {
+ return &errors.UnmarshalTypeError{
+ Value: "boolean",
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ }
+ }
+ case 'f':
+ if err := falseBytes(s); err == nil {
+ return &errors.UnmarshalTypeError{
+ Value: "boolean",
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ }
+ }
+ }
+ }
+ return errors.ErrInvalidBeginningOfValue(s.buf[s.cursor], s.totalOffset())
+}
+
+func (d *funcDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ buf := ctx.Buf
+ cursor = skipWhiteSpace(buf, cursor)
+ start := cursor
+ end, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return 0, err
+ }
+ src := buf[start:end]
+ if len(src) > 0 {
+ switch src[0] {
+ case '"':
+ return 0, &errors.UnmarshalTypeError{
+ Value: "string",
+ Type: runtime.RType2Type(d.typ),
+ Offset: start,
+ }
+ case '[':
+ return 0, &errors.UnmarshalTypeError{
+ Value: "array",
+ Type: runtime.RType2Type(d.typ),
+ Offset: start,
+ }
+ case '{':
+ return 0, &errors.UnmarshalTypeError{
+ Value: "object",
+ Type: runtime.RType2Type(d.typ),
+ Offset: start,
+ }
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return 0, &errors.UnmarshalTypeError{
+ Value: "number",
+ Type: runtime.RType2Type(d.typ),
+ Offset: start,
+ }
+ case 'n':
+ if bytes.Equal(src, nullbytes) {
+ *(*unsafe.Pointer)(p) = nil
+ return end, nil
+ }
+ case 't':
+ if err := validateTrue(buf, start); err == nil {
+ return 0, &errors.UnmarshalTypeError{
+ Value: "boolean",
+ Type: runtime.RType2Type(d.typ),
+ Offset: start,
+ }
+ }
+ case 'f':
+ if err := validateFalse(buf, start); err == nil {
+ return 0, &errors.UnmarshalTypeError{
+ Value: "boolean",
+ Type: runtime.RType2Type(d.typ),
+ Offset: start,
+ }
+ }
+ }
+ }
+ return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
+}
+
+func (d *funcDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ return nil, 0, fmt.Errorf("json: func decoder does not support decode path")
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/int.go b/vendor/github.com/goccy/go-json/internal/decoder/int.go
new file mode 100644
index 00000000..1a7f0819
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/int.go
@@ -0,0 +1,246 @@
+package decoder
+
+import (
+ "fmt"
+ "reflect"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type intDecoder struct {
+ typ *runtime.Type
+ kind reflect.Kind
+ op func(unsafe.Pointer, int64)
+ structName string
+ fieldName string
+}
+
+func newIntDecoder(typ *runtime.Type, structName, fieldName string, op func(unsafe.Pointer, int64)) *intDecoder {
+ return &intDecoder{
+ typ: typ,
+ kind: typ.Kind(),
+ op: op,
+ structName: structName,
+ fieldName: fieldName,
+ }
+}
+
+func (d *intDecoder) typeError(buf []byte, offset int64) *errors.UnmarshalTypeError {
+ return &errors.UnmarshalTypeError{
+ Value: fmt.Sprintf("number %s", string(buf)),
+ Type: runtime.RType2Type(d.typ),
+ Struct: d.structName,
+ Field: d.fieldName,
+ Offset: offset,
+ }
+}
+
+var (
+ pow10i64 = [...]int64{
+ 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18,
+ }
+ pow10i64Len = len(pow10i64)
+)
+
+func (d *intDecoder) parseInt(b []byte) (int64, error) {
+ isNegative := false
+ if b[0] == '-' {
+ b = b[1:]
+ isNegative = true
+ }
+ maxDigit := len(b)
+ if maxDigit > pow10i64Len {
+ return 0, fmt.Errorf("invalid length of number")
+ }
+ sum := int64(0)
+ for i := 0; i < maxDigit; i++ {
+ c := int64(b[i]) - 48
+ digitValue := pow10i64[maxDigit-i-1]
+ sum += c * digitValue
+ }
+ if isNegative {
+ return -1 * sum, nil
+ }
+ return sum, nil
+}
+
+var (
+ numTable = [256]bool{
+ '0': true,
+ '1': true,
+ '2': true,
+ '3': true,
+ '4': true,
+ '5': true,
+ '6': true,
+ '7': true,
+ '8': true,
+ '9': true,
+ }
+)
+
+var (
+ numZeroBuf = []byte{'0'}
+)
+
+func (d *intDecoder) decodeStreamByte(s *Stream) ([]byte, error) {
+ for {
+ switch s.char() {
+ case ' ', '\n', '\t', '\r':
+ s.cursor++
+ continue
+ case '-':
+ start := s.cursor
+ for {
+ s.cursor++
+ if numTable[s.char()] {
+ continue
+ } else if s.char() == nul {
+ if s.read() {
+ s.cursor-- // for retry current character
+ continue
+ }
+ }
+ break
+ }
+ num := s.buf[start:s.cursor]
+ if len(num) < 2 {
+ goto ERROR
+ }
+ return num, nil
+ case '0':
+ s.cursor++
+ return numZeroBuf, nil
+ case '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ start := s.cursor
+ for {
+ s.cursor++
+ if numTable[s.char()] {
+ continue
+ } else if s.char() == nul {
+ if s.read() {
+ s.cursor-- // for retry current character
+ continue
+ }
+ }
+ break
+ }
+ num := s.buf[start:s.cursor]
+ return num, nil
+ case 'n':
+ if err := nullBytes(s); err != nil {
+ return nil, err
+ }
+ return nil, nil
+ case nul:
+ if s.read() {
+ continue
+ }
+ goto ERROR
+ default:
+ return nil, d.typeError([]byte{s.char()}, s.totalOffset())
+ }
+ }
+ERROR:
+ return nil, errors.ErrUnexpectedEndOfJSON("number(integer)", s.totalOffset())
+}
+
+func (d *intDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
+ b := (*sliceHeader)(unsafe.Pointer(&buf)).data
+ for {
+ switch char(b, cursor) {
+ case ' ', '\n', '\t', '\r':
+ cursor++
+ continue
+ case '0':
+ cursor++
+ return numZeroBuf, cursor, nil
+ case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ start := cursor
+ cursor++
+ for numTable[char(b, cursor)] {
+ cursor++
+ }
+ num := buf[start:cursor]
+ return num, cursor, nil
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return nil, 0, err
+ }
+ cursor += 4
+ return nil, cursor, nil
+ default:
+ return nil, 0, d.typeError([]byte{char(b, cursor)}, cursor)
+ }
+ }
+}
+
+func (d *intDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ bytes, err := d.decodeStreamByte(s)
+ if err != nil {
+ return err
+ }
+ if bytes == nil {
+ return nil
+ }
+ i64, err := d.parseInt(bytes)
+ if err != nil {
+ return d.typeError(bytes, s.totalOffset())
+ }
+ switch d.kind {
+ case reflect.Int8:
+ if i64 < -1*(1<<7) || (1<<7) <= i64 {
+ return d.typeError(bytes, s.totalOffset())
+ }
+ case reflect.Int16:
+ if i64 < -1*(1<<15) || (1<<15) <= i64 {
+ return d.typeError(bytes, s.totalOffset())
+ }
+ case reflect.Int32:
+ if i64 < -1*(1<<31) || (1<<31) <= i64 {
+ return d.typeError(bytes, s.totalOffset())
+ }
+ }
+ d.op(p, i64)
+ s.reset()
+ return nil
+}
+
+func (d *intDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ bytes, c, err := d.decodeByte(ctx.Buf, cursor)
+ if err != nil {
+ return 0, err
+ }
+ if bytes == nil {
+ return c, nil
+ }
+ cursor = c
+
+ i64, err := d.parseInt(bytes)
+ if err != nil {
+ return 0, d.typeError(bytes, cursor)
+ }
+ switch d.kind {
+ case reflect.Int8:
+ if i64 < -1*(1<<7) || (1<<7) <= i64 {
+ return 0, d.typeError(bytes, cursor)
+ }
+ case reflect.Int16:
+ if i64 < -1*(1<<15) || (1<<15) <= i64 {
+ return 0, d.typeError(bytes, cursor)
+ }
+ case reflect.Int32:
+ if i64 < -1*(1<<31) || (1<<31) <= i64 {
+ return 0, d.typeError(bytes, cursor)
+ }
+ }
+ d.op(p, i64)
+ return cursor, nil
+}
+
+func (d *intDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ return nil, 0, fmt.Errorf("json: int decoder does not support decode path")
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/interface.go b/vendor/github.com/goccy/go-json/internal/decoder/interface.go
new file mode 100644
index 00000000..45c69ab8
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/interface.go
@@ -0,0 +1,528 @@
+package decoder
+
+import (
+ "bytes"
+ "encoding"
+ "encoding/json"
+ "reflect"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type interfaceDecoder struct {
+ typ *runtime.Type
+ structName string
+ fieldName string
+ sliceDecoder *sliceDecoder
+ mapDecoder *mapDecoder
+ floatDecoder *floatDecoder
+ numberDecoder *numberDecoder
+ stringDecoder *stringDecoder
+}
+
+func newEmptyInterfaceDecoder(structName, fieldName string) *interfaceDecoder {
+ ifaceDecoder := &interfaceDecoder{
+ typ: emptyInterfaceType,
+ structName: structName,
+ fieldName: fieldName,
+ floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
+ *(*interface{})(p) = v
+ }),
+ numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) {
+ *(*interface{})(p) = v
+ }),
+ stringDecoder: newStringDecoder(structName, fieldName),
+ }
+ ifaceDecoder.sliceDecoder = newSliceDecoder(
+ ifaceDecoder,
+ emptyInterfaceType,
+ emptyInterfaceType.Size(),
+ structName, fieldName,
+ )
+ ifaceDecoder.mapDecoder = newMapDecoder(
+ interfaceMapType,
+ stringType,
+ ifaceDecoder.stringDecoder,
+ interfaceMapType.Elem(),
+ ifaceDecoder,
+ structName,
+ fieldName,
+ )
+ return ifaceDecoder
+}
+
+func newInterfaceDecoder(typ *runtime.Type, structName, fieldName string) *interfaceDecoder {
+ emptyIfaceDecoder := newEmptyInterfaceDecoder(structName, fieldName)
+ stringDecoder := newStringDecoder(structName, fieldName)
+ return &interfaceDecoder{
+ typ: typ,
+ structName: structName,
+ fieldName: fieldName,
+ sliceDecoder: newSliceDecoder(
+ emptyIfaceDecoder,
+ emptyInterfaceType,
+ emptyInterfaceType.Size(),
+ structName, fieldName,
+ ),
+ mapDecoder: newMapDecoder(
+ interfaceMapType,
+ stringType,
+ stringDecoder,
+ interfaceMapType.Elem(),
+ emptyIfaceDecoder,
+ structName,
+ fieldName,
+ ),
+ floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) {
+ *(*interface{})(p) = v
+ }),
+ numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) {
+ *(*interface{})(p) = v
+ }),
+ stringDecoder: stringDecoder,
+ }
+}
+
+func (d *interfaceDecoder) numDecoder(s *Stream) Decoder {
+ if s.UseNumber {
+ return d.numberDecoder
+ }
+ return d.floatDecoder
+}
+
+var (
+ emptyInterfaceType = runtime.Type2RType(reflect.TypeOf((*interface{})(nil)).Elem())
+ EmptyInterfaceType = emptyInterfaceType
+ interfaceMapType = runtime.Type2RType(
+ reflect.TypeOf((*map[string]interface{})(nil)).Elem(),
+ )
+ stringType = runtime.Type2RType(
+ reflect.TypeOf(""),
+ )
+)
+
+func decodeStreamUnmarshaler(s *Stream, depth int64, unmarshaler json.Unmarshaler) error {
+ start := s.cursor
+ if err := s.skipValue(depth); err != nil {
+ return err
+ }
+ src := s.buf[start:s.cursor]
+ dst := make([]byte, len(src))
+ copy(dst, src)
+
+ if err := unmarshaler.UnmarshalJSON(dst); err != nil {
+ return err
+ }
+ return nil
+}
+
+func decodeStreamUnmarshalerContext(s *Stream, depth int64, unmarshaler unmarshalerContext) error {
+ start := s.cursor
+ if err := s.skipValue(depth); err != nil {
+ return err
+ }
+ src := s.buf[start:s.cursor]
+ dst := make([]byte, len(src))
+ copy(dst, src)
+
+ if err := unmarshaler.UnmarshalJSON(s.Option.Context, dst); err != nil {
+ return err
+ }
+ return nil
+}
+
+func decodeUnmarshaler(buf []byte, cursor, depth int64, unmarshaler json.Unmarshaler) (int64, error) {
+ cursor = skipWhiteSpace(buf, cursor)
+ start := cursor
+ end, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return 0, err
+ }
+ src := buf[start:end]
+ dst := make([]byte, len(src))
+ copy(dst, src)
+
+ if err := unmarshaler.UnmarshalJSON(dst); err != nil {
+ return 0, err
+ }
+ return end, nil
+}
+
+func decodeUnmarshalerContext(ctx *RuntimeContext, buf []byte, cursor, depth int64, unmarshaler unmarshalerContext) (int64, error) {
+ cursor = skipWhiteSpace(buf, cursor)
+ start := cursor
+ end, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return 0, err
+ }
+ src := buf[start:end]
+ dst := make([]byte, len(src))
+ copy(dst, src)
+
+ if err := unmarshaler.UnmarshalJSON(ctx.Option.Context, dst); err != nil {
+ return 0, err
+ }
+ return end, nil
+}
+
+func decodeStreamTextUnmarshaler(s *Stream, depth int64, unmarshaler encoding.TextUnmarshaler, p unsafe.Pointer) error {
+ start := s.cursor
+ if err := s.skipValue(depth); err != nil {
+ return err
+ }
+ src := s.buf[start:s.cursor]
+ if bytes.Equal(src, nullbytes) {
+ *(*unsafe.Pointer)(p) = nil
+ return nil
+ }
+
+ dst := make([]byte, len(src))
+ copy(dst, src)
+
+ if err := unmarshaler.UnmarshalText(dst); err != nil {
+ return err
+ }
+ return nil
+}
+
+func decodeTextUnmarshaler(buf []byte, cursor, depth int64, unmarshaler encoding.TextUnmarshaler, p unsafe.Pointer) (int64, error) {
+ cursor = skipWhiteSpace(buf, cursor)
+ start := cursor
+ end, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return 0, err
+ }
+ src := buf[start:end]
+ if bytes.Equal(src, nullbytes) {
+ *(*unsafe.Pointer)(p) = nil
+ return end, nil
+ }
+ if s, ok := unquoteBytes(src); ok {
+ src = s
+ }
+ if err := unmarshaler.UnmarshalText(src); err != nil {
+ return 0, err
+ }
+ return end, nil
+}
+
+func (d *interfaceDecoder) decodeStreamEmptyInterface(s *Stream, depth int64, p unsafe.Pointer) error {
+ c := s.skipWhiteSpace()
+ for {
+ switch c {
+ case '{':
+ var v map[string]interface{}
+ ptr := unsafe.Pointer(&v)
+ if err := d.mapDecoder.DecodeStream(s, depth, ptr); err != nil {
+ return err
+ }
+ *(*interface{})(p) = v
+ return nil
+ case '[':
+ var v []interface{}
+ ptr := unsafe.Pointer(&v)
+ if err := d.sliceDecoder.DecodeStream(s, depth, ptr); err != nil {
+ return err
+ }
+ *(*interface{})(p) = v
+ return nil
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return d.numDecoder(s).DecodeStream(s, depth, p)
+ case '"':
+ s.cursor++
+ start := s.cursor
+ for {
+ switch s.char() {
+ case '\\':
+ if _, err := decodeEscapeString(s, nil); err != nil {
+ return err
+ }
+ case '"':
+ literal := s.buf[start:s.cursor]
+ s.cursor++
+ *(*interface{})(p) = string(literal)
+ return nil
+ case nul:
+ if s.read() {
+ continue
+ }
+ return errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
+ }
+ s.cursor++
+ }
+ case 't':
+ if err := trueBytes(s); err != nil {
+ return err
+ }
+ **(**interface{})(unsafe.Pointer(&p)) = true
+ return nil
+ case 'f':
+ if err := falseBytes(s); err != nil {
+ return err
+ }
+ **(**interface{})(unsafe.Pointer(&p)) = false
+ return nil
+ case 'n':
+ if err := nullBytes(s); err != nil {
+ return err
+ }
+ *(*interface{})(p) = nil
+ return nil
+ case nul:
+ if s.read() {
+ c = s.char()
+ continue
+ }
+ }
+ break
+ }
+ return errors.ErrInvalidBeginningOfValue(c, s.totalOffset())
+}
+
+type emptyInterface struct {
+ typ *runtime.Type
+ ptr unsafe.Pointer
+}
+
+func (d *interfaceDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ runtimeInterfaceValue := *(*interface{})(unsafe.Pointer(&emptyInterface{
+ typ: d.typ,
+ ptr: p,
+ }))
+ rv := reflect.ValueOf(runtimeInterfaceValue)
+ if rv.NumMethod() > 0 && rv.CanInterface() {
+ if u, ok := rv.Interface().(unmarshalerContext); ok {
+ return decodeStreamUnmarshalerContext(s, depth, u)
+ }
+ if u, ok := rv.Interface().(json.Unmarshaler); ok {
+ return decodeStreamUnmarshaler(s, depth, u)
+ }
+ if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
+ return decodeStreamTextUnmarshaler(s, depth, u, p)
+ }
+ if s.skipWhiteSpace() == 'n' {
+ if err := nullBytes(s); err != nil {
+ return err
+ }
+ *(*interface{})(p) = nil
+ return nil
+ }
+ return d.errUnmarshalType(rv.Type(), s.totalOffset())
+ }
+ iface := rv.Interface()
+ ifaceHeader := (*emptyInterface)(unsafe.Pointer(&iface))
+ typ := ifaceHeader.typ
+ if ifaceHeader.ptr == nil || d.typ == typ || typ == nil {
+ // concrete type is empty interface
+ return d.decodeStreamEmptyInterface(s, depth, p)
+ }
+ if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr {
+ return d.decodeStreamEmptyInterface(s, depth, p)
+ }
+ if s.skipWhiteSpace() == 'n' {
+ if err := nullBytes(s); err != nil {
+ return err
+ }
+ *(*interface{})(p) = nil
+ return nil
+ }
+ decoder, err := CompileToGetDecoder(typ)
+ if err != nil {
+ return err
+ }
+ return decoder.DecodeStream(s, depth, ifaceHeader.ptr)
+}
+
+func (d *interfaceDecoder) errUnmarshalType(typ reflect.Type, offset int64) *errors.UnmarshalTypeError {
+ return &errors.UnmarshalTypeError{
+ Value: typ.String(),
+ Type: typ,
+ Offset: offset,
+ Struct: d.structName,
+ Field: d.fieldName,
+ }
+}
+
+func (d *interfaceDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ buf := ctx.Buf
+ runtimeInterfaceValue := *(*interface{})(unsafe.Pointer(&emptyInterface{
+ typ: d.typ,
+ ptr: p,
+ }))
+ rv := reflect.ValueOf(runtimeInterfaceValue)
+ if rv.NumMethod() > 0 && rv.CanInterface() {
+ if u, ok := rv.Interface().(unmarshalerContext); ok {
+ return decodeUnmarshalerContext(ctx, buf, cursor, depth, u)
+ }
+ if u, ok := rv.Interface().(json.Unmarshaler); ok {
+ return decodeUnmarshaler(buf, cursor, depth, u)
+ }
+ if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok {
+ return decodeTextUnmarshaler(buf, cursor, depth, u, p)
+ }
+ cursor = skipWhiteSpace(buf, cursor)
+ if buf[cursor] == 'n' {
+ if err := validateNull(buf, cursor); err != nil {
+ return 0, err
+ }
+ cursor += 4
+ **(**interface{})(unsafe.Pointer(&p)) = nil
+ return cursor, nil
+ }
+ return 0, d.errUnmarshalType(rv.Type(), cursor)
+ }
+
+ iface := rv.Interface()
+ ifaceHeader := (*emptyInterface)(unsafe.Pointer(&iface))
+ typ := ifaceHeader.typ
+ if ifaceHeader.ptr == nil || d.typ == typ || typ == nil {
+ // concrete type is empty interface
+ return d.decodeEmptyInterface(ctx, cursor, depth, p)
+ }
+ if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr {
+ return d.decodeEmptyInterface(ctx, cursor, depth, p)
+ }
+ cursor = skipWhiteSpace(buf, cursor)
+ if buf[cursor] == 'n' {
+ if err := validateNull(buf, cursor); err != nil {
+ return 0, err
+ }
+ cursor += 4
+ **(**interface{})(unsafe.Pointer(&p)) = nil
+ return cursor, nil
+ }
+ decoder, err := CompileToGetDecoder(typ)
+ if err != nil {
+ return 0, err
+ }
+ return decoder.Decode(ctx, cursor, depth, ifaceHeader.ptr)
+}
+
+func (d *interfaceDecoder) decodeEmptyInterface(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ buf := ctx.Buf
+ cursor = skipWhiteSpace(buf, cursor)
+ switch buf[cursor] {
+ case '{':
+ var v map[string]interface{}
+ ptr := unsafe.Pointer(&v)
+ cursor, err := d.mapDecoder.Decode(ctx, cursor, depth, ptr)
+ if err != nil {
+ return 0, err
+ }
+ **(**interface{})(unsafe.Pointer(&p)) = v
+ return cursor, nil
+ case '[':
+ var v []interface{}
+ ptr := unsafe.Pointer(&v)
+ cursor, err := d.sliceDecoder.Decode(ctx, cursor, depth, ptr)
+ if err != nil {
+ return 0, err
+ }
+ **(**interface{})(unsafe.Pointer(&p)) = v
+ return cursor, nil
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return d.floatDecoder.Decode(ctx, cursor, depth, p)
+ case '"':
+ var v string
+ ptr := unsafe.Pointer(&v)
+ cursor, err := d.stringDecoder.Decode(ctx, cursor, depth, ptr)
+ if err != nil {
+ return 0, err
+ }
+ **(**interface{})(unsafe.Pointer(&p)) = v
+ return cursor, nil
+ case 't':
+ if err := validateTrue(buf, cursor); err != nil {
+ return 0, err
+ }
+ cursor += 4
+ **(**interface{})(unsafe.Pointer(&p)) = true
+ return cursor, nil
+ case 'f':
+ if err := validateFalse(buf, cursor); err != nil {
+ return 0, err
+ }
+ cursor += 5
+ **(**interface{})(unsafe.Pointer(&p)) = false
+ return cursor, nil
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return 0, err
+ }
+ cursor += 4
+ **(**interface{})(unsafe.Pointer(&p)) = nil
+ return cursor, nil
+ }
+ return cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
+}
+
+func NewPathDecoder() Decoder {
+ ifaceDecoder := &interfaceDecoder{
+ typ: emptyInterfaceType,
+ structName: "",
+ fieldName: "",
+ floatDecoder: newFloatDecoder("", "", func(p unsafe.Pointer, v float64) {
+ *(*interface{})(p) = v
+ }),
+ numberDecoder: newNumberDecoder("", "", func(p unsafe.Pointer, v json.Number) {
+ *(*interface{})(p) = v
+ }),
+ stringDecoder: newStringDecoder("", ""),
+ }
+ ifaceDecoder.sliceDecoder = newSliceDecoder(
+ ifaceDecoder,
+ emptyInterfaceType,
+ emptyInterfaceType.Size(),
+ "", "",
+ )
+ ifaceDecoder.mapDecoder = newMapDecoder(
+ interfaceMapType,
+ stringType,
+ ifaceDecoder.stringDecoder,
+ interfaceMapType.Elem(),
+ ifaceDecoder,
+ "", "",
+ )
+ return ifaceDecoder
+}
+
+var (
+ truebytes = []byte("true")
+ falsebytes = []byte("false")
+)
+
+func (d *interfaceDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ buf := ctx.Buf
+ cursor = skipWhiteSpace(buf, cursor)
+ switch buf[cursor] {
+ case '{':
+ return d.mapDecoder.DecodePath(ctx, cursor, depth)
+ case '[':
+ return d.sliceDecoder.DecodePath(ctx, cursor, depth)
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return d.floatDecoder.DecodePath(ctx, cursor, depth)
+ case '"':
+ return d.stringDecoder.DecodePath(ctx, cursor, depth)
+ case 't':
+ if err := validateTrue(buf, cursor); err != nil {
+ return nil, 0, err
+ }
+ cursor += 4
+ return [][]byte{truebytes}, cursor, nil
+ case 'f':
+ if err := validateFalse(buf, cursor); err != nil {
+ return nil, 0, err
+ }
+ cursor += 5
+ return [][]byte{falsebytes}, cursor, nil
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return nil, 0, err
+ }
+ cursor += 4
+ return [][]byte{nullbytes}, cursor, nil
+ }
+ return nil, cursor, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/invalid.go b/vendor/github.com/goccy/go-json/internal/decoder/invalid.go
new file mode 100644
index 00000000..4c9721b0
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/invalid.go
@@ -0,0 +1,55 @@
+package decoder
+
+import (
+ "reflect"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type invalidDecoder struct {
+ typ *runtime.Type
+ kind reflect.Kind
+ structName string
+ fieldName string
+}
+
+func newInvalidDecoder(typ *runtime.Type, structName, fieldName string) *invalidDecoder {
+ return &invalidDecoder{
+ typ: typ,
+ kind: typ.Kind(),
+ structName: structName,
+ fieldName: fieldName,
+ }
+}
+
+func (d *invalidDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ return &errors.UnmarshalTypeError{
+ Value: "object",
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ Struct: d.structName,
+ Field: d.fieldName,
+ }
+}
+
+func (d *invalidDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ return 0, &errors.UnmarshalTypeError{
+ Value: "object",
+ Type: runtime.RType2Type(d.typ),
+ Offset: cursor,
+ Struct: d.structName,
+ Field: d.fieldName,
+ }
+}
+
+func (d *invalidDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ return nil, 0, &errors.UnmarshalTypeError{
+ Value: "object",
+ Type: runtime.RType2Type(d.typ),
+ Offset: cursor,
+ Struct: d.structName,
+ Field: d.fieldName,
+ }
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/map.go b/vendor/github.com/goccy/go-json/internal/decoder/map.go
new file mode 100644
index 00000000..07a9caea
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/map.go
@@ -0,0 +1,280 @@
+package decoder
+
+import (
+ "reflect"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type mapDecoder struct {
+ mapType *runtime.Type
+ keyType *runtime.Type
+ valueType *runtime.Type
+ canUseAssignFaststrType bool
+ keyDecoder Decoder
+ valueDecoder Decoder
+ structName string
+ fieldName string
+}
+
+func newMapDecoder(mapType *runtime.Type, keyType *runtime.Type, keyDec Decoder, valueType *runtime.Type, valueDec Decoder, structName, fieldName string) *mapDecoder {
+ return &mapDecoder{
+ mapType: mapType,
+ keyDecoder: keyDec,
+ keyType: keyType,
+ canUseAssignFaststrType: canUseAssignFaststrType(keyType, valueType),
+ valueType: valueType,
+ valueDecoder: valueDec,
+ structName: structName,
+ fieldName: fieldName,
+ }
+}
+
+const (
+ mapMaxElemSize = 128
+)
+
+// See detail: https://github.com/goccy/go-json/pull/283
+func canUseAssignFaststrType(key *runtime.Type, value *runtime.Type) bool {
+ indirectElem := value.Size() > mapMaxElemSize
+ if indirectElem {
+ return false
+ }
+ return key.Kind() == reflect.String
+}
+
+//go:linkname makemap reflect.makemap
+func makemap(*runtime.Type, int) unsafe.Pointer
+
+//nolint:golint
+//go:linkname mapassign_faststr runtime.mapassign_faststr
+//go:noescape
+func mapassign_faststr(t *runtime.Type, m unsafe.Pointer, s string) unsafe.Pointer
+
+//go:linkname mapassign reflect.mapassign
+//go:noescape
+func mapassign(t *runtime.Type, m unsafe.Pointer, k, v unsafe.Pointer)
+
+func (d *mapDecoder) mapassign(t *runtime.Type, m, k, v unsafe.Pointer) {
+ if d.canUseAssignFaststrType {
+ mapV := mapassign_faststr(t, m, *(*string)(k))
+ typedmemmove(d.valueType, mapV, v)
+ } else {
+ mapassign(t, m, k, v)
+ }
+}
+
+func (d *mapDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return errors.ErrExceededMaxDepth(s.char(), s.cursor)
+ }
+
+ switch s.skipWhiteSpace() {
+ case 'n':
+ if err := nullBytes(s); err != nil {
+ return err
+ }
+ **(**unsafe.Pointer)(unsafe.Pointer(&p)) = nil
+ return nil
+ case '{':
+ default:
+ return errors.ErrExpected("{ character for map value", s.totalOffset())
+ }
+ mapValue := *(*unsafe.Pointer)(p)
+ if mapValue == nil {
+ mapValue = makemap(d.mapType, 0)
+ }
+ s.cursor++
+ if s.skipWhiteSpace() == '}' {
+ *(*unsafe.Pointer)(p) = mapValue
+ s.cursor++
+ return nil
+ }
+ for {
+ k := unsafe_New(d.keyType)
+ if err := d.keyDecoder.DecodeStream(s, depth, k); err != nil {
+ return err
+ }
+ s.skipWhiteSpace()
+ if !s.equalChar(':') {
+ return errors.ErrExpected("colon after object key", s.totalOffset())
+ }
+ s.cursor++
+ v := unsafe_New(d.valueType)
+ if err := d.valueDecoder.DecodeStream(s, depth, v); err != nil {
+ return err
+ }
+ d.mapassign(d.mapType, mapValue, k, v)
+ s.skipWhiteSpace()
+ if s.equalChar('}') {
+ **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue
+ s.cursor++
+ return nil
+ }
+ if !s.equalChar(',') {
+ return errors.ErrExpected("comma after object value", s.totalOffset())
+ }
+ s.cursor++
+ }
+}
+
+func (d *mapDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ buf := ctx.Buf
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
+ }
+
+ cursor = skipWhiteSpace(buf, cursor)
+ buflen := int64(len(buf))
+ if buflen < 2 {
+ return 0, errors.ErrExpected("{} for map", cursor)
+ }
+ switch buf[cursor] {
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return 0, err
+ }
+ cursor += 4
+ **(**unsafe.Pointer)(unsafe.Pointer(&p)) = nil
+ return cursor, nil
+ case '{':
+ default:
+ return 0, errors.ErrExpected("{ character for map value", cursor)
+ }
+ cursor++
+ cursor = skipWhiteSpace(buf, cursor)
+ mapValue := *(*unsafe.Pointer)(p)
+ if mapValue == nil {
+ mapValue = makemap(d.mapType, 0)
+ }
+ if buf[cursor] == '}' {
+ **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue
+ cursor++
+ return cursor, nil
+ }
+ for {
+ k := unsafe_New(d.keyType)
+ keyCursor, err := d.keyDecoder.Decode(ctx, cursor, depth, k)
+ if err != nil {
+ return 0, err
+ }
+ cursor = skipWhiteSpace(buf, keyCursor)
+ if buf[cursor] != ':' {
+ return 0, errors.ErrExpected("colon after object key", cursor)
+ }
+ cursor++
+ v := unsafe_New(d.valueType)
+ valueCursor, err := d.valueDecoder.Decode(ctx, cursor, depth, v)
+ if err != nil {
+ return 0, err
+ }
+ d.mapassign(d.mapType, mapValue, k, v)
+ cursor = skipWhiteSpace(buf, valueCursor)
+ if buf[cursor] == '}' {
+ **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue
+ cursor++
+ return cursor, nil
+ }
+ if buf[cursor] != ',' {
+ return 0, errors.ErrExpected("comma after object value", cursor)
+ }
+ cursor++
+ }
+}
+
+func (d *mapDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ buf := ctx.Buf
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return nil, 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
+ }
+
+ cursor = skipWhiteSpace(buf, cursor)
+ buflen := int64(len(buf))
+ if buflen < 2 {
+ return nil, 0, errors.ErrExpected("{} for map", cursor)
+ }
+ switch buf[cursor] {
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return nil, 0, err
+ }
+ cursor += 4
+ return [][]byte{nullbytes}, cursor, nil
+ case '{':
+ default:
+ return nil, 0, errors.ErrExpected("{ character for map value", cursor)
+ }
+ cursor++
+ cursor = skipWhiteSpace(buf, cursor)
+ if buf[cursor] == '}' {
+ cursor++
+ return nil, cursor, nil
+ }
+ keyDecoder, ok := d.keyDecoder.(*stringDecoder)
+ if !ok {
+ return nil, 0, &errors.UnmarshalTypeError{
+ Value: "string",
+ Type: reflect.TypeOf(""),
+ Offset: cursor,
+ Struct: d.structName,
+ Field: d.fieldName,
+ }
+ }
+ ret := [][]byte{}
+ for {
+ key, keyCursor, err := keyDecoder.decodeByte(buf, cursor)
+ if err != nil {
+ return nil, 0, err
+ }
+ cursor = skipWhiteSpace(buf, keyCursor)
+ if buf[cursor] != ':' {
+ return nil, 0, errors.ErrExpected("colon after object key", cursor)
+ }
+ cursor++
+ child, found, err := ctx.Option.Path.Field(string(key))
+ if err != nil {
+ return nil, 0, err
+ }
+ if found {
+ if child != nil {
+ oldPath := ctx.Option.Path.node
+ ctx.Option.Path.node = child
+ paths, c, err := d.valueDecoder.DecodePath(ctx, cursor, depth)
+ if err != nil {
+ return nil, 0, err
+ }
+ ctx.Option.Path.node = oldPath
+ ret = append(ret, paths...)
+ cursor = c
+ } else {
+ start := cursor
+ end, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return nil, 0, err
+ }
+ ret = append(ret, buf[start:end])
+ cursor = end
+ }
+ } else {
+ c, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return nil, 0, err
+ }
+ cursor = c
+ }
+ cursor = skipWhiteSpace(buf, cursor)
+ if buf[cursor] == '}' {
+ cursor++
+ return ret, cursor, nil
+ }
+ if buf[cursor] != ',' {
+ return nil, 0, errors.ErrExpected("comma after object value", cursor)
+ }
+ cursor++
+ }
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/number.go b/vendor/github.com/goccy/go-json/internal/decoder/number.go
new file mode 100644
index 00000000..10e5435e
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/number.go
@@ -0,0 +1,123 @@
+package decoder
+
+import (
+ "encoding/json"
+ "strconv"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+)
+
+type numberDecoder struct {
+ stringDecoder *stringDecoder
+ op func(unsafe.Pointer, json.Number)
+ structName string
+ fieldName string
+}
+
+func newNumberDecoder(structName, fieldName string, op func(unsafe.Pointer, json.Number)) *numberDecoder {
+ return &numberDecoder{
+ stringDecoder: newStringDecoder(structName, fieldName),
+ op: op,
+ structName: structName,
+ fieldName: fieldName,
+ }
+}
+
+func (d *numberDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ bytes, err := d.decodeStreamByte(s)
+ if err != nil {
+ return err
+ }
+ if _, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&bytes)), 64); err != nil {
+ return errors.ErrSyntax(err.Error(), s.totalOffset())
+ }
+ d.op(p, json.Number(string(bytes)))
+ s.reset()
+ return nil
+}
+
+func (d *numberDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ bytes, c, err := d.decodeByte(ctx.Buf, cursor)
+ if err != nil {
+ return 0, err
+ }
+ if _, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&bytes)), 64); err != nil {
+ return 0, errors.ErrSyntax(err.Error(), c)
+ }
+ cursor = c
+ s := *(*string)(unsafe.Pointer(&bytes))
+ d.op(p, json.Number(s))
+ return cursor, nil
+}
+
+func (d *numberDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ bytes, c, err := d.decodeByte(ctx.Buf, cursor)
+ if err != nil {
+ return nil, 0, err
+ }
+ if bytes == nil {
+ return [][]byte{nullbytes}, c, nil
+ }
+ return [][]byte{bytes}, c, nil
+}
+
+func (d *numberDecoder) decodeStreamByte(s *Stream) ([]byte, error) {
+ start := s.cursor
+ for {
+ switch s.char() {
+ case ' ', '\n', '\t', '\r':
+ s.cursor++
+ continue
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return floatBytes(s), nil
+ case 'n':
+ if err := nullBytes(s); err != nil {
+ return nil, err
+ }
+ return nil, nil
+ case '"':
+ return d.stringDecoder.decodeStreamByte(s)
+ case nul:
+ if s.read() {
+ continue
+ }
+ goto ERROR
+ default:
+ goto ERROR
+ }
+ }
+ERROR:
+ if s.cursor == start {
+ return nil, errors.ErrInvalidBeginningOfValue(s.char(), s.totalOffset())
+ }
+ return nil, errors.ErrUnexpectedEndOfJSON("json.Number", s.totalOffset())
+}
+
+func (d *numberDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
+ for {
+ switch buf[cursor] {
+ case ' ', '\n', '\t', '\r':
+ cursor++
+ continue
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ start := cursor
+ cursor++
+ for floatTable[buf[cursor]] {
+ cursor++
+ }
+ num := buf[start:cursor]
+ return num, cursor, nil
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return nil, 0, err
+ }
+ cursor += 4
+ return nil, cursor, nil
+ case '"':
+ return d.stringDecoder.decodeByte(buf, cursor)
+ default:
+ return nil, 0, errors.ErrUnexpectedEndOfJSON("json.Number", cursor)
+ }
+ }
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/option.go b/vendor/github.com/goccy/go-json/internal/decoder/option.go
new file mode 100644
index 00000000..502f772e
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/option.go
@@ -0,0 +1,17 @@
+package decoder
+
+import "context"
+
+type OptionFlags uint8
+
+const (
+ FirstWinOption OptionFlags = 1 << iota
+ ContextOption
+ PathOption
+)
+
+type Option struct {
+ Flags OptionFlags
+ Context context.Context
+ Path *Path
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/path.go b/vendor/github.com/goccy/go-json/internal/decoder/path.go
new file mode 100644
index 00000000..a15ff69e
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/path.go
@@ -0,0 +1,670 @@
+package decoder
+
+import (
+ "fmt"
+ "reflect"
+ "strconv"
+
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type PathString string
+
+func (s PathString) Build() (*Path, error) {
+ builder := new(PathBuilder)
+ return builder.Build([]rune(s))
+}
+
+type PathBuilder struct {
+ root PathNode
+ node PathNode
+ singleQuotePathSelector bool
+ doubleQuotePathSelector bool
+}
+
+func (b *PathBuilder) Build(buf []rune) (*Path, error) {
+ node, err := b.build(buf)
+ if err != nil {
+ return nil, err
+ }
+ return &Path{
+ node: node,
+ RootSelectorOnly: node == nil,
+ SingleQuotePathSelector: b.singleQuotePathSelector,
+ DoubleQuotePathSelector: b.doubleQuotePathSelector,
+ }, nil
+}
+
+func (b *PathBuilder) build(buf []rune) (PathNode, error) {
+ if len(buf) == 0 {
+ return nil, errors.ErrEmptyPath()
+ }
+ if buf[0] != '$' {
+ return nil, errors.ErrInvalidPath("JSON Path must start with a $ character")
+ }
+ if len(buf) == 1 {
+ return nil, nil
+ }
+ buf = buf[1:]
+ offset, err := b.buildNext(buf)
+ if err != nil {
+ return nil, err
+ }
+ if len(buf) > offset {
+ return nil, errors.ErrInvalidPath("remain invalid path %q", buf[offset:])
+ }
+ return b.root, nil
+}
+
+func (b *PathBuilder) buildNextCharIfExists(buf []rune, cursor int) (int, error) {
+ if len(buf) > cursor {
+ offset, err := b.buildNext(buf[cursor:])
+ if err != nil {
+ return 0, err
+ }
+ return cursor + 1 + offset, nil
+ }
+ return cursor, nil
+}
+
+func (b *PathBuilder) buildNext(buf []rune) (int, error) {
+ switch buf[0] {
+ case '.':
+ if len(buf) == 1 {
+ return 0, errors.ErrInvalidPath("JSON Path ends with dot character")
+ }
+ offset, err := b.buildSelector(buf[1:])
+ if err != nil {
+ return 0, err
+ }
+ return offset + 1, nil
+ case '[':
+ if len(buf) == 1 {
+ return 0, errors.ErrInvalidPath("JSON Path ends with left bracket character")
+ }
+ offset, err := b.buildIndex(buf[1:])
+ if err != nil {
+ return 0, err
+ }
+ return offset + 1, nil
+ default:
+ return 0, errors.ErrInvalidPath("expect dot or left bracket character. but found %c character", buf[0])
+ }
+}
+
+func (b *PathBuilder) buildSelector(buf []rune) (int, error) {
+ switch buf[0] {
+ case '.':
+ if len(buf) == 1 {
+ return 0, errors.ErrInvalidPath("JSON Path ends with double dot character")
+ }
+ offset, err := b.buildPathRecursive(buf[1:])
+ if err != nil {
+ return 0, err
+ }
+ return 1 + offset, nil
+ case '[', ']', '$', '*':
+ return 0, errors.ErrInvalidPath("found invalid path character %c after dot", buf[0])
+ }
+ for cursor := 0; cursor < len(buf); cursor++ {
+ switch buf[cursor] {
+ case '$', '*', ']':
+ return 0, errors.ErrInvalidPath("found %c character in field selector context", buf[cursor])
+ case '.':
+ if cursor+1 >= len(buf) {
+ return 0, errors.ErrInvalidPath("JSON Path ends with dot character")
+ }
+ selector := buf[:cursor]
+ b.addSelectorNode(string(selector))
+ offset, err := b.buildSelector(buf[cursor+1:])
+ if err != nil {
+ return 0, err
+ }
+ return cursor + 1 + offset, nil
+ case '[':
+ if cursor+1 >= len(buf) {
+ return 0, errors.ErrInvalidPath("JSON Path ends with left bracket character")
+ }
+ selector := buf[:cursor]
+ b.addSelectorNode(string(selector))
+ offset, err := b.buildIndex(buf[cursor+1:])
+ if err != nil {
+ return 0, err
+ }
+ return cursor + 1 + offset, nil
+ case '"':
+ if cursor+1 >= len(buf) {
+ return 0, errors.ErrInvalidPath("JSON Path ends with double quote character")
+ }
+ offset, err := b.buildQuoteSelector(buf[cursor+1:], DoubleQuotePathSelector)
+ if err != nil {
+ return 0, err
+ }
+ return cursor + 1 + offset, nil
+ }
+ }
+ b.addSelectorNode(string(buf))
+ return len(buf), nil
+}
+
+func (b *PathBuilder) buildQuoteSelector(buf []rune, sel QuotePathSelector) (int, error) {
+ switch buf[0] {
+ case '[', ']', '$', '.', '*', '\'', '"':
+ return 0, errors.ErrInvalidPath("found invalid path character %c after quote", buf[0])
+ }
+ for cursor := 0; cursor < len(buf); cursor++ {
+ switch buf[cursor] {
+ case '\'':
+ if sel != SingleQuotePathSelector {
+ return 0, errors.ErrInvalidPath("found double quote character in field selector with single quote context")
+ }
+ if len(buf) <= cursor+1 {
+ return 0, errors.ErrInvalidPath("JSON Path ends with single quote character in field selector context")
+ }
+ if buf[cursor+1] != ']' {
+ return 0, errors.ErrInvalidPath("expect right bracket for field selector with single quote but found %c", buf[cursor+1])
+ }
+ selector := buf[:cursor]
+ b.addSelectorNode(string(selector))
+ b.singleQuotePathSelector = true
+ return b.buildNextCharIfExists(buf, cursor+2)
+ case '"':
+ if sel != DoubleQuotePathSelector {
+ return 0, errors.ErrInvalidPath("found single quote character in field selector with double quote context")
+ }
+ selector := buf[:cursor]
+ b.addSelectorNode(string(selector))
+ b.doubleQuotePathSelector = true
+ return b.buildNextCharIfExists(buf, cursor+1)
+ }
+ }
+ return 0, errors.ErrInvalidPath("couldn't find quote character in selector quote path context")
+}
+
+func (b *PathBuilder) buildPathRecursive(buf []rune) (int, error) {
+ switch buf[0] {
+ case '.', '[', ']', '$', '*':
+ return 0, errors.ErrInvalidPath("found invalid path character %c after double dot", buf[0])
+ }
+ for cursor := 0; cursor < len(buf); cursor++ {
+ switch buf[cursor] {
+ case '$', '*', ']':
+ return 0, errors.ErrInvalidPath("found %c character in field selector context", buf[cursor])
+ case '.':
+ if cursor+1 >= len(buf) {
+ return 0, errors.ErrInvalidPath("JSON Path ends with dot character")
+ }
+ selector := buf[:cursor]
+ b.addRecursiveNode(string(selector))
+ offset, err := b.buildSelector(buf[cursor+1:])
+ if err != nil {
+ return 0, err
+ }
+ return cursor + 1 + offset, nil
+ case '[':
+ if cursor+1 >= len(buf) {
+ return 0, errors.ErrInvalidPath("JSON Path ends with left bracket character")
+ }
+ selector := buf[:cursor]
+ b.addRecursiveNode(string(selector))
+ offset, err := b.buildIndex(buf[cursor+1:])
+ if err != nil {
+ return 0, err
+ }
+ return cursor + 1 + offset, nil
+ }
+ }
+ b.addRecursiveNode(string(buf))
+ return len(buf), nil
+}
+
+func (b *PathBuilder) buildIndex(buf []rune) (int, error) {
+ switch buf[0] {
+ case '.', '[', ']', '$':
+ return 0, errors.ErrInvalidPath("found invalid path character %c after left bracket", buf[0])
+ case '\'':
+ if len(buf) == 1 {
+ return 0, errors.ErrInvalidPath("JSON Path ends with single quote character")
+ }
+ offset, err := b.buildQuoteSelector(buf[1:], SingleQuotePathSelector)
+ if err != nil {
+ return 0, err
+ }
+ return 1 + offset, nil
+ case '*':
+ if len(buf) == 1 {
+ return 0, errors.ErrInvalidPath("JSON Path ends with star character")
+ }
+ if buf[1] != ']' {
+ return 0, errors.ErrInvalidPath("expect right bracket character for index all path but found %c character", buf[1])
+ }
+ b.addIndexAllNode()
+ offset := len("*]")
+ if len(buf) > 2 {
+ buildOffset, err := b.buildNext(buf[2:])
+ if err != nil {
+ return 0, err
+ }
+ return offset + buildOffset, nil
+ }
+ return offset, nil
+ }
+
+ for cursor := 0; cursor < len(buf); cursor++ {
+ switch buf[cursor] {
+ case ']':
+ index, err := strconv.ParseInt(string(buf[:cursor]), 10, 64)
+ if err != nil {
+ return 0, errors.ErrInvalidPath("%q is unexpected index path", buf[:cursor])
+ }
+ b.addIndexNode(int(index))
+ return b.buildNextCharIfExists(buf, cursor+1)
+ }
+ }
+ return 0, errors.ErrInvalidPath("couldn't find right bracket character in index path context")
+}
+
+func (b *PathBuilder) addIndexAllNode() {
+ node := newPathIndexAllNode()
+ if b.root == nil {
+ b.root = node
+ b.node = node
+ } else {
+ b.node = b.node.chain(node)
+ }
+}
+
+func (b *PathBuilder) addRecursiveNode(selector string) {
+ node := newPathRecursiveNode(selector)
+ if b.root == nil {
+ b.root = node
+ b.node = node
+ } else {
+ b.node = b.node.chain(node)
+ }
+}
+
+func (b *PathBuilder) addSelectorNode(name string) {
+ node := newPathSelectorNode(name)
+ if b.root == nil {
+ b.root = node
+ b.node = node
+ } else {
+ b.node = b.node.chain(node)
+ }
+}
+
+func (b *PathBuilder) addIndexNode(idx int) {
+ node := newPathIndexNode(idx)
+ if b.root == nil {
+ b.root = node
+ b.node = node
+ } else {
+ b.node = b.node.chain(node)
+ }
+}
+
+type QuotePathSelector int
+
+const (
+ SingleQuotePathSelector QuotePathSelector = 1
+ DoubleQuotePathSelector QuotePathSelector = 2
+)
+
+type Path struct {
+ node PathNode
+ RootSelectorOnly bool
+ SingleQuotePathSelector bool
+ DoubleQuotePathSelector bool
+}
+
+func (p *Path) Field(sel string) (PathNode, bool, error) {
+ if p.node == nil {
+ return nil, false, nil
+ }
+ return p.node.Field(sel)
+}
+
+func (p *Path) Get(src, dst reflect.Value) error {
+ if p.node == nil {
+ return nil
+ }
+ return p.node.Get(src, dst)
+}
+
+func (p *Path) String() string {
+ if p.node == nil {
+ return "$"
+ }
+ return p.node.String()
+}
+
+type PathNode interface {
+ fmt.Stringer
+ Index(idx int) (PathNode, bool, error)
+ Field(fieldName string) (PathNode, bool, error)
+ Get(src, dst reflect.Value) error
+ chain(PathNode) PathNode
+ target() bool
+ single() bool
+}
+
+type BasePathNode struct {
+ child PathNode
+}
+
+func (n *BasePathNode) chain(node PathNode) PathNode {
+ n.child = node
+ return node
+}
+
+func (n *BasePathNode) target() bool {
+ return n.child == nil
+}
+
+func (n *BasePathNode) single() bool {
+ return true
+}
+
+type PathSelectorNode struct {
+ *BasePathNode
+ selector string
+}
+
+func newPathSelectorNode(selector string) *PathSelectorNode {
+ return &PathSelectorNode{
+ BasePathNode: &BasePathNode{},
+ selector: selector,
+ }
+}
+
+func (n *PathSelectorNode) Index(idx int) (PathNode, bool, error) {
+ return nil, false, &errors.PathError{}
+}
+
+func (n *PathSelectorNode) Field(fieldName string) (PathNode, bool, error) {
+ if n.selector == fieldName {
+ return n.child, true, nil
+ }
+ return nil, false, nil
+}
+
+func (n *PathSelectorNode) Get(src, dst reflect.Value) error {
+ switch src.Type().Kind() {
+ case reflect.Map:
+ iter := src.MapRange()
+ for iter.Next() {
+ key, ok := iter.Key().Interface().(string)
+ if !ok {
+ return fmt.Errorf("invalid map key type %T", src.Type().Key())
+ }
+ child, found, err := n.Field(key)
+ if err != nil {
+ return err
+ }
+ if found {
+ if child != nil {
+ return child.Get(iter.Value(), dst)
+ }
+ return AssignValue(iter.Value(), dst)
+ }
+ }
+ case reflect.Struct:
+ typ := src.Type()
+ for i := 0; i < typ.Len(); i++ {
+ tag := runtime.StructTagFromField(typ.Field(i))
+ child, found, err := n.Field(tag.Key)
+ if err != nil {
+ return err
+ }
+ if found {
+ if child != nil {
+ return child.Get(src.Field(i), dst)
+ }
+ return AssignValue(src.Field(i), dst)
+ }
+ }
+ case reflect.Ptr:
+ return n.Get(src.Elem(), dst)
+ case reflect.Interface:
+ return n.Get(reflect.ValueOf(src.Interface()), dst)
+ case reflect.Float64, reflect.String, reflect.Bool:
+ return AssignValue(src, dst)
+ }
+ return fmt.Errorf("failed to get %s value from %s", n.selector, src.Type())
+}
+
+func (n *PathSelectorNode) String() string {
+ s := fmt.Sprintf(".%s", n.selector)
+ if n.child != nil {
+ s += n.child.String()
+ }
+ return s
+}
+
+type PathIndexNode struct {
+ *BasePathNode
+ selector int
+}
+
+func newPathIndexNode(selector int) *PathIndexNode {
+ return &PathIndexNode{
+ BasePathNode: &BasePathNode{},
+ selector: selector,
+ }
+}
+
+func (n *PathIndexNode) Index(idx int) (PathNode, bool, error) {
+ if n.selector == idx {
+ return n.child, true, nil
+ }
+ return nil, false, nil
+}
+
+func (n *PathIndexNode) Field(fieldName string) (PathNode, bool, error) {
+ return nil, false, &errors.PathError{}
+}
+
+func (n *PathIndexNode) Get(src, dst reflect.Value) error {
+ switch src.Type().Kind() {
+ case reflect.Array, reflect.Slice:
+ if src.Len() > n.selector {
+ if n.child != nil {
+ return n.child.Get(src.Index(n.selector), dst)
+ }
+ return AssignValue(src.Index(n.selector), dst)
+ }
+ case reflect.Ptr:
+ return n.Get(src.Elem(), dst)
+ case reflect.Interface:
+ return n.Get(reflect.ValueOf(src.Interface()), dst)
+ }
+ return fmt.Errorf("failed to get [%d] value from %s", n.selector, src.Type())
+}
+
+func (n *PathIndexNode) String() string {
+ s := fmt.Sprintf("[%d]", n.selector)
+ if n.child != nil {
+ s += n.child.String()
+ }
+ return s
+}
+
+type PathIndexAllNode struct {
+ *BasePathNode
+}
+
+func newPathIndexAllNode() *PathIndexAllNode {
+ return &PathIndexAllNode{
+ BasePathNode: &BasePathNode{},
+ }
+}
+
+func (n *PathIndexAllNode) Index(idx int) (PathNode, bool, error) {
+ return n.child, true, nil
+}
+
+func (n *PathIndexAllNode) Field(fieldName string) (PathNode, bool, error) {
+ return nil, false, &errors.PathError{}
+}
+
+func (n *PathIndexAllNode) Get(src, dst reflect.Value) error {
+ switch src.Type().Kind() {
+ case reflect.Array, reflect.Slice:
+ var arr []interface{}
+ for i := 0; i < src.Len(); i++ {
+ var v interface{}
+ rv := reflect.ValueOf(&v)
+ if n.child != nil {
+ if err := n.child.Get(src.Index(i), rv); err != nil {
+ return err
+ }
+ } else {
+ if err := AssignValue(src.Index(i), rv); err != nil {
+ return err
+ }
+ }
+ arr = append(arr, v)
+ }
+ if err := AssignValue(reflect.ValueOf(arr), dst); err != nil {
+ return err
+ }
+ return nil
+ case reflect.Ptr:
+ return n.Get(src.Elem(), dst)
+ case reflect.Interface:
+ return n.Get(reflect.ValueOf(src.Interface()), dst)
+ }
+ return fmt.Errorf("failed to get all value from %s", src.Type())
+}
+
+func (n *PathIndexAllNode) String() string {
+ s := "[*]"
+ if n.child != nil {
+ s += n.child.String()
+ }
+ return s
+}
+
+type PathRecursiveNode struct {
+ *BasePathNode
+ selector string
+}
+
+func newPathRecursiveNode(selector string) *PathRecursiveNode {
+ node := newPathSelectorNode(selector)
+ return &PathRecursiveNode{
+ BasePathNode: &BasePathNode{
+ child: node,
+ },
+ selector: selector,
+ }
+}
+
+func (n *PathRecursiveNode) Field(fieldName string) (PathNode, bool, error) {
+ if n.selector == fieldName {
+ return n.child, true, nil
+ }
+ return nil, false, nil
+}
+
+func (n *PathRecursiveNode) Index(_ int) (PathNode, bool, error) {
+ return n, true, nil
+}
+
+func valueToSliceValue(v interface{}) []interface{} {
+ rv := reflect.ValueOf(v)
+ ret := []interface{}{}
+ if rv.Type().Kind() == reflect.Slice || rv.Type().Kind() == reflect.Array {
+ for i := 0; i < rv.Len(); i++ {
+ ret = append(ret, rv.Index(i).Interface())
+ }
+ return ret
+ }
+ return []interface{}{v}
+}
+
+func (n *PathRecursiveNode) Get(src, dst reflect.Value) error {
+ if n.child == nil {
+ return fmt.Errorf("failed to get by recursive path ..%s", n.selector)
+ }
+ var arr []interface{}
+ switch src.Type().Kind() {
+ case reflect.Map:
+ iter := src.MapRange()
+ for iter.Next() {
+ key, ok := iter.Key().Interface().(string)
+ if !ok {
+ return fmt.Errorf("invalid map key type %T", src.Type().Key())
+ }
+ child, found, err := n.Field(key)
+ if err != nil {
+ return err
+ }
+ if found {
+ var v interface{}
+ rv := reflect.ValueOf(&v)
+ _ = child.Get(iter.Value(), rv)
+ arr = append(arr, valueToSliceValue(v)...)
+ } else {
+ var v interface{}
+ rv := reflect.ValueOf(&v)
+ _ = n.Get(iter.Value(), rv)
+ if v != nil {
+ arr = append(arr, valueToSliceValue(v)...)
+ }
+ }
+ }
+ _ = AssignValue(reflect.ValueOf(arr), dst)
+ return nil
+ case reflect.Struct:
+ typ := src.Type()
+ for i := 0; i < typ.Len(); i++ {
+ tag := runtime.StructTagFromField(typ.Field(i))
+ child, found, err := n.Field(tag.Key)
+ if err != nil {
+ return err
+ }
+ if found {
+ var v interface{}
+ rv := reflect.ValueOf(&v)
+ _ = child.Get(src.Field(i), rv)
+ arr = append(arr, valueToSliceValue(v)...)
+ } else {
+ var v interface{}
+ rv := reflect.ValueOf(&v)
+ _ = n.Get(src.Field(i), rv)
+ if v != nil {
+ arr = append(arr, valueToSliceValue(v)...)
+ }
+ }
+ }
+ _ = AssignValue(reflect.ValueOf(arr), dst)
+ return nil
+ case reflect.Array, reflect.Slice:
+ for i := 0; i < src.Len(); i++ {
+ var v interface{}
+ rv := reflect.ValueOf(&v)
+ _ = n.Get(src.Index(i), rv)
+ if v != nil {
+ arr = append(arr, valueToSliceValue(v)...)
+ }
+ }
+ _ = AssignValue(reflect.ValueOf(arr), dst)
+ return nil
+ case reflect.Ptr:
+ return n.Get(src.Elem(), dst)
+ case reflect.Interface:
+ return n.Get(reflect.ValueOf(src.Interface()), dst)
+ }
+ return fmt.Errorf("failed to get %s value from %s", n.selector, src.Type())
+}
+
+func (n *PathRecursiveNode) String() string {
+ s := fmt.Sprintf("..%s", n.selector)
+ if n.child != nil {
+ s += n.child.String()
+ }
+ return s
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/ptr.go b/vendor/github.com/goccy/go-json/internal/decoder/ptr.go
new file mode 100644
index 00000000..ae229946
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/ptr.go
@@ -0,0 +1,97 @@
+package decoder
+
+import (
+ "fmt"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type ptrDecoder struct {
+ dec Decoder
+ typ *runtime.Type
+ structName string
+ fieldName string
+}
+
+func newPtrDecoder(dec Decoder, typ *runtime.Type, structName, fieldName string) *ptrDecoder {
+ return &ptrDecoder{
+ dec: dec,
+ typ: typ,
+ structName: structName,
+ fieldName: fieldName,
+ }
+}
+
+func (d *ptrDecoder) contentDecoder() Decoder {
+ dec, ok := d.dec.(*ptrDecoder)
+ if !ok {
+ return d.dec
+ }
+ return dec.contentDecoder()
+}
+
+//nolint:golint
+//go:linkname unsafe_New reflect.unsafe_New
+func unsafe_New(*runtime.Type) unsafe.Pointer
+
+func UnsafeNew(t *runtime.Type) unsafe.Pointer {
+ return unsafe_New(t)
+}
+
+func (d *ptrDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ if s.skipWhiteSpace() == nul {
+ s.read()
+ }
+ if s.char() == 'n' {
+ if err := nullBytes(s); err != nil {
+ return err
+ }
+ *(*unsafe.Pointer)(p) = nil
+ return nil
+ }
+ var newptr unsafe.Pointer
+ if *(*unsafe.Pointer)(p) == nil {
+ newptr = unsafe_New(d.typ)
+ *(*unsafe.Pointer)(p) = newptr
+ } else {
+ newptr = *(*unsafe.Pointer)(p)
+ }
+ if err := d.dec.DecodeStream(s, depth, newptr); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (d *ptrDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ buf := ctx.Buf
+ cursor = skipWhiteSpace(buf, cursor)
+ if buf[cursor] == 'n' {
+ if err := validateNull(buf, cursor); err != nil {
+ return 0, err
+ }
+ if p != nil {
+ *(*unsafe.Pointer)(p) = nil
+ }
+ cursor += 4
+ return cursor, nil
+ }
+ var newptr unsafe.Pointer
+ if *(*unsafe.Pointer)(p) == nil {
+ newptr = unsafe_New(d.typ)
+ *(*unsafe.Pointer)(p) = newptr
+ } else {
+ newptr = *(*unsafe.Pointer)(p)
+ }
+ c, err := d.dec.Decode(ctx, cursor, depth, newptr)
+ if err != nil {
+ *(*unsafe.Pointer)(p) = nil
+ return 0, err
+ }
+ cursor = c
+ return cursor, nil
+}
+
+func (d *ptrDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ return nil, 0, fmt.Errorf("json: ptr decoder does not support decode path")
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/slice.go b/vendor/github.com/goccy/go-json/internal/decoder/slice.go
new file mode 100644
index 00000000..30a23e4b
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/slice.go
@@ -0,0 +1,380 @@
+package decoder
+
+import (
+ "reflect"
+ "sync"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+var (
+ sliceType = runtime.Type2RType(
+ reflect.TypeOf((*sliceHeader)(nil)).Elem(),
+ )
+ nilSlice = unsafe.Pointer(&sliceHeader{})
+)
+
+type sliceDecoder struct {
+ elemType *runtime.Type
+ isElemPointerType bool
+ valueDecoder Decoder
+ size uintptr
+ arrayPool sync.Pool
+ structName string
+ fieldName string
+}
+
+// If use reflect.SliceHeader, data type is uintptr.
+// In this case, Go compiler cannot trace reference created by newArray().
+// So, define using unsafe.Pointer as data type
+type sliceHeader struct {
+ data unsafe.Pointer
+ len int
+ cap int
+}
+
+const (
+ defaultSliceCapacity = 2
+)
+
+func newSliceDecoder(dec Decoder, elemType *runtime.Type, size uintptr, structName, fieldName string) *sliceDecoder {
+ return &sliceDecoder{
+ valueDecoder: dec,
+ elemType: elemType,
+ isElemPointerType: elemType.Kind() == reflect.Ptr || elemType.Kind() == reflect.Map,
+ size: size,
+ arrayPool: sync.Pool{
+ New: func() interface{} {
+ return &sliceHeader{
+ data: newArray(elemType, defaultSliceCapacity),
+ len: 0,
+ cap: defaultSliceCapacity,
+ }
+ },
+ },
+ structName: structName,
+ fieldName: fieldName,
+ }
+}
+
+func (d *sliceDecoder) newSlice(src *sliceHeader) *sliceHeader {
+ slice := d.arrayPool.Get().(*sliceHeader)
+ if src.len > 0 {
+ // copy original elem
+ if slice.cap < src.cap {
+ data := newArray(d.elemType, src.cap)
+ slice = &sliceHeader{data: data, len: src.len, cap: src.cap}
+ } else {
+ slice.len = src.len
+ }
+ copySlice(d.elemType, *slice, *src)
+ } else {
+ slice.len = 0
+ }
+ return slice
+}
+
+func (d *sliceDecoder) releaseSlice(p *sliceHeader) {
+ d.arrayPool.Put(p)
+}
+
+//go:linkname copySlice reflect.typedslicecopy
+func copySlice(elemType *runtime.Type, dst, src sliceHeader) int
+
+//go:linkname newArray reflect.unsafe_NewArray
+func newArray(*runtime.Type, int) unsafe.Pointer
+
+//go:linkname typedmemmove reflect.typedmemmove
+func typedmemmove(t *runtime.Type, dst, src unsafe.Pointer)
+
+func (d *sliceDecoder) errNumber(offset int64) *errors.UnmarshalTypeError {
+ return &errors.UnmarshalTypeError{
+ Value: "number",
+ Type: reflect.SliceOf(runtime.RType2Type(d.elemType)),
+ Struct: d.structName,
+ Field: d.fieldName,
+ Offset: offset,
+ }
+}
+
+func (d *sliceDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return errors.ErrExceededMaxDepth(s.char(), s.cursor)
+ }
+
+ for {
+ switch s.char() {
+ case ' ', '\n', '\t', '\r':
+ s.cursor++
+ continue
+ case 'n':
+ if err := nullBytes(s); err != nil {
+ return err
+ }
+ typedmemmove(sliceType, p, nilSlice)
+ return nil
+ case '[':
+ s.cursor++
+ if s.skipWhiteSpace() == ']' {
+ dst := (*sliceHeader)(p)
+ if dst.data == nil {
+ dst.data = newArray(d.elemType, 0)
+ } else {
+ dst.len = 0
+ }
+ s.cursor++
+ return nil
+ }
+ idx := 0
+ slice := d.newSlice((*sliceHeader)(p))
+ srcLen := slice.len
+ capacity := slice.cap
+ data := slice.data
+ for {
+ if capacity <= idx {
+ src := sliceHeader{data: data, len: idx, cap: capacity}
+ capacity *= 2
+ data = newArray(d.elemType, capacity)
+ dst := sliceHeader{data: data, len: idx, cap: capacity}
+ copySlice(d.elemType, dst, src)
+ }
+ ep := unsafe.Pointer(uintptr(data) + uintptr(idx)*d.size)
+
+ // if srcLen is greater than idx, keep the original reference
+ if srcLen <= idx {
+ if d.isElemPointerType {
+ **(**unsafe.Pointer)(unsafe.Pointer(&ep)) = nil // initialize elem pointer
+ } else {
+ // assign new element to the slice
+ typedmemmove(d.elemType, ep, unsafe_New(d.elemType))
+ }
+ }
+
+ if err := d.valueDecoder.DecodeStream(s, depth, ep); err != nil {
+ return err
+ }
+ s.skipWhiteSpace()
+ RETRY:
+ switch s.char() {
+ case ']':
+ slice.cap = capacity
+ slice.len = idx + 1
+ slice.data = data
+ dst := (*sliceHeader)(p)
+ dst.len = idx + 1
+ if dst.len > dst.cap {
+ dst.data = newArray(d.elemType, dst.len)
+ dst.cap = dst.len
+ }
+ copySlice(d.elemType, *dst, *slice)
+ d.releaseSlice(slice)
+ s.cursor++
+ return nil
+ case ',':
+ idx++
+ case nul:
+ if s.read() {
+ goto RETRY
+ }
+ slice.cap = capacity
+ slice.data = data
+ d.releaseSlice(slice)
+ goto ERROR
+ default:
+ slice.cap = capacity
+ slice.data = data
+ d.releaseSlice(slice)
+ goto ERROR
+ }
+ s.cursor++
+ }
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return d.errNumber(s.totalOffset())
+ case nul:
+ if s.read() {
+ continue
+ }
+ goto ERROR
+ default:
+ goto ERROR
+ }
+ }
+ERROR:
+ return errors.ErrUnexpectedEndOfJSON("slice", s.totalOffset())
+}
+
+func (d *sliceDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ buf := ctx.Buf
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
+ }
+
+ for {
+ switch buf[cursor] {
+ case ' ', '\n', '\t', '\r':
+ cursor++
+ continue
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return 0, err
+ }
+ cursor += 4
+ typedmemmove(sliceType, p, nilSlice)
+ return cursor, nil
+ case '[':
+ cursor++
+ cursor = skipWhiteSpace(buf, cursor)
+ if buf[cursor] == ']' {
+ dst := (*sliceHeader)(p)
+ if dst.data == nil {
+ dst.data = newArray(d.elemType, 0)
+ } else {
+ dst.len = 0
+ }
+ cursor++
+ return cursor, nil
+ }
+ idx := 0
+ slice := d.newSlice((*sliceHeader)(p))
+ srcLen := slice.len
+ capacity := slice.cap
+ data := slice.data
+ for {
+ if capacity <= idx {
+ src := sliceHeader{data: data, len: idx, cap: capacity}
+ capacity *= 2
+ data = newArray(d.elemType, capacity)
+ dst := sliceHeader{data: data, len: idx, cap: capacity}
+ copySlice(d.elemType, dst, src)
+ }
+ ep := unsafe.Pointer(uintptr(data) + uintptr(idx)*d.size)
+ // if srcLen is greater than idx, keep the original reference
+ if srcLen <= idx {
+ if d.isElemPointerType {
+ **(**unsafe.Pointer)(unsafe.Pointer(&ep)) = nil // initialize elem pointer
+ } else {
+ // assign new element to the slice
+ typedmemmove(d.elemType, ep, unsafe_New(d.elemType))
+ }
+ }
+ c, err := d.valueDecoder.Decode(ctx, cursor, depth, ep)
+ if err != nil {
+ return 0, err
+ }
+ cursor = c
+ cursor = skipWhiteSpace(buf, cursor)
+ switch buf[cursor] {
+ case ']':
+ slice.cap = capacity
+ slice.len = idx + 1
+ slice.data = data
+ dst := (*sliceHeader)(p)
+ dst.len = idx + 1
+ if dst.len > dst.cap {
+ dst.data = newArray(d.elemType, dst.len)
+ dst.cap = dst.len
+ }
+ copySlice(d.elemType, *dst, *slice)
+ d.releaseSlice(slice)
+ cursor++
+ return cursor, nil
+ case ',':
+ idx++
+ default:
+ slice.cap = capacity
+ slice.data = data
+ d.releaseSlice(slice)
+ return 0, errors.ErrInvalidCharacter(buf[cursor], "slice", cursor)
+ }
+ cursor++
+ }
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return 0, d.errNumber(cursor)
+ default:
+ return 0, errors.ErrUnexpectedEndOfJSON("slice", cursor)
+ }
+ }
+}
+
+func (d *sliceDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ buf := ctx.Buf
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return nil, 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
+ }
+
+ ret := [][]byte{}
+ for {
+ switch buf[cursor] {
+ case ' ', '\n', '\t', '\r':
+ cursor++
+ continue
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return nil, 0, err
+ }
+ cursor += 4
+ return [][]byte{nullbytes}, cursor, nil
+ case '[':
+ cursor++
+ cursor = skipWhiteSpace(buf, cursor)
+ if buf[cursor] == ']' {
+ cursor++
+ return ret, cursor, nil
+ }
+ idx := 0
+ for {
+ child, found, err := ctx.Option.Path.node.Index(idx)
+ if err != nil {
+ return nil, 0, err
+ }
+ if found {
+ if child != nil {
+ oldPath := ctx.Option.Path.node
+ ctx.Option.Path.node = child
+ paths, c, err := d.valueDecoder.DecodePath(ctx, cursor, depth)
+ if err != nil {
+ return nil, 0, err
+ }
+ ctx.Option.Path.node = oldPath
+ ret = append(ret, paths...)
+ cursor = c
+ } else {
+ start := cursor
+ end, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return nil, 0, err
+ }
+ ret = append(ret, buf[start:end])
+ cursor = end
+ }
+ } else {
+ c, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return nil, 0, err
+ }
+ cursor = c
+ }
+ cursor = skipWhiteSpace(buf, cursor)
+ switch buf[cursor] {
+ case ']':
+ cursor++
+ return ret, cursor, nil
+ case ',':
+ idx++
+ default:
+ return nil, 0, errors.ErrInvalidCharacter(buf[cursor], "slice", cursor)
+ }
+ cursor++
+ }
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return nil, 0, d.errNumber(cursor)
+ default:
+ return nil, 0, errors.ErrUnexpectedEndOfJSON("slice", cursor)
+ }
+ }
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/stream.go b/vendor/github.com/goccy/go-json/internal/decoder/stream.go
new file mode 100644
index 00000000..a383f725
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/stream.go
@@ -0,0 +1,556 @@
+package decoder
+
+import (
+ "bytes"
+ "encoding/json"
+ "io"
+ "strconv"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+)
+
+const (
+ initBufSize = 512
+)
+
+type Stream struct {
+ buf []byte
+ bufSize int64
+ length int64
+ r io.Reader
+ offset int64
+ cursor int64
+ filledBuffer bool
+ allRead bool
+ UseNumber bool
+ DisallowUnknownFields bool
+ Option *Option
+}
+
+func NewStream(r io.Reader) *Stream {
+ return &Stream{
+ r: r,
+ bufSize: initBufSize,
+ buf: make([]byte, initBufSize),
+ Option: &Option{},
+ }
+}
+
+func (s *Stream) TotalOffset() int64 {
+ return s.totalOffset()
+}
+
+func (s *Stream) Buffered() io.Reader {
+ buflen := int64(len(s.buf))
+ for i := s.cursor; i < buflen; i++ {
+ if s.buf[i] == nul {
+ return bytes.NewReader(s.buf[s.cursor:i])
+ }
+ }
+ return bytes.NewReader(s.buf[s.cursor:])
+}
+
+func (s *Stream) PrepareForDecode() error {
+ for {
+ switch s.char() {
+ case ' ', '\t', '\r', '\n':
+ s.cursor++
+ continue
+ case ',', ':':
+ s.cursor++
+ return nil
+ case nul:
+ if s.read() {
+ continue
+ }
+ return io.EOF
+ }
+ break
+ }
+ return nil
+}
+
+func (s *Stream) totalOffset() int64 {
+ return s.offset + s.cursor
+}
+
+func (s *Stream) char() byte {
+ return s.buf[s.cursor]
+}
+
+func (s *Stream) equalChar(c byte) bool {
+ cur := s.buf[s.cursor]
+ if cur == nul {
+ s.read()
+ cur = s.buf[s.cursor]
+ }
+ return cur == c
+}
+
+func (s *Stream) stat() ([]byte, int64, unsafe.Pointer) {
+ return s.buf, s.cursor, (*sliceHeader)(unsafe.Pointer(&s.buf)).data
+}
+
+func (s *Stream) bufptr() unsafe.Pointer {
+ return (*sliceHeader)(unsafe.Pointer(&s.buf)).data
+}
+
+func (s *Stream) statForRetry() ([]byte, int64, unsafe.Pointer) {
+ s.cursor-- // for retry ( because caller progress cursor position in each loop )
+ return s.buf, s.cursor, (*sliceHeader)(unsafe.Pointer(&s.buf)).data
+}
+
+func (s *Stream) Reset() {
+ s.reset()
+ s.bufSize = int64(len(s.buf))
+}
+
+func (s *Stream) More() bool {
+ for {
+ switch s.char() {
+ case ' ', '\n', '\r', '\t':
+ s.cursor++
+ continue
+ case '}', ']':
+ return false
+ case nul:
+ if s.read() {
+ continue
+ }
+ return false
+ }
+ break
+ }
+ return true
+}
+
+func (s *Stream) Token() (interface{}, error) {
+ for {
+ c := s.char()
+ switch c {
+ case ' ', '\n', '\r', '\t':
+ s.cursor++
+ case '{', '[', ']', '}':
+ s.cursor++
+ return json.Delim(c), nil
+ case ',', ':':
+ s.cursor++
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ bytes := floatBytes(s)
+ str := *(*string)(unsafe.Pointer(&bytes))
+ if s.UseNumber {
+ return json.Number(str), nil
+ }
+ f64, err := strconv.ParseFloat(str, 64)
+ if err != nil {
+ return nil, err
+ }
+ return f64, nil
+ case '"':
+ bytes, err := stringBytes(s)
+ if err != nil {
+ return nil, err
+ }
+ return string(bytes), nil
+ case 't':
+ if err := trueBytes(s); err != nil {
+ return nil, err
+ }
+ return true, nil
+ case 'f':
+ if err := falseBytes(s); err != nil {
+ return nil, err
+ }
+ return false, nil
+ case 'n':
+ if err := nullBytes(s); err != nil {
+ return nil, err
+ }
+ return nil, nil
+ case nul:
+ if s.read() {
+ continue
+ }
+ goto END
+ default:
+ return nil, errors.ErrInvalidCharacter(s.char(), "token", s.totalOffset())
+ }
+ }
+END:
+ return nil, io.EOF
+}
+
+func (s *Stream) reset() {
+ s.offset += s.cursor
+ s.buf = s.buf[s.cursor:]
+ s.length -= s.cursor
+ s.cursor = 0
+}
+
+func (s *Stream) readBuf() []byte {
+ if s.filledBuffer {
+ s.bufSize *= 2
+ remainBuf := s.buf
+ s.buf = make([]byte, s.bufSize)
+ copy(s.buf, remainBuf)
+ }
+ remainLen := s.length - s.cursor
+ remainNotNulCharNum := int64(0)
+ for i := int64(0); i < remainLen; i++ {
+ if s.buf[s.cursor+i] == nul {
+ break
+ }
+ remainNotNulCharNum++
+ }
+ s.length = s.cursor + remainNotNulCharNum
+ return s.buf[s.cursor+remainNotNulCharNum:]
+}
+
+func (s *Stream) read() bool {
+ if s.allRead {
+ return false
+ }
+ buf := s.readBuf()
+ last := len(buf) - 1
+ buf[last] = nul
+ n, err := s.r.Read(buf[:last])
+ s.length += int64(n)
+ if n == last {
+ s.filledBuffer = true
+ } else {
+ s.filledBuffer = false
+ }
+ if err == io.EOF {
+ s.allRead = true
+ } else if err != nil {
+ return false
+ }
+ return true
+}
+
+func (s *Stream) skipWhiteSpace() byte {
+ p := s.bufptr()
+LOOP:
+ c := char(p, s.cursor)
+ switch c {
+ case ' ', '\n', '\t', '\r':
+ s.cursor++
+ goto LOOP
+ case nul:
+ if s.read() {
+ p = s.bufptr()
+ goto LOOP
+ }
+ }
+ return c
+}
+
+func (s *Stream) skipObject(depth int64) error {
+ braceCount := 1
+ _, cursor, p := s.stat()
+ for {
+ switch char(p, cursor) {
+ case '{':
+ braceCount++
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return errors.ErrExceededMaxDepth(s.char(), s.cursor)
+ }
+ case '}':
+ braceCount--
+ depth--
+ if braceCount == 0 {
+ s.cursor = cursor + 1
+ return nil
+ }
+ case '[':
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return errors.ErrExceededMaxDepth(s.char(), s.cursor)
+ }
+ case ']':
+ depth--
+ case '"':
+ for {
+ cursor++
+ switch char(p, cursor) {
+ case '\\':
+ cursor++
+ if char(p, cursor) == nul {
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.stat()
+ continue
+ }
+ return errors.ErrUnexpectedEndOfJSON("string of object", cursor)
+ }
+ case '"':
+ goto SWITCH_OUT
+ case nul:
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.statForRetry()
+ continue
+ }
+ return errors.ErrUnexpectedEndOfJSON("string of object", cursor)
+ }
+ }
+ case nul:
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.stat()
+ continue
+ }
+ return errors.ErrUnexpectedEndOfJSON("object of object", cursor)
+ }
+ SWITCH_OUT:
+ cursor++
+ }
+}
+
+func (s *Stream) skipArray(depth int64) error {
+ bracketCount := 1
+ _, cursor, p := s.stat()
+ for {
+ switch char(p, cursor) {
+ case '[':
+ bracketCount++
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return errors.ErrExceededMaxDepth(s.char(), s.cursor)
+ }
+ case ']':
+ bracketCount--
+ depth--
+ if bracketCount == 0 {
+ s.cursor = cursor + 1
+ return nil
+ }
+ case '{':
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return errors.ErrExceededMaxDepth(s.char(), s.cursor)
+ }
+ case '}':
+ depth--
+ case '"':
+ for {
+ cursor++
+ switch char(p, cursor) {
+ case '\\':
+ cursor++
+ if char(p, cursor) == nul {
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.stat()
+ continue
+ }
+ return errors.ErrUnexpectedEndOfJSON("string of object", cursor)
+ }
+ case '"':
+ goto SWITCH_OUT
+ case nul:
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.statForRetry()
+ continue
+ }
+ return errors.ErrUnexpectedEndOfJSON("string of object", cursor)
+ }
+ }
+ case nul:
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.stat()
+ continue
+ }
+ return errors.ErrUnexpectedEndOfJSON("array of object", cursor)
+ }
+ SWITCH_OUT:
+ cursor++
+ }
+}
+
+func (s *Stream) skipValue(depth int64) error {
+ _, cursor, p := s.stat()
+ for {
+ switch char(p, cursor) {
+ case ' ', '\n', '\t', '\r':
+ cursor++
+ continue
+ case nul:
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.stat()
+ continue
+ }
+ return errors.ErrUnexpectedEndOfJSON("value of object", s.totalOffset())
+ case '{':
+ s.cursor = cursor + 1
+ return s.skipObject(depth + 1)
+ case '[':
+ s.cursor = cursor + 1
+ return s.skipArray(depth + 1)
+ case '"':
+ for {
+ cursor++
+ switch char(p, cursor) {
+ case '\\':
+ cursor++
+ if char(p, cursor) == nul {
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.stat()
+ continue
+ }
+ return errors.ErrUnexpectedEndOfJSON("value of string", s.totalOffset())
+ }
+ case '"':
+ s.cursor = cursor + 1
+ return nil
+ case nul:
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.statForRetry()
+ continue
+ }
+ return errors.ErrUnexpectedEndOfJSON("value of string", s.totalOffset())
+ }
+ }
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ for {
+ cursor++
+ c := char(p, cursor)
+ if floatTable[c] {
+ continue
+ } else if c == nul {
+ if s.read() {
+ _, cursor, p = s.stat()
+ continue
+ }
+ }
+ s.cursor = cursor
+ return nil
+ }
+ case 't':
+ s.cursor = cursor
+ if err := trueBytes(s); err != nil {
+ return err
+ }
+ return nil
+ case 'f':
+ s.cursor = cursor
+ if err := falseBytes(s); err != nil {
+ return err
+ }
+ return nil
+ case 'n':
+ s.cursor = cursor
+ if err := nullBytes(s); err != nil {
+ return err
+ }
+ return nil
+ }
+ cursor++
+ }
+}
+
+func nullBytes(s *Stream) error {
+ // current cursor's character is 'n'
+ s.cursor++
+ if s.char() != 'u' {
+ if err := retryReadNull(s); err != nil {
+ return err
+ }
+ }
+ s.cursor++
+ if s.char() != 'l' {
+ if err := retryReadNull(s); err != nil {
+ return err
+ }
+ }
+ s.cursor++
+ if s.char() != 'l' {
+ if err := retryReadNull(s); err != nil {
+ return err
+ }
+ }
+ s.cursor++
+ return nil
+}
+
+func retryReadNull(s *Stream) error {
+ if s.char() == nul && s.read() {
+ return nil
+ }
+ return errors.ErrInvalidCharacter(s.char(), "null", s.totalOffset())
+}
+
+func trueBytes(s *Stream) error {
+ // current cursor's character is 't'
+ s.cursor++
+ if s.char() != 'r' {
+ if err := retryReadTrue(s); err != nil {
+ return err
+ }
+ }
+ s.cursor++
+ if s.char() != 'u' {
+ if err := retryReadTrue(s); err != nil {
+ return err
+ }
+ }
+ s.cursor++
+ if s.char() != 'e' {
+ if err := retryReadTrue(s); err != nil {
+ return err
+ }
+ }
+ s.cursor++
+ return nil
+}
+
+func retryReadTrue(s *Stream) error {
+ if s.char() == nul && s.read() {
+ return nil
+ }
+ return errors.ErrInvalidCharacter(s.char(), "bool(true)", s.totalOffset())
+}
+
+func falseBytes(s *Stream) error {
+ // current cursor's character is 'f'
+ s.cursor++
+ if s.char() != 'a' {
+ if err := retryReadFalse(s); err != nil {
+ return err
+ }
+ }
+ s.cursor++
+ if s.char() != 'l' {
+ if err := retryReadFalse(s); err != nil {
+ return err
+ }
+ }
+ s.cursor++
+ if s.char() != 's' {
+ if err := retryReadFalse(s); err != nil {
+ return err
+ }
+ }
+ s.cursor++
+ if s.char() != 'e' {
+ if err := retryReadFalse(s); err != nil {
+ return err
+ }
+ }
+ s.cursor++
+ return nil
+}
+
+func retryReadFalse(s *Stream) error {
+ if s.char() == nul && s.read() {
+ return nil
+ }
+ return errors.ErrInvalidCharacter(s.char(), "bool(false)", s.totalOffset())
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/string.go b/vendor/github.com/goccy/go-json/internal/decoder/string.go
new file mode 100644
index 00000000..32602c90
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/string.go
@@ -0,0 +1,452 @@
+package decoder
+
+import (
+ "bytes"
+ "fmt"
+ "reflect"
+ "unicode"
+ "unicode/utf16"
+ "unicode/utf8"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+)
+
+type stringDecoder struct {
+ structName string
+ fieldName string
+}
+
+func newStringDecoder(structName, fieldName string) *stringDecoder {
+ return &stringDecoder{
+ structName: structName,
+ fieldName: fieldName,
+ }
+}
+
+func (d *stringDecoder) errUnmarshalType(typeName string, offset int64) *errors.UnmarshalTypeError {
+ return &errors.UnmarshalTypeError{
+ Value: typeName,
+ Type: reflect.TypeOf(""),
+ Offset: offset,
+ Struct: d.structName,
+ Field: d.fieldName,
+ }
+}
+
+func (d *stringDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ bytes, err := d.decodeStreamByte(s)
+ if err != nil {
+ return err
+ }
+ if bytes == nil {
+ return nil
+ }
+ **(**string)(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&bytes))
+ s.reset()
+ return nil
+}
+
+func (d *stringDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ bytes, c, err := d.decodeByte(ctx.Buf, cursor)
+ if err != nil {
+ return 0, err
+ }
+ if bytes == nil {
+ return c, nil
+ }
+ cursor = c
+ **(**string)(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&bytes))
+ return cursor, nil
+}
+
+func (d *stringDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ bytes, c, err := d.decodeByte(ctx.Buf, cursor)
+ if err != nil {
+ return nil, 0, err
+ }
+ if bytes == nil {
+ return [][]byte{nullbytes}, c, nil
+ }
+ return [][]byte{bytes}, c, nil
+}
+
+var (
+ hexToInt = [256]int{
+ '0': 0,
+ '1': 1,
+ '2': 2,
+ '3': 3,
+ '4': 4,
+ '5': 5,
+ '6': 6,
+ '7': 7,
+ '8': 8,
+ '9': 9,
+ 'A': 10,
+ 'B': 11,
+ 'C': 12,
+ 'D': 13,
+ 'E': 14,
+ 'F': 15,
+ 'a': 10,
+ 'b': 11,
+ 'c': 12,
+ 'd': 13,
+ 'e': 14,
+ 'f': 15,
+ }
+)
+
+func unicodeToRune(code []byte) rune {
+ var r rune
+ for i := 0; i < len(code); i++ {
+ r = r*16 + rune(hexToInt[code[i]])
+ }
+ return r
+}
+
+func readAtLeast(s *Stream, n int64, p *unsafe.Pointer) bool {
+ for s.cursor+n >= s.length {
+ if !s.read() {
+ return false
+ }
+ *p = s.bufptr()
+ }
+ return true
+}
+
+func decodeUnicodeRune(s *Stream, p unsafe.Pointer) (rune, int64, unsafe.Pointer, error) {
+ const defaultOffset = 5
+ const surrogateOffset = 11
+
+ if !readAtLeast(s, defaultOffset, &p) {
+ return rune(0), 0, nil, errors.ErrInvalidCharacter(s.char(), "escaped string", s.totalOffset())
+ }
+
+ r := unicodeToRune(s.buf[s.cursor+1 : s.cursor+defaultOffset])
+ if utf16.IsSurrogate(r) {
+ if !readAtLeast(s, surrogateOffset, &p) {
+ return unicode.ReplacementChar, defaultOffset, p, nil
+ }
+ if s.buf[s.cursor+defaultOffset] != '\\' || s.buf[s.cursor+defaultOffset+1] != 'u' {
+ return unicode.ReplacementChar, defaultOffset, p, nil
+ }
+ r2 := unicodeToRune(s.buf[s.cursor+defaultOffset+2 : s.cursor+surrogateOffset])
+ if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar {
+ return r, surrogateOffset, p, nil
+ }
+ }
+ return r, defaultOffset, p, nil
+}
+
+func decodeUnicode(s *Stream, p unsafe.Pointer) (unsafe.Pointer, error) {
+ const backSlashAndULen = 2 // length of \u
+
+ r, offset, pp, err := decodeUnicodeRune(s, p)
+ if err != nil {
+ return nil, err
+ }
+ unicode := []byte(string(r))
+ unicodeLen := int64(len(unicode))
+ s.buf = append(append(s.buf[:s.cursor-1], unicode...), s.buf[s.cursor+offset:]...)
+ unicodeOrgLen := offset - 1
+ s.length = s.length - (backSlashAndULen + (unicodeOrgLen - unicodeLen))
+ s.cursor = s.cursor - backSlashAndULen + unicodeLen
+ return pp, nil
+}
+
+func decodeEscapeString(s *Stream, p unsafe.Pointer) (unsafe.Pointer, error) {
+ s.cursor++
+RETRY:
+ switch s.buf[s.cursor] {
+ case '"':
+ s.buf[s.cursor] = '"'
+ case '\\':
+ s.buf[s.cursor] = '\\'
+ case '/':
+ s.buf[s.cursor] = '/'
+ case 'b':
+ s.buf[s.cursor] = '\b'
+ case 'f':
+ s.buf[s.cursor] = '\f'
+ case 'n':
+ s.buf[s.cursor] = '\n'
+ case 'r':
+ s.buf[s.cursor] = '\r'
+ case 't':
+ s.buf[s.cursor] = '\t'
+ case 'u':
+ return decodeUnicode(s, p)
+ case nul:
+ if !s.read() {
+ return nil, errors.ErrInvalidCharacter(s.char(), "escaped string", s.totalOffset())
+ }
+ p = s.bufptr()
+ goto RETRY
+ default:
+ return nil, errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
+ }
+ s.buf = append(s.buf[:s.cursor-1], s.buf[s.cursor:]...)
+ s.length--
+ s.cursor--
+ p = s.bufptr()
+ return p, nil
+}
+
+var (
+ runeErrBytes = []byte(string(utf8.RuneError))
+ runeErrBytesLen = int64(len(runeErrBytes))
+)
+
+func stringBytes(s *Stream) ([]byte, error) {
+ _, cursor, p := s.stat()
+ cursor++ // skip double quote char
+ start := cursor
+ for {
+ switch char(p, cursor) {
+ case '\\':
+ s.cursor = cursor
+ pp, err := decodeEscapeString(s, p)
+ if err != nil {
+ return nil, err
+ }
+ p = pp
+ cursor = s.cursor
+ case '"':
+ literal := s.buf[start:cursor]
+ cursor++
+ s.cursor = cursor
+ return literal, nil
+ case
+ // 0x00 is nul, 0x5c is '\\', 0x22 is '"' .
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, // 0x00-0x0F
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, // 0x10-0x1F
+ 0x20, 0x21 /*0x22,*/, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, // 0x20-0x2F
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, // 0x30-0x3F
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, // 0x40-0x4F
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B /*0x5C,*/, 0x5D, 0x5E, 0x5F, // 0x50-0x5F
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, // 0x60-0x6F
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F: // 0x70-0x7F
+ // character is ASCII. skip to next char
+ case
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, // 0x80-0x8F
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, // 0x90-0x9F
+ 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, // 0xA0-0xAF
+ 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, // 0xB0-0xBF
+ 0xC0, 0xC1, // 0xC0-0xC1
+ 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF: // 0xF5-0xFE
+ // character is invalid
+ s.buf = append(append(append([]byte{}, s.buf[:cursor]...), runeErrBytes...), s.buf[cursor+1:]...)
+ _, _, p = s.stat()
+ cursor += runeErrBytesLen
+ s.length += runeErrBytesLen
+ continue
+ case nul:
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.stat()
+ continue
+ }
+ goto ERROR
+ case 0xEF:
+ // RuneError is {0xEF, 0xBF, 0xBD}
+ if s.buf[cursor+1] == 0xBF && s.buf[cursor+2] == 0xBD {
+ // found RuneError: skip
+ cursor += 2
+ break
+ }
+ fallthrough
+ default:
+ // multi bytes character
+ if !utf8.FullRune(s.buf[cursor : len(s.buf)-1]) {
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.stat()
+ continue
+ }
+ goto ERROR
+ }
+ r, size := utf8.DecodeRune(s.buf[cursor:])
+ if r == utf8.RuneError {
+ s.buf = append(append(append([]byte{}, s.buf[:cursor]...), runeErrBytes...), s.buf[cursor+1:]...)
+ cursor += runeErrBytesLen
+ s.length += runeErrBytesLen
+ _, _, p = s.stat()
+ } else {
+ cursor += int64(size)
+ }
+ continue
+ }
+ cursor++
+ }
+ERROR:
+ return nil, errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
+}
+
+func (d *stringDecoder) decodeStreamByte(s *Stream) ([]byte, error) {
+ for {
+ switch s.char() {
+ case ' ', '\n', '\t', '\r':
+ s.cursor++
+ continue
+ case '[':
+ return nil, d.errUnmarshalType("array", s.totalOffset())
+ case '{':
+ return nil, d.errUnmarshalType("object", s.totalOffset())
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return nil, d.errUnmarshalType("number", s.totalOffset())
+ case '"':
+ return stringBytes(s)
+ case 'n':
+ if err := nullBytes(s); err != nil {
+ return nil, err
+ }
+ return nil, nil
+ case nul:
+ if s.read() {
+ continue
+ }
+ }
+ break
+ }
+ return nil, errors.ErrInvalidBeginningOfValue(s.char(), s.totalOffset())
+}
+
+func (d *stringDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
+ for {
+ switch buf[cursor] {
+ case ' ', '\n', '\t', '\r':
+ cursor++
+ case '[':
+ return nil, 0, d.errUnmarshalType("array", cursor)
+ case '{':
+ return nil, 0, d.errUnmarshalType("object", cursor)
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return nil, 0, d.errUnmarshalType("number", cursor)
+ case '"':
+ cursor++
+ start := cursor
+ b := (*sliceHeader)(unsafe.Pointer(&buf)).data
+ escaped := 0
+ for {
+ switch char(b, cursor) {
+ case '\\':
+ escaped++
+ cursor++
+ switch char(b, cursor) {
+ case '"', '\\', '/', 'b', 'f', 'n', 'r', 't':
+ cursor++
+ case 'u':
+ buflen := int64(len(buf))
+ if cursor+5 >= buflen {
+ return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor)
+ }
+ for i := int64(1); i <= 4; i++ {
+ c := char(b, cursor+i)
+ if !(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')) {
+ return nil, 0, errors.ErrSyntax(fmt.Sprintf("json: invalid character %c in \\u hexadecimal character escape", c), cursor+i)
+ }
+ }
+ cursor += 5
+ default:
+ return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor)
+ }
+ continue
+ case '"':
+ literal := buf[start:cursor]
+ if escaped > 0 {
+ literal = literal[:unescapeString(literal)]
+ }
+ cursor++
+ return literal, cursor, nil
+ case nul:
+ return nil, 0, errors.ErrUnexpectedEndOfJSON("string", cursor)
+ }
+ cursor++
+ }
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return nil, 0, err
+ }
+ cursor += 4
+ return nil, cursor, nil
+ default:
+ return nil, 0, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
+ }
+ }
+}
+
+var unescapeMap = [256]byte{
+ '"': '"',
+ '\\': '\\',
+ '/': '/',
+ 'b': '\b',
+ 'f': '\f',
+ 'n': '\n',
+ 'r': '\r',
+ 't': '\t',
+}
+
+func unsafeAdd(ptr unsafe.Pointer, offset int) unsafe.Pointer {
+ return unsafe.Pointer(uintptr(ptr) + uintptr(offset))
+}
+
+func unescapeString(buf []byte) int {
+ p := (*sliceHeader)(unsafe.Pointer(&buf)).data
+ end := unsafeAdd(p, len(buf))
+ src := unsafeAdd(p, bytes.IndexByte(buf, '\\'))
+ dst := src
+ for src != end {
+ c := char(src, 0)
+ if c == '\\' {
+ escapeChar := char(src, 1)
+ if escapeChar != 'u' {
+ *(*byte)(dst) = unescapeMap[escapeChar]
+ src = unsafeAdd(src, 2)
+ dst = unsafeAdd(dst, 1)
+ } else {
+ v1 := hexToInt[char(src, 2)]
+ v2 := hexToInt[char(src, 3)]
+ v3 := hexToInt[char(src, 4)]
+ v4 := hexToInt[char(src, 5)]
+ code := rune((v1 << 12) | (v2 << 8) | (v3 << 4) | v4)
+ if code >= 0xd800 && code < 0xdc00 && uintptr(unsafeAdd(src, 11)) < uintptr(end) {
+ if char(src, 6) == '\\' && char(src, 7) == 'u' {
+ v1 := hexToInt[char(src, 8)]
+ v2 := hexToInt[char(src, 9)]
+ v3 := hexToInt[char(src, 10)]
+ v4 := hexToInt[char(src, 11)]
+ lo := rune((v1 << 12) | (v2 << 8) | (v3 << 4) | v4)
+ if lo >= 0xdc00 && lo < 0xe000 {
+ code = (code-0xd800)<<10 | (lo - 0xdc00) + 0x10000
+ src = unsafeAdd(src, 6)
+ }
+ }
+ }
+ var b [utf8.UTFMax]byte
+ n := utf8.EncodeRune(b[:], code)
+ switch n {
+ case 4:
+ *(*byte)(unsafeAdd(dst, 3)) = b[3]
+ fallthrough
+ case 3:
+ *(*byte)(unsafeAdd(dst, 2)) = b[2]
+ fallthrough
+ case 2:
+ *(*byte)(unsafeAdd(dst, 1)) = b[1]
+ fallthrough
+ case 1:
+ *(*byte)(unsafeAdd(dst, 0)) = b[0]
+ }
+ src = unsafeAdd(src, 6)
+ dst = unsafeAdd(dst, n)
+ }
+ } else {
+ *(*byte)(dst) = c
+ src = unsafeAdd(src, 1)
+ dst = unsafeAdd(dst, 1)
+ }
+ }
+ return int(uintptr(dst) - uintptr(p))
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/struct.go b/vendor/github.com/goccy/go-json/internal/decoder/struct.go
new file mode 100644
index 00000000..313da153
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/struct.go
@@ -0,0 +1,845 @@
+package decoder
+
+import (
+ "fmt"
+ "math"
+ "math/bits"
+ "sort"
+ "strings"
+ "unicode"
+ "unicode/utf16"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+)
+
+type structFieldSet struct {
+ dec Decoder
+ offset uintptr
+ isTaggedKey bool
+ fieldIdx int
+ key string
+ keyLen int64
+ err error
+}
+
+type structDecoder struct {
+ fieldMap map[string]*structFieldSet
+ fieldUniqueNameNum int
+ stringDecoder *stringDecoder
+ structName string
+ fieldName string
+ isTriedOptimize bool
+ keyBitmapUint8 [][256]uint8
+ keyBitmapUint16 [][256]uint16
+ sortedFieldSets []*structFieldSet
+ keyDecoder func(*structDecoder, []byte, int64) (int64, *structFieldSet, error)
+ keyStreamDecoder func(*structDecoder, *Stream) (*structFieldSet, string, error)
+}
+
+var (
+ largeToSmallTable [256]byte
+)
+
+func init() {
+ for i := 0; i < 256; i++ {
+ c := i
+ if 'A' <= c && c <= 'Z' {
+ c += 'a' - 'A'
+ }
+ largeToSmallTable[i] = byte(c)
+ }
+}
+
+func toASCIILower(s string) string {
+ b := []byte(s)
+ for i := range b {
+ b[i] = largeToSmallTable[b[i]]
+ }
+ return string(b)
+}
+
+func newStructDecoder(structName, fieldName string, fieldMap map[string]*structFieldSet) *structDecoder {
+ return &structDecoder{
+ fieldMap: fieldMap,
+ stringDecoder: newStringDecoder(structName, fieldName),
+ structName: structName,
+ fieldName: fieldName,
+ keyDecoder: decodeKey,
+ keyStreamDecoder: decodeKeyStream,
+ }
+}
+
+const (
+ allowOptimizeMaxKeyLen = 64
+ allowOptimizeMaxFieldLen = 16
+)
+
+func (d *structDecoder) tryOptimize() {
+ fieldUniqueNameMap := map[string]int{}
+ fieldIdx := -1
+ for k, v := range d.fieldMap {
+ lower := strings.ToLower(k)
+ idx, exists := fieldUniqueNameMap[lower]
+ if exists {
+ v.fieldIdx = idx
+ } else {
+ fieldIdx++
+ v.fieldIdx = fieldIdx
+ }
+ fieldUniqueNameMap[lower] = fieldIdx
+ }
+ d.fieldUniqueNameNum = len(fieldUniqueNameMap)
+
+ if d.isTriedOptimize {
+ return
+ }
+ fieldMap := map[string]*structFieldSet{}
+ conflicted := map[string]struct{}{}
+ for k, v := range d.fieldMap {
+ key := strings.ToLower(k)
+ if key != k {
+ if key != toASCIILower(k) {
+ d.isTriedOptimize = true
+ return
+ }
+ // already exists same key (e.g. Hello and HELLO has same lower case key
+ if _, exists := conflicted[key]; exists {
+ d.isTriedOptimize = true
+ return
+ }
+ conflicted[key] = struct{}{}
+ }
+ if field, exists := fieldMap[key]; exists {
+ if field != v {
+ d.isTriedOptimize = true
+ return
+ }
+ }
+ fieldMap[key] = v
+ }
+
+ if len(fieldMap) > allowOptimizeMaxFieldLen {
+ d.isTriedOptimize = true
+ return
+ }
+
+ var maxKeyLen int
+ sortedKeys := []string{}
+ for key := range fieldMap {
+ keyLen := len(key)
+ if keyLen > allowOptimizeMaxKeyLen {
+ d.isTriedOptimize = true
+ return
+ }
+ if maxKeyLen < keyLen {
+ maxKeyLen = keyLen
+ }
+ sortedKeys = append(sortedKeys, key)
+ }
+ sort.Strings(sortedKeys)
+
+ // By allocating one extra capacity than `maxKeyLen`,
+ // it is possible to avoid the process of comparing the index of the key with the length of the bitmap each time.
+ bitmapLen := maxKeyLen + 1
+ if len(sortedKeys) <= 8 {
+ keyBitmap := make([][256]uint8, bitmapLen)
+ for i, key := range sortedKeys {
+ for j := 0; j < len(key); j++ {
+ c := key[j]
+ keyBitmap[j][c] |= (1 << uint(i))
+ }
+ d.sortedFieldSets = append(d.sortedFieldSets, fieldMap[key])
+ }
+ d.keyBitmapUint8 = keyBitmap
+ d.keyDecoder = decodeKeyByBitmapUint8
+ d.keyStreamDecoder = decodeKeyByBitmapUint8Stream
+ } else {
+ keyBitmap := make([][256]uint16, bitmapLen)
+ for i, key := range sortedKeys {
+ for j := 0; j < len(key); j++ {
+ c := key[j]
+ keyBitmap[j][c] |= (1 << uint(i))
+ }
+ d.sortedFieldSets = append(d.sortedFieldSets, fieldMap[key])
+ }
+ d.keyBitmapUint16 = keyBitmap
+ d.keyDecoder = decodeKeyByBitmapUint16
+ d.keyStreamDecoder = decodeKeyByBitmapUint16Stream
+ }
+}
+
+// decode from '\uXXXX'
+func decodeKeyCharByUnicodeRune(buf []byte, cursor int64) ([]byte, int64, error) {
+ const defaultOffset = 4
+ const surrogateOffset = 6
+
+ if cursor+defaultOffset >= int64(len(buf)) {
+ return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor)
+ }
+
+ r := unicodeToRune(buf[cursor : cursor+defaultOffset])
+ if utf16.IsSurrogate(r) {
+ cursor += defaultOffset
+ if cursor+surrogateOffset >= int64(len(buf)) || buf[cursor] != '\\' || buf[cursor+1] != 'u' {
+ return []byte(string(unicode.ReplacementChar)), cursor + defaultOffset - 1, nil
+ }
+ cursor += 2
+ r2 := unicodeToRune(buf[cursor : cursor+defaultOffset])
+ if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar {
+ return []byte(string(r)), cursor + defaultOffset - 1, nil
+ }
+ }
+ return []byte(string(r)), cursor + defaultOffset - 1, nil
+}
+
+func decodeKeyCharByEscapedChar(buf []byte, cursor int64) ([]byte, int64, error) {
+ c := buf[cursor]
+ cursor++
+ switch c {
+ case '"':
+ return []byte{'"'}, cursor, nil
+ case '\\':
+ return []byte{'\\'}, cursor, nil
+ case '/':
+ return []byte{'/'}, cursor, nil
+ case 'b':
+ return []byte{'\b'}, cursor, nil
+ case 'f':
+ return []byte{'\f'}, cursor, nil
+ case 'n':
+ return []byte{'\n'}, cursor, nil
+ case 'r':
+ return []byte{'\r'}, cursor, nil
+ case 't':
+ return []byte{'\t'}, cursor, nil
+ case 'u':
+ return decodeKeyCharByUnicodeRune(buf, cursor)
+ }
+ return nil, cursor, nil
+}
+
+func decodeKeyByBitmapUint8(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) {
+ var (
+ curBit uint8 = math.MaxUint8
+ )
+ b := (*sliceHeader)(unsafe.Pointer(&buf)).data
+ for {
+ switch char(b, cursor) {
+ case ' ', '\n', '\t', '\r':
+ cursor++
+ case '"':
+ cursor++
+ c := char(b, cursor)
+ switch c {
+ case '"':
+ cursor++
+ return cursor, nil, nil
+ case nul:
+ return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
+ }
+ keyIdx := 0
+ bitmap := d.keyBitmapUint8
+ start := cursor
+ for {
+ c := char(b, cursor)
+ switch c {
+ case '"':
+ fieldSetIndex := bits.TrailingZeros8(curBit)
+ field := d.sortedFieldSets[fieldSetIndex]
+ keyLen := cursor - start
+ cursor++
+ if keyLen < field.keyLen {
+ // early match
+ return cursor, nil, nil
+ }
+ return cursor, field, nil
+ case nul:
+ return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
+ case '\\':
+ cursor++
+ chars, nextCursor, err := decodeKeyCharByEscapedChar(buf, cursor)
+ if err != nil {
+ return 0, nil, err
+ }
+ for _, c := range chars {
+ curBit &= bitmap[keyIdx][largeToSmallTable[c]]
+ if curBit == 0 {
+ return decodeKeyNotFound(b, cursor)
+ }
+ keyIdx++
+ }
+ cursor = nextCursor
+ default:
+ curBit &= bitmap[keyIdx][largeToSmallTable[c]]
+ if curBit == 0 {
+ return decodeKeyNotFound(b, cursor)
+ }
+ keyIdx++
+ }
+ cursor++
+ }
+ default:
+ return cursor, nil, errors.ErrInvalidBeginningOfValue(char(b, cursor), cursor)
+ }
+ }
+}
+
+func decodeKeyByBitmapUint16(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) {
+ var (
+ curBit uint16 = math.MaxUint16
+ )
+ b := (*sliceHeader)(unsafe.Pointer(&buf)).data
+ for {
+ switch char(b, cursor) {
+ case ' ', '\n', '\t', '\r':
+ cursor++
+ case '"':
+ cursor++
+ c := char(b, cursor)
+ switch c {
+ case '"':
+ cursor++
+ return cursor, nil, nil
+ case nul:
+ return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
+ }
+ keyIdx := 0
+ bitmap := d.keyBitmapUint16
+ start := cursor
+ for {
+ c := char(b, cursor)
+ switch c {
+ case '"':
+ fieldSetIndex := bits.TrailingZeros16(curBit)
+ field := d.sortedFieldSets[fieldSetIndex]
+ keyLen := cursor - start
+ cursor++
+ if keyLen < field.keyLen {
+ // early match
+ return cursor, nil, nil
+ }
+ return cursor, field, nil
+ case nul:
+ return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
+ case '\\':
+ cursor++
+ chars, nextCursor, err := decodeKeyCharByEscapedChar(buf, cursor)
+ if err != nil {
+ return 0, nil, err
+ }
+ for _, c := range chars {
+ curBit &= bitmap[keyIdx][largeToSmallTable[c]]
+ if curBit == 0 {
+ return decodeKeyNotFound(b, cursor)
+ }
+ keyIdx++
+ }
+ cursor = nextCursor
+ default:
+ curBit &= bitmap[keyIdx][largeToSmallTable[c]]
+ if curBit == 0 {
+ return decodeKeyNotFound(b, cursor)
+ }
+ keyIdx++
+ }
+ cursor++
+ }
+ default:
+ return cursor, nil, errors.ErrInvalidBeginningOfValue(char(b, cursor), cursor)
+ }
+ }
+}
+
+func decodeKeyNotFound(b unsafe.Pointer, cursor int64) (int64, *structFieldSet, error) {
+ for {
+ cursor++
+ switch char(b, cursor) {
+ case '"':
+ cursor++
+ return cursor, nil, nil
+ case '\\':
+ cursor++
+ if char(b, cursor) == nul {
+ return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
+ }
+ case nul:
+ return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor)
+ }
+ }
+}
+
+func decodeKey(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) {
+ key, c, err := d.stringDecoder.decodeByte(buf, cursor)
+ if err != nil {
+ return 0, nil, err
+ }
+ cursor = c
+ k := *(*string)(unsafe.Pointer(&key))
+ field, exists := d.fieldMap[k]
+ if !exists {
+ return cursor, nil, nil
+ }
+ return cursor, field, nil
+}
+
+func decodeKeyByBitmapUint8Stream(d *structDecoder, s *Stream) (*structFieldSet, string, error) {
+ var (
+ curBit uint8 = math.MaxUint8
+ )
+ _, cursor, p := s.stat()
+ for {
+ switch char(p, cursor) {
+ case ' ', '\n', '\t', '\r':
+ cursor++
+ case nul:
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.stat()
+ continue
+ }
+ return nil, "", errors.ErrInvalidBeginningOfValue(char(p, cursor), s.totalOffset())
+ case '"':
+ cursor++
+ FIRST_CHAR:
+ start := cursor
+ switch char(p, cursor) {
+ case '"':
+ cursor++
+ s.cursor = cursor
+ return nil, "", nil
+ case nul:
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.stat()
+ goto FIRST_CHAR
+ }
+ return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
+ }
+ keyIdx := 0
+ bitmap := d.keyBitmapUint8
+ for {
+ c := char(p, cursor)
+ switch c {
+ case '"':
+ fieldSetIndex := bits.TrailingZeros8(curBit)
+ field := d.sortedFieldSets[fieldSetIndex]
+ keyLen := cursor - start
+ cursor++
+ s.cursor = cursor
+ if keyLen < field.keyLen {
+ // early match
+ return nil, field.key, nil
+ }
+ return field, field.key, nil
+ case nul:
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.stat()
+ continue
+ }
+ return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
+ case '\\':
+ s.cursor = cursor + 1 // skip '\' char
+ chars, err := decodeKeyCharByEscapeCharStream(s)
+ if err != nil {
+ return nil, "", err
+ }
+ cursor = s.cursor
+ for _, c := range chars {
+ curBit &= bitmap[keyIdx][largeToSmallTable[c]]
+ if curBit == 0 {
+ s.cursor = cursor
+ return decodeKeyNotFoundStream(s, start)
+ }
+ keyIdx++
+ }
+ default:
+ curBit &= bitmap[keyIdx][largeToSmallTable[c]]
+ if curBit == 0 {
+ s.cursor = cursor
+ return decodeKeyNotFoundStream(s, start)
+ }
+ keyIdx++
+ }
+ cursor++
+ }
+ default:
+ return nil, "", errors.ErrInvalidBeginningOfValue(char(p, cursor), s.totalOffset())
+ }
+ }
+}
+
+func decodeKeyByBitmapUint16Stream(d *structDecoder, s *Stream) (*structFieldSet, string, error) {
+ var (
+ curBit uint16 = math.MaxUint16
+ )
+ _, cursor, p := s.stat()
+ for {
+ switch char(p, cursor) {
+ case ' ', '\n', '\t', '\r':
+ cursor++
+ case nul:
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.stat()
+ continue
+ }
+ return nil, "", errors.ErrInvalidBeginningOfValue(char(p, cursor), s.totalOffset())
+ case '"':
+ cursor++
+ FIRST_CHAR:
+ start := cursor
+ switch char(p, cursor) {
+ case '"':
+ cursor++
+ s.cursor = cursor
+ return nil, "", nil
+ case nul:
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.stat()
+ goto FIRST_CHAR
+ }
+ return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
+ }
+ keyIdx := 0
+ bitmap := d.keyBitmapUint16
+ for {
+ c := char(p, cursor)
+ switch c {
+ case '"':
+ fieldSetIndex := bits.TrailingZeros16(curBit)
+ field := d.sortedFieldSets[fieldSetIndex]
+ keyLen := cursor - start
+ cursor++
+ s.cursor = cursor
+ if keyLen < field.keyLen {
+ // early match
+ return nil, field.key, nil
+ }
+ return field, field.key, nil
+ case nul:
+ s.cursor = cursor
+ if s.read() {
+ _, cursor, p = s.stat()
+ continue
+ }
+ return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
+ case '\\':
+ s.cursor = cursor + 1 // skip '\' char
+ chars, err := decodeKeyCharByEscapeCharStream(s)
+ if err != nil {
+ return nil, "", err
+ }
+ cursor = s.cursor
+ for _, c := range chars {
+ curBit &= bitmap[keyIdx][largeToSmallTable[c]]
+ if curBit == 0 {
+ s.cursor = cursor
+ return decodeKeyNotFoundStream(s, start)
+ }
+ keyIdx++
+ }
+ default:
+ curBit &= bitmap[keyIdx][largeToSmallTable[c]]
+ if curBit == 0 {
+ s.cursor = cursor
+ return decodeKeyNotFoundStream(s, start)
+ }
+ keyIdx++
+ }
+ cursor++
+ }
+ default:
+ return nil, "", errors.ErrInvalidBeginningOfValue(char(p, cursor), s.totalOffset())
+ }
+ }
+}
+
+// decode from '\uXXXX'
+func decodeKeyCharByUnicodeRuneStream(s *Stream) ([]byte, error) {
+ const defaultOffset = 4
+ const surrogateOffset = 6
+
+ if s.cursor+defaultOffset >= s.length {
+ if !s.read() {
+ return nil, errors.ErrInvalidCharacter(s.char(), "escaped unicode char", s.totalOffset())
+ }
+ }
+
+ r := unicodeToRune(s.buf[s.cursor : s.cursor+defaultOffset])
+ if utf16.IsSurrogate(r) {
+ s.cursor += defaultOffset
+ if s.cursor+surrogateOffset >= s.length {
+ s.read()
+ }
+ if s.cursor+surrogateOffset >= s.length || s.buf[s.cursor] != '\\' || s.buf[s.cursor+1] != 'u' {
+ s.cursor += defaultOffset - 1
+ return []byte(string(unicode.ReplacementChar)), nil
+ }
+ r2 := unicodeToRune(s.buf[s.cursor+defaultOffset+2 : s.cursor+surrogateOffset])
+ if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar {
+ s.cursor += defaultOffset - 1
+ return []byte(string(r)), nil
+ }
+ }
+ s.cursor += defaultOffset - 1
+ return []byte(string(r)), nil
+}
+
+func decodeKeyCharByEscapeCharStream(s *Stream) ([]byte, error) {
+ c := s.buf[s.cursor]
+ s.cursor++
+RETRY:
+ switch c {
+ case '"':
+ return []byte{'"'}, nil
+ case '\\':
+ return []byte{'\\'}, nil
+ case '/':
+ return []byte{'/'}, nil
+ case 'b':
+ return []byte{'\b'}, nil
+ case 'f':
+ return []byte{'\f'}, nil
+ case 'n':
+ return []byte{'\n'}, nil
+ case 'r':
+ return []byte{'\r'}, nil
+ case 't':
+ return []byte{'\t'}, nil
+ case 'u':
+ return decodeKeyCharByUnicodeRuneStream(s)
+ case nul:
+ if !s.read() {
+ return nil, errors.ErrInvalidCharacter(s.char(), "escaped char", s.totalOffset())
+ }
+ goto RETRY
+ default:
+ return nil, errors.ErrUnexpectedEndOfJSON("struct field", s.totalOffset())
+ }
+}
+
+func decodeKeyNotFoundStream(s *Stream, start int64) (*structFieldSet, string, error) {
+ buf, cursor, p := s.stat()
+ for {
+ cursor++
+ switch char(p, cursor) {
+ case '"':
+ b := buf[start:cursor]
+ key := *(*string)(unsafe.Pointer(&b))
+ cursor++
+ s.cursor = cursor
+ return nil, key, nil
+ case '\\':
+ cursor++
+ if char(p, cursor) == nul {
+ s.cursor = cursor
+ if !s.read() {
+ return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
+ }
+ buf, cursor, p = s.statForRetry()
+ }
+ case nul:
+ s.cursor = cursor
+ if !s.read() {
+ return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
+ }
+ buf, cursor, p = s.statForRetry()
+ }
+ }
+}
+
+func decodeKeyStream(d *structDecoder, s *Stream) (*structFieldSet, string, error) {
+ key, err := d.stringDecoder.decodeStreamByte(s)
+ if err != nil {
+ return nil, "", err
+ }
+ k := *(*string)(unsafe.Pointer(&key))
+ return d.fieldMap[k], k, nil
+}
+
+func (d *structDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return errors.ErrExceededMaxDepth(s.char(), s.cursor)
+ }
+
+ c := s.skipWhiteSpace()
+ switch c {
+ case 'n':
+ if err := nullBytes(s); err != nil {
+ return err
+ }
+ return nil
+ default:
+ if s.char() != '{' {
+ return errors.ErrInvalidBeginningOfValue(s.char(), s.totalOffset())
+ }
+ }
+ s.cursor++
+ if s.skipWhiteSpace() == '}' {
+ s.cursor++
+ return nil
+ }
+ var (
+ seenFields map[int]struct{}
+ seenFieldNum int
+ )
+ firstWin := (s.Option.Flags & FirstWinOption) != 0
+ if firstWin {
+ seenFields = make(map[int]struct{}, d.fieldUniqueNameNum)
+ }
+ for {
+ s.reset()
+ field, key, err := d.keyStreamDecoder(d, s)
+ if err != nil {
+ return err
+ }
+ if s.skipWhiteSpace() != ':' {
+ return errors.ErrExpected("colon after object key", s.totalOffset())
+ }
+ s.cursor++
+ if field != nil {
+ if field.err != nil {
+ return field.err
+ }
+ if firstWin {
+ if _, exists := seenFields[field.fieldIdx]; exists {
+ if err := s.skipValue(depth); err != nil {
+ return err
+ }
+ } else {
+ if err := field.dec.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+field.offset)); err != nil {
+ return err
+ }
+ seenFieldNum++
+ if d.fieldUniqueNameNum <= seenFieldNum {
+ return s.skipObject(depth)
+ }
+ seenFields[field.fieldIdx] = struct{}{}
+ }
+ } else {
+ if err := field.dec.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+field.offset)); err != nil {
+ return err
+ }
+ }
+ } else if s.DisallowUnknownFields {
+ return fmt.Errorf("json: unknown field %q", key)
+ } else {
+ if err := s.skipValue(depth); err != nil {
+ return err
+ }
+ }
+ c := s.skipWhiteSpace()
+ if c == '}' {
+ s.cursor++
+ return nil
+ }
+ if c != ',' {
+ return errors.ErrExpected("comma after object element", s.totalOffset())
+ }
+ s.cursor++
+ }
+}
+
+func (d *structDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ buf := ctx.Buf
+ depth++
+ if depth > maxDecodeNestingDepth {
+ return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
+ }
+ buflen := int64(len(buf))
+ cursor = skipWhiteSpace(buf, cursor)
+ b := (*sliceHeader)(unsafe.Pointer(&buf)).data
+ switch char(b, cursor) {
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return 0, err
+ }
+ cursor += 4
+ return cursor, nil
+ case '{':
+ default:
+ return 0, errors.ErrInvalidBeginningOfValue(char(b, cursor), cursor)
+ }
+ cursor++
+ cursor = skipWhiteSpace(buf, cursor)
+ if buf[cursor] == '}' {
+ cursor++
+ return cursor, nil
+ }
+ var (
+ seenFields map[int]struct{}
+ seenFieldNum int
+ )
+ firstWin := (ctx.Option.Flags & FirstWinOption) != 0
+ if firstWin {
+ seenFields = make(map[int]struct{}, d.fieldUniqueNameNum)
+ }
+ for {
+ c, field, err := d.keyDecoder(d, buf, cursor)
+ if err != nil {
+ return 0, err
+ }
+ cursor = skipWhiteSpace(buf, c)
+ if char(b, cursor) != ':' {
+ return 0, errors.ErrExpected("colon after object key", cursor)
+ }
+ cursor++
+ if cursor >= buflen {
+ return 0, errors.ErrExpected("object value after colon", cursor)
+ }
+ if field != nil {
+ if field.err != nil {
+ return 0, field.err
+ }
+ if firstWin {
+ if _, exists := seenFields[field.fieldIdx]; exists {
+ c, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return 0, err
+ }
+ cursor = c
+ } else {
+ c, err := field.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+field.offset))
+ if err != nil {
+ return 0, err
+ }
+ cursor = c
+ seenFieldNum++
+ if d.fieldUniqueNameNum <= seenFieldNum {
+ return skipObject(buf, cursor, depth)
+ }
+ seenFields[field.fieldIdx] = struct{}{}
+ }
+ } else {
+ c, err := field.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+field.offset))
+ if err != nil {
+ return 0, err
+ }
+ cursor = c
+ }
+ } else {
+ c, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return 0, err
+ }
+ cursor = c
+ }
+ cursor = skipWhiteSpace(buf, cursor)
+ if char(b, cursor) == '}' {
+ cursor++
+ return cursor, nil
+ }
+ if char(b, cursor) != ',' {
+ return 0, errors.ErrExpected("comma after object element", cursor)
+ }
+ cursor++
+ }
+}
+
+func (d *structDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ return nil, 0, fmt.Errorf("json: struct decoder does not support decode path")
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/type.go b/vendor/github.com/goccy/go-json/internal/decoder/type.go
new file mode 100644
index 00000000..beaf3ab8
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/type.go
@@ -0,0 +1,30 @@
+package decoder
+
+import (
+ "context"
+ "encoding"
+ "encoding/json"
+ "reflect"
+ "unsafe"
+)
+
+type Decoder interface {
+ Decode(*RuntimeContext, int64, int64, unsafe.Pointer) (int64, error)
+ DecodePath(*RuntimeContext, int64, int64) ([][]byte, int64, error)
+ DecodeStream(*Stream, int64, unsafe.Pointer) error
+}
+
+const (
+ nul = '\000'
+ maxDecodeNestingDepth = 10000
+)
+
+type unmarshalerContext interface {
+ UnmarshalJSON(context.Context, []byte) error
+}
+
+var (
+ unmarshalJSONType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
+ unmarshalJSONContextType = reflect.TypeOf((*unmarshalerContext)(nil)).Elem()
+ unmarshalTextType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
+)
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/uint.go b/vendor/github.com/goccy/go-json/internal/decoder/uint.go
new file mode 100644
index 00000000..4131731b
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/uint.go
@@ -0,0 +1,194 @@
+package decoder
+
+import (
+ "fmt"
+ "reflect"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type uintDecoder struct {
+ typ *runtime.Type
+ kind reflect.Kind
+ op func(unsafe.Pointer, uint64)
+ structName string
+ fieldName string
+}
+
+func newUintDecoder(typ *runtime.Type, structName, fieldName string, op func(unsafe.Pointer, uint64)) *uintDecoder {
+ return &uintDecoder{
+ typ: typ,
+ kind: typ.Kind(),
+ op: op,
+ structName: structName,
+ fieldName: fieldName,
+ }
+}
+
+func (d *uintDecoder) typeError(buf []byte, offset int64) *errors.UnmarshalTypeError {
+ return &errors.UnmarshalTypeError{
+ Value: fmt.Sprintf("number %s", string(buf)),
+ Type: runtime.RType2Type(d.typ),
+ Offset: offset,
+ }
+}
+
+var (
+ pow10u64 = [...]uint64{
+ 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ }
+ pow10u64Len = len(pow10u64)
+)
+
+func (d *uintDecoder) parseUint(b []byte) (uint64, error) {
+ maxDigit := len(b)
+ if maxDigit > pow10u64Len {
+ return 0, fmt.Errorf("invalid length of number")
+ }
+ sum := uint64(0)
+ for i := 0; i < maxDigit; i++ {
+ c := uint64(b[i]) - 48
+ digitValue := pow10u64[maxDigit-i-1]
+ sum += c * digitValue
+ }
+ return sum, nil
+}
+
+func (d *uintDecoder) decodeStreamByte(s *Stream) ([]byte, error) {
+ for {
+ switch s.char() {
+ case ' ', '\n', '\t', '\r':
+ s.cursor++
+ continue
+ case '0':
+ s.cursor++
+ return numZeroBuf, nil
+ case '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ start := s.cursor
+ for {
+ s.cursor++
+ if numTable[s.char()] {
+ continue
+ } else if s.char() == nul {
+ if s.read() {
+ s.cursor-- // for retry current character
+ continue
+ }
+ }
+ break
+ }
+ num := s.buf[start:s.cursor]
+ return num, nil
+ case 'n':
+ if err := nullBytes(s); err != nil {
+ return nil, err
+ }
+ return nil, nil
+ case nul:
+ if s.read() {
+ continue
+ }
+ default:
+ return nil, d.typeError([]byte{s.char()}, s.totalOffset())
+ }
+ break
+ }
+ return nil, errors.ErrUnexpectedEndOfJSON("number(unsigned integer)", s.totalOffset())
+}
+
+func (d *uintDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
+ for {
+ switch buf[cursor] {
+ case ' ', '\n', '\t', '\r':
+ cursor++
+ continue
+ case '0':
+ cursor++
+ return numZeroBuf, cursor, nil
+ case '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ start := cursor
+ cursor++
+ for numTable[buf[cursor]] {
+ cursor++
+ }
+ num := buf[start:cursor]
+ return num, cursor, nil
+ case 'n':
+ if err := validateNull(buf, cursor); err != nil {
+ return nil, 0, err
+ }
+ cursor += 4
+ return nil, cursor, nil
+ default:
+ return nil, 0, d.typeError([]byte{buf[cursor]}, cursor)
+ }
+ }
+}
+
+func (d *uintDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ bytes, err := d.decodeStreamByte(s)
+ if err != nil {
+ return err
+ }
+ if bytes == nil {
+ return nil
+ }
+ u64, err := d.parseUint(bytes)
+ if err != nil {
+ return d.typeError(bytes, s.totalOffset())
+ }
+ switch d.kind {
+ case reflect.Uint8:
+ if (1 << 8) <= u64 {
+ return d.typeError(bytes, s.totalOffset())
+ }
+ case reflect.Uint16:
+ if (1 << 16) <= u64 {
+ return d.typeError(bytes, s.totalOffset())
+ }
+ case reflect.Uint32:
+ if (1 << 32) <= u64 {
+ return d.typeError(bytes, s.totalOffset())
+ }
+ }
+ d.op(p, u64)
+ return nil
+}
+
+func (d *uintDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ bytes, c, err := d.decodeByte(ctx.Buf, cursor)
+ if err != nil {
+ return 0, err
+ }
+ if bytes == nil {
+ return c, nil
+ }
+ cursor = c
+ u64, err := d.parseUint(bytes)
+ if err != nil {
+ return 0, d.typeError(bytes, cursor)
+ }
+ switch d.kind {
+ case reflect.Uint8:
+ if (1 << 8) <= u64 {
+ return 0, d.typeError(bytes, cursor)
+ }
+ case reflect.Uint16:
+ if (1 << 16) <= u64 {
+ return 0, d.typeError(bytes, cursor)
+ }
+ case reflect.Uint32:
+ if (1 << 32) <= u64 {
+ return 0, d.typeError(bytes, cursor)
+ }
+ }
+ d.op(p, u64)
+ return cursor, nil
+}
+
+func (d *uintDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ return nil, 0, fmt.Errorf("json: uint decoder does not support decode path")
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go b/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go
new file mode 100644
index 00000000..4cd6dbd5
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go
@@ -0,0 +1,104 @@
+package decoder
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type unmarshalJSONDecoder struct {
+ typ *runtime.Type
+ structName string
+ fieldName string
+}
+
+func newUnmarshalJSONDecoder(typ *runtime.Type, structName, fieldName string) *unmarshalJSONDecoder {
+ return &unmarshalJSONDecoder{
+ typ: typ,
+ structName: structName,
+ fieldName: fieldName,
+ }
+}
+
+func (d *unmarshalJSONDecoder) annotateError(cursor int64, err error) {
+ switch e := err.(type) {
+ case *errors.UnmarshalTypeError:
+ e.Struct = d.structName
+ e.Field = d.fieldName
+ case *errors.SyntaxError:
+ e.Offset = cursor
+ }
+}
+
+func (d *unmarshalJSONDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ s.skipWhiteSpace()
+ start := s.cursor
+ if err := s.skipValue(depth); err != nil {
+ return err
+ }
+ src := s.buf[start:s.cursor]
+ dst := make([]byte, len(src))
+ copy(dst, src)
+
+ v := *(*interface{})(unsafe.Pointer(&emptyInterface{
+ typ: d.typ,
+ ptr: p,
+ }))
+ switch v := v.(type) {
+ case unmarshalerContext:
+ var ctx context.Context
+ if (s.Option.Flags & ContextOption) != 0 {
+ ctx = s.Option.Context
+ } else {
+ ctx = context.Background()
+ }
+ if err := v.UnmarshalJSON(ctx, dst); err != nil {
+ d.annotateError(s.cursor, err)
+ return err
+ }
+ case json.Unmarshaler:
+ if err := v.UnmarshalJSON(dst); err != nil {
+ d.annotateError(s.cursor, err)
+ return err
+ }
+ }
+ return nil
+}
+
+func (d *unmarshalJSONDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ buf := ctx.Buf
+ cursor = skipWhiteSpace(buf, cursor)
+ start := cursor
+ end, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return 0, err
+ }
+ src := buf[start:end]
+ dst := make([]byte, len(src))
+ copy(dst, src)
+
+ v := *(*interface{})(unsafe.Pointer(&emptyInterface{
+ typ: d.typ,
+ ptr: p,
+ }))
+ if (ctx.Option.Flags & ContextOption) != 0 {
+ if err := v.(unmarshalerContext).UnmarshalJSON(ctx.Option.Context, dst); err != nil {
+ d.annotateError(cursor, err)
+ return 0, err
+ }
+ } else {
+ if err := v.(json.Unmarshaler).UnmarshalJSON(dst); err != nil {
+ d.annotateError(cursor, err)
+ return 0, err
+ }
+ }
+ return end, nil
+}
+
+func (d *unmarshalJSONDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ return nil, 0, fmt.Errorf("json: unmarshal json decoder does not support decode path")
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go b/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go
new file mode 100644
index 00000000..d711d0f8
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go
@@ -0,0 +1,285 @@
+package decoder
+
+import (
+ "bytes"
+ "encoding"
+ "fmt"
+ "unicode"
+ "unicode/utf16"
+ "unicode/utf8"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type unmarshalTextDecoder struct {
+ typ *runtime.Type
+ structName string
+ fieldName string
+}
+
+func newUnmarshalTextDecoder(typ *runtime.Type, structName, fieldName string) *unmarshalTextDecoder {
+ return &unmarshalTextDecoder{
+ typ: typ,
+ structName: structName,
+ fieldName: fieldName,
+ }
+}
+
+func (d *unmarshalTextDecoder) annotateError(cursor int64, err error) {
+ switch e := err.(type) {
+ case *errors.UnmarshalTypeError:
+ e.Struct = d.structName
+ e.Field = d.fieldName
+ case *errors.SyntaxError:
+ e.Offset = cursor
+ }
+}
+
+var (
+ nullbytes = []byte(`null`)
+)
+
+func (d *unmarshalTextDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ s.skipWhiteSpace()
+ start := s.cursor
+ if err := s.skipValue(depth); err != nil {
+ return err
+ }
+ src := s.buf[start:s.cursor]
+ if len(src) > 0 {
+ switch src[0] {
+ case '[':
+ return &errors.UnmarshalTypeError{
+ Value: "array",
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ }
+ case '{':
+ return &errors.UnmarshalTypeError{
+ Value: "object",
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ }
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return &errors.UnmarshalTypeError{
+ Value: "number",
+ Type: runtime.RType2Type(d.typ),
+ Offset: s.totalOffset(),
+ }
+ case 'n':
+ if bytes.Equal(src, nullbytes) {
+ *(*unsafe.Pointer)(p) = nil
+ return nil
+ }
+ }
+ }
+ dst := make([]byte, len(src))
+ copy(dst, src)
+
+ if b, ok := unquoteBytes(dst); ok {
+ dst = b
+ }
+ v := *(*interface{})(unsafe.Pointer(&emptyInterface{
+ typ: d.typ,
+ ptr: p,
+ }))
+ if err := v.(encoding.TextUnmarshaler).UnmarshalText(dst); err != nil {
+ d.annotateError(s.cursor, err)
+ return err
+ }
+ return nil
+}
+
+func (d *unmarshalTextDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ buf := ctx.Buf
+ cursor = skipWhiteSpace(buf, cursor)
+ start := cursor
+ end, err := skipValue(buf, cursor, depth)
+ if err != nil {
+ return 0, err
+ }
+ src := buf[start:end]
+ if len(src) > 0 {
+ switch src[0] {
+ case '[':
+ return 0, &errors.UnmarshalTypeError{
+ Value: "array",
+ Type: runtime.RType2Type(d.typ),
+ Offset: start,
+ }
+ case '{':
+ return 0, &errors.UnmarshalTypeError{
+ Value: "object",
+ Type: runtime.RType2Type(d.typ),
+ Offset: start,
+ }
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return 0, &errors.UnmarshalTypeError{
+ Value: "number",
+ Type: runtime.RType2Type(d.typ),
+ Offset: start,
+ }
+ case 'n':
+ if bytes.Equal(src, nullbytes) {
+ *(*unsafe.Pointer)(p) = nil
+ return end, nil
+ }
+ }
+ }
+
+ if s, ok := unquoteBytes(src); ok {
+ src = s
+ }
+ v := *(*interface{})(unsafe.Pointer(&emptyInterface{
+ typ: d.typ,
+ ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
+ }))
+ if err := v.(encoding.TextUnmarshaler).UnmarshalText(src); err != nil {
+ d.annotateError(cursor, err)
+ return 0, err
+ }
+ return end, nil
+}
+
+func (d *unmarshalTextDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ return nil, 0, fmt.Errorf("json: unmarshal text decoder does not support decode path")
+}
+
+func unquoteBytes(s []byte) (t []byte, ok bool) { //nolint: nonamedreturns
+ length := len(s)
+ if length < 2 || s[0] != '"' || s[length-1] != '"' {
+ return
+ }
+ s = s[1 : length-1]
+ length -= 2
+
+ // Check for unusual characters. If there are none,
+ // then no unquoting is needed, so return a slice of the
+ // original bytes.
+ r := 0
+ for r < length {
+ c := s[r]
+ if c == '\\' || c == '"' || c < ' ' {
+ break
+ }
+ if c < utf8.RuneSelf {
+ r++
+ continue
+ }
+ rr, size := utf8.DecodeRune(s[r:])
+ if rr == utf8.RuneError && size == 1 {
+ break
+ }
+ r += size
+ }
+ if r == length {
+ return s, true
+ }
+
+ b := make([]byte, length+2*utf8.UTFMax)
+ w := copy(b, s[0:r])
+ for r < length {
+ // Out of room? Can only happen if s is full of
+ // malformed UTF-8 and we're replacing each
+ // byte with RuneError.
+ if w >= len(b)-2*utf8.UTFMax {
+ nb := make([]byte, (len(b)+utf8.UTFMax)*2)
+ copy(nb, b[0:w])
+ b = nb
+ }
+ switch c := s[r]; {
+ case c == '\\':
+ r++
+ if r >= length {
+ return
+ }
+ switch s[r] {
+ default:
+ return
+ case '"', '\\', '/', '\'':
+ b[w] = s[r]
+ r++
+ w++
+ case 'b':
+ b[w] = '\b'
+ r++
+ w++
+ case 'f':
+ b[w] = '\f'
+ r++
+ w++
+ case 'n':
+ b[w] = '\n'
+ r++
+ w++
+ case 'r':
+ b[w] = '\r'
+ r++
+ w++
+ case 't':
+ b[w] = '\t'
+ r++
+ w++
+ case 'u':
+ r--
+ rr := getu4(s[r:])
+ if rr < 0 {
+ return
+ }
+ r += 6
+ if utf16.IsSurrogate(rr) {
+ rr1 := getu4(s[r:])
+ if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar {
+ // A valid pair; consume.
+ r += 6
+ w += utf8.EncodeRune(b[w:], dec)
+ break
+ }
+ // Invalid surrogate; fall back to replacement rune.
+ rr = unicode.ReplacementChar
+ }
+ w += utf8.EncodeRune(b[w:], rr)
+ }
+
+ // Quote, control characters are invalid.
+ case c == '"', c < ' ':
+ return
+
+ // ASCII
+ case c < utf8.RuneSelf:
+ b[w] = c
+ r++
+ w++
+
+ // Coerce to well-formed UTF-8.
+ default:
+ rr, size := utf8.DecodeRune(s[r:])
+ r += size
+ w += utf8.EncodeRune(b[w:], rr)
+ }
+ }
+ return b[0:w], true
+}
+
+func getu4(s []byte) rune {
+ if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {
+ return -1
+ }
+ var r rune
+ for _, c := range s[2:6] {
+ switch {
+ case '0' <= c && c <= '9':
+ c = c - '0'
+ case 'a' <= c && c <= 'f':
+ c = c - 'a' + 10
+ case 'A' <= c && c <= 'F':
+ c = c - 'A' + 10
+ default:
+ return -1
+ }
+ r = r*16 + rune(c)
+ }
+ return r
+}
diff --git a/vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go b/vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go
new file mode 100644
index 00000000..0c4e2e6e
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go
@@ -0,0 +1,73 @@
+package decoder
+
+import (
+ "fmt"
+ "reflect"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type wrappedStringDecoder struct {
+ typ *runtime.Type
+ dec Decoder
+ stringDecoder *stringDecoder
+ structName string
+ fieldName string
+ isPtrType bool
+}
+
+func newWrappedStringDecoder(typ *runtime.Type, dec Decoder, structName, fieldName string) *wrappedStringDecoder {
+ return &wrappedStringDecoder{
+ typ: typ,
+ dec: dec,
+ stringDecoder: newStringDecoder(structName, fieldName),
+ structName: structName,
+ fieldName: fieldName,
+ isPtrType: typ.Kind() == reflect.Ptr,
+ }
+}
+
+func (d *wrappedStringDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
+ bytes, err := d.stringDecoder.decodeStreamByte(s)
+ if err != nil {
+ return err
+ }
+ if bytes == nil {
+ if d.isPtrType {
+ *(*unsafe.Pointer)(p) = nil
+ }
+ return nil
+ }
+ b := make([]byte, len(bytes)+1)
+ copy(b, bytes)
+ if _, err := d.dec.Decode(&RuntimeContext{Buf: b}, 0, depth, p); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (d *wrappedStringDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
+ bytes, c, err := d.stringDecoder.decodeByte(ctx.Buf, cursor)
+ if err != nil {
+ return 0, err
+ }
+ if bytes == nil {
+ if d.isPtrType {
+ *(*unsafe.Pointer)(p) = nil
+ }
+ return c, nil
+ }
+ bytes = append(bytes, nul)
+ oldBuf := ctx.Buf
+ ctx.Buf = bytes
+ if _, err := d.dec.Decode(ctx, 0, depth, p); err != nil {
+ return 0, err
+ }
+ ctx.Buf = oldBuf
+ return c, nil
+}
+
+func (d *wrappedStringDecoder) DecodePath(ctx *RuntimeContext, cursor, depth int64) ([][]byte, int64, error) {
+ return nil, 0, fmt.Errorf("json: wrapped string decoder does not support decode path")
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/code.go b/vendor/github.com/goccy/go-json/internal/encoder/code.go
new file mode 100644
index 00000000..5b08faef
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/code.go
@@ -0,0 +1,1023 @@
+package encoder
+
+import (
+ "fmt"
+ "reflect"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type Code interface {
+ Kind() CodeKind
+ ToOpcode(*compileContext) Opcodes
+ Filter(*FieldQuery) Code
+}
+
+type AnonymousCode interface {
+ ToAnonymousOpcode(*compileContext) Opcodes
+}
+
+type Opcodes []*Opcode
+
+func (o Opcodes) First() *Opcode {
+ if len(o) == 0 {
+ return nil
+ }
+ return o[0]
+}
+
+func (o Opcodes) Last() *Opcode {
+ if len(o) == 0 {
+ return nil
+ }
+ return o[len(o)-1]
+}
+
+func (o Opcodes) Add(codes ...*Opcode) Opcodes {
+ return append(o, codes...)
+}
+
+type CodeKind int
+
+const (
+ CodeKindInterface CodeKind = iota
+ CodeKindPtr
+ CodeKindInt
+ CodeKindUint
+ CodeKindFloat
+ CodeKindString
+ CodeKindBool
+ CodeKindStruct
+ CodeKindMap
+ CodeKindSlice
+ CodeKindArray
+ CodeKindBytes
+ CodeKindMarshalJSON
+ CodeKindMarshalText
+ CodeKindRecursive
+)
+
+type IntCode struct {
+ typ *runtime.Type
+ bitSize uint8
+ isString bool
+ isPtr bool
+}
+
+func (c *IntCode) Kind() CodeKind {
+ return CodeKindInt
+}
+
+func (c *IntCode) ToOpcode(ctx *compileContext) Opcodes {
+ var code *Opcode
+ switch {
+ case c.isPtr:
+ code = newOpCode(ctx, c.typ, OpIntPtr)
+ case c.isString:
+ code = newOpCode(ctx, c.typ, OpIntString)
+ default:
+ code = newOpCode(ctx, c.typ, OpInt)
+ }
+ code.NumBitSize = c.bitSize
+ ctx.incIndex()
+ return Opcodes{code}
+}
+
+func (c *IntCode) Filter(_ *FieldQuery) Code {
+ return c
+}
+
+type UintCode struct {
+ typ *runtime.Type
+ bitSize uint8
+ isString bool
+ isPtr bool
+}
+
+func (c *UintCode) Kind() CodeKind {
+ return CodeKindUint
+}
+
+func (c *UintCode) ToOpcode(ctx *compileContext) Opcodes {
+ var code *Opcode
+ switch {
+ case c.isPtr:
+ code = newOpCode(ctx, c.typ, OpUintPtr)
+ case c.isString:
+ code = newOpCode(ctx, c.typ, OpUintString)
+ default:
+ code = newOpCode(ctx, c.typ, OpUint)
+ }
+ code.NumBitSize = c.bitSize
+ ctx.incIndex()
+ return Opcodes{code}
+}
+
+func (c *UintCode) Filter(_ *FieldQuery) Code {
+ return c
+}
+
+type FloatCode struct {
+ typ *runtime.Type
+ bitSize uint8
+ isPtr bool
+}
+
+func (c *FloatCode) Kind() CodeKind {
+ return CodeKindFloat
+}
+
+func (c *FloatCode) ToOpcode(ctx *compileContext) Opcodes {
+ var code *Opcode
+ switch {
+ case c.isPtr:
+ switch c.bitSize {
+ case 32:
+ code = newOpCode(ctx, c.typ, OpFloat32Ptr)
+ default:
+ code = newOpCode(ctx, c.typ, OpFloat64Ptr)
+ }
+ default:
+ switch c.bitSize {
+ case 32:
+ code = newOpCode(ctx, c.typ, OpFloat32)
+ default:
+ code = newOpCode(ctx, c.typ, OpFloat64)
+ }
+ }
+ ctx.incIndex()
+ return Opcodes{code}
+}
+
+func (c *FloatCode) Filter(_ *FieldQuery) Code {
+ return c
+}
+
+type StringCode struct {
+ typ *runtime.Type
+ isPtr bool
+}
+
+func (c *StringCode) Kind() CodeKind {
+ return CodeKindString
+}
+
+func (c *StringCode) ToOpcode(ctx *compileContext) Opcodes {
+ isJSONNumberType := c.typ == runtime.Type2RType(jsonNumberType)
+ var code *Opcode
+ if c.isPtr {
+ if isJSONNumberType {
+ code = newOpCode(ctx, c.typ, OpNumberPtr)
+ } else {
+ code = newOpCode(ctx, c.typ, OpStringPtr)
+ }
+ } else {
+ if isJSONNumberType {
+ code = newOpCode(ctx, c.typ, OpNumber)
+ } else {
+ code = newOpCode(ctx, c.typ, OpString)
+ }
+ }
+ ctx.incIndex()
+ return Opcodes{code}
+}
+
+func (c *StringCode) Filter(_ *FieldQuery) Code {
+ return c
+}
+
+type BoolCode struct {
+ typ *runtime.Type
+ isPtr bool
+}
+
+func (c *BoolCode) Kind() CodeKind {
+ return CodeKindBool
+}
+
+func (c *BoolCode) ToOpcode(ctx *compileContext) Opcodes {
+ var code *Opcode
+ switch {
+ case c.isPtr:
+ code = newOpCode(ctx, c.typ, OpBoolPtr)
+ default:
+ code = newOpCode(ctx, c.typ, OpBool)
+ }
+ ctx.incIndex()
+ return Opcodes{code}
+}
+
+func (c *BoolCode) Filter(_ *FieldQuery) Code {
+ return c
+}
+
+type BytesCode struct {
+ typ *runtime.Type
+ isPtr bool
+}
+
+func (c *BytesCode) Kind() CodeKind {
+ return CodeKindBytes
+}
+
+func (c *BytesCode) ToOpcode(ctx *compileContext) Opcodes {
+ var code *Opcode
+ switch {
+ case c.isPtr:
+ code = newOpCode(ctx, c.typ, OpBytesPtr)
+ default:
+ code = newOpCode(ctx, c.typ, OpBytes)
+ }
+ ctx.incIndex()
+ return Opcodes{code}
+}
+
+func (c *BytesCode) Filter(_ *FieldQuery) Code {
+ return c
+}
+
+type SliceCode struct {
+ typ *runtime.Type
+ value Code
+}
+
+func (c *SliceCode) Kind() CodeKind {
+ return CodeKindSlice
+}
+
+func (c *SliceCode) ToOpcode(ctx *compileContext) Opcodes {
+ // header => opcode => elem => end
+ // ^ |
+ // |________|
+ size := c.typ.Elem().Size()
+ header := newSliceHeaderCode(ctx, c.typ)
+ ctx.incIndex()
+
+ ctx.incIndent()
+ codes := c.value.ToOpcode(ctx)
+ ctx.decIndent()
+
+ codes.First().Flags |= IndirectFlags
+ elemCode := newSliceElemCode(ctx, c.typ.Elem(), header, size)
+ ctx.incIndex()
+ end := newOpCode(ctx, c.typ, OpSliceEnd)
+ ctx.incIndex()
+ header.End = end
+ header.Next = codes.First()
+ codes.Last().Next = elemCode
+ elemCode.Next = codes.First()
+ elemCode.End = end
+ return Opcodes{header}.Add(codes...).Add(elemCode).Add(end)
+}
+
+func (c *SliceCode) Filter(_ *FieldQuery) Code {
+ return c
+}
+
+type ArrayCode struct {
+ typ *runtime.Type
+ value Code
+}
+
+func (c *ArrayCode) Kind() CodeKind {
+ return CodeKindArray
+}
+
+func (c *ArrayCode) ToOpcode(ctx *compileContext) Opcodes {
+ // header => opcode => elem => end
+ // ^ |
+ // |________|
+ elem := c.typ.Elem()
+ alen := c.typ.Len()
+ size := elem.Size()
+
+ header := newArrayHeaderCode(ctx, c.typ, alen)
+ ctx.incIndex()
+
+ ctx.incIndent()
+ codes := c.value.ToOpcode(ctx)
+ ctx.decIndent()
+
+ codes.First().Flags |= IndirectFlags
+
+ elemCode := newArrayElemCode(ctx, elem, header, alen, size)
+ ctx.incIndex()
+
+ end := newOpCode(ctx, c.typ, OpArrayEnd)
+ ctx.incIndex()
+
+ header.End = end
+ header.Next = codes.First()
+ codes.Last().Next = elemCode
+ elemCode.Next = codes.First()
+ elemCode.End = end
+
+ return Opcodes{header}.Add(codes...).Add(elemCode).Add(end)
+}
+
+func (c *ArrayCode) Filter(_ *FieldQuery) Code {
+ return c
+}
+
+type MapCode struct {
+ typ *runtime.Type
+ key Code
+ value Code
+}
+
+func (c *MapCode) Kind() CodeKind {
+ return CodeKindMap
+}
+
+func (c *MapCode) ToOpcode(ctx *compileContext) Opcodes {
+ // header => code => value => code => key => code => value => code => end
+ // ^ |
+ // |_______________________|
+ header := newMapHeaderCode(ctx, c.typ)
+ ctx.incIndex()
+
+ keyCodes := c.key.ToOpcode(ctx)
+
+ value := newMapValueCode(ctx, c.typ.Elem(), header)
+ ctx.incIndex()
+
+ ctx.incIndent()
+ valueCodes := c.value.ToOpcode(ctx)
+ ctx.decIndent()
+
+ valueCodes.First().Flags |= IndirectFlags
+
+ key := newMapKeyCode(ctx, c.typ.Key(), header)
+ ctx.incIndex()
+
+ end := newMapEndCode(ctx, c.typ, header)
+ ctx.incIndex()
+
+ header.Next = keyCodes.First()
+ keyCodes.Last().Next = value
+ value.Next = valueCodes.First()
+ valueCodes.Last().Next = key
+ key.Next = keyCodes.First()
+
+ header.End = end
+ key.End = end
+ value.End = end
+ return Opcodes{header}.Add(keyCodes...).Add(value).Add(valueCodes...).Add(key).Add(end)
+}
+
+func (c *MapCode) Filter(_ *FieldQuery) Code {
+ return c
+}
+
+type StructCode struct {
+ typ *runtime.Type
+ fields []*StructFieldCode
+ isPtr bool
+ disableIndirectConversion bool
+ isIndirect bool
+ isRecursive bool
+}
+
+func (c *StructCode) Kind() CodeKind {
+ return CodeKindStruct
+}
+
+func (c *StructCode) lastFieldCode(field *StructFieldCode, firstField *Opcode) *Opcode {
+ if isEmbeddedStruct(field) {
+ return c.lastAnonymousFieldCode(firstField)
+ }
+ lastField := firstField
+ for lastField.NextField != nil {
+ lastField = lastField.NextField
+ }
+ return lastField
+}
+
+func (c *StructCode) lastAnonymousFieldCode(firstField *Opcode) *Opcode {
+ // firstField is special StructHead operation for anonymous structure.
+ // So, StructHead's next operation is truly struct head operation.
+ for firstField.Op == OpStructHead || firstField.Op == OpStructField {
+ firstField = firstField.Next
+ }
+ lastField := firstField
+ for lastField.NextField != nil {
+ lastField = lastField.NextField
+ }
+ return lastField
+}
+
+func (c *StructCode) ToOpcode(ctx *compileContext) Opcodes {
+ // header => code => structField => code => end
+ // ^ |
+ // |__________|
+ if c.isRecursive {
+ recursive := newRecursiveCode(ctx, c.typ, &CompiledCode{})
+ recursive.Type = c.typ
+ ctx.incIndex()
+ *ctx.recursiveCodes = append(*ctx.recursiveCodes, recursive)
+ return Opcodes{recursive}
+ }
+ codes := Opcodes{}
+ var prevField *Opcode
+ ctx.incIndent()
+ for idx, field := range c.fields {
+ isFirstField := idx == 0
+ isEndField := idx == len(c.fields)-1
+ fieldCodes := field.ToOpcode(ctx, isFirstField, isEndField)
+ for _, code := range fieldCodes {
+ if c.isIndirect {
+ code.Flags |= IndirectFlags
+ }
+ }
+ firstField := fieldCodes.First()
+ if len(codes) > 0 {
+ codes.Last().Next = firstField
+ firstField.Idx = codes.First().Idx
+ }
+ if prevField != nil {
+ prevField.NextField = firstField
+ }
+ if isEndField {
+ endField := fieldCodes.Last()
+ if len(codes) > 0 {
+ codes.First().End = endField
+ } else {
+ firstField.End = endField
+ }
+ codes = codes.Add(fieldCodes...)
+ break
+ }
+ prevField = c.lastFieldCode(field, firstField)
+ codes = codes.Add(fieldCodes...)
+ }
+ if len(codes) == 0 {
+ head := &Opcode{
+ Op: OpStructHead,
+ Idx: opcodeOffset(ctx.ptrIndex),
+ Type: c.typ,
+ DisplayIdx: ctx.opcodeIndex,
+ Indent: ctx.indent,
+ }
+ ctx.incOpcodeIndex()
+ end := &Opcode{
+ Op: OpStructEnd,
+ Idx: opcodeOffset(ctx.ptrIndex),
+ DisplayIdx: ctx.opcodeIndex,
+ Indent: ctx.indent,
+ }
+ head.NextField = end
+ head.Next = end
+ head.End = end
+ codes = codes.Add(head, end)
+ ctx.incIndex()
+ }
+ ctx.decIndent()
+ ctx.structTypeToCodes[uintptr(unsafe.Pointer(c.typ))] = codes
+ return codes
+}
+
+func (c *StructCode) ToAnonymousOpcode(ctx *compileContext) Opcodes {
+ // header => code => structField => code => end
+ // ^ |
+ // |__________|
+ if c.isRecursive {
+ recursive := newRecursiveCode(ctx, c.typ, &CompiledCode{})
+ recursive.Type = c.typ
+ ctx.incIndex()
+ *ctx.recursiveCodes = append(*ctx.recursiveCodes, recursive)
+ return Opcodes{recursive}
+ }
+ codes := Opcodes{}
+ var prevField *Opcode
+ for idx, field := range c.fields {
+ isFirstField := idx == 0
+ isEndField := idx == len(c.fields)-1
+ fieldCodes := field.ToAnonymousOpcode(ctx, isFirstField, isEndField)
+ for _, code := range fieldCodes {
+ if c.isIndirect {
+ code.Flags |= IndirectFlags
+ }
+ }
+ firstField := fieldCodes.First()
+ if len(codes) > 0 {
+ codes.Last().Next = firstField
+ firstField.Idx = codes.First().Idx
+ }
+ if prevField != nil {
+ prevField.NextField = firstField
+ }
+ if isEndField {
+ lastField := fieldCodes.Last()
+ if len(codes) > 0 {
+ codes.First().End = lastField
+ } else {
+ firstField.End = lastField
+ }
+ }
+ prevField = firstField
+ codes = codes.Add(fieldCodes...)
+ }
+ return codes
+}
+
+func (c *StructCode) removeFieldsByTags(tags runtime.StructTags) {
+ fields := make([]*StructFieldCode, 0, len(c.fields))
+ for _, field := range c.fields {
+ if field.isAnonymous {
+ structCode := field.getAnonymousStruct()
+ if structCode != nil && !structCode.isRecursive {
+ structCode.removeFieldsByTags(tags)
+ if len(structCode.fields) > 0 {
+ fields = append(fields, field)
+ }
+ continue
+ }
+ }
+ if tags.ExistsKey(field.key) {
+ continue
+ }
+ fields = append(fields, field)
+ }
+ c.fields = fields
+}
+
+func (c *StructCode) enableIndirect() {
+ if c.isIndirect {
+ return
+ }
+ c.isIndirect = true
+ if len(c.fields) == 0 {
+ return
+ }
+ structCode := c.fields[0].getStruct()
+ if structCode == nil {
+ return
+ }
+ structCode.enableIndirect()
+}
+
+func (c *StructCode) Filter(query *FieldQuery) Code {
+ fieldMap := map[string]*FieldQuery{}
+ for _, field := range query.Fields {
+ fieldMap[field.Name] = field
+ }
+ fields := make([]*StructFieldCode, 0, len(c.fields))
+ for _, field := range c.fields {
+ query, exists := fieldMap[field.key]
+ if !exists {
+ continue
+ }
+ fieldCode := &StructFieldCode{
+ typ: field.typ,
+ key: field.key,
+ tag: field.tag,
+ value: field.value,
+ offset: field.offset,
+ isAnonymous: field.isAnonymous,
+ isTaggedKey: field.isTaggedKey,
+ isNilableType: field.isNilableType,
+ isNilCheck: field.isNilCheck,
+ isAddrForMarshaler: field.isAddrForMarshaler,
+ isNextOpPtrType: field.isNextOpPtrType,
+ }
+ if len(query.Fields) > 0 {
+ fieldCode.value = fieldCode.value.Filter(query)
+ }
+ fields = append(fields, fieldCode)
+ }
+ return &StructCode{
+ typ: c.typ,
+ fields: fields,
+ isPtr: c.isPtr,
+ disableIndirectConversion: c.disableIndirectConversion,
+ isIndirect: c.isIndirect,
+ isRecursive: c.isRecursive,
+ }
+}
+
+type StructFieldCode struct {
+ typ *runtime.Type
+ key string
+ tag *runtime.StructTag
+ value Code
+ offset uintptr
+ isAnonymous bool
+ isTaggedKey bool
+ isNilableType bool
+ isNilCheck bool
+ isAddrForMarshaler bool
+ isNextOpPtrType bool
+ isMarshalerContext bool
+}
+
+func (c *StructFieldCode) getStruct() *StructCode {
+ value := c.value
+ ptr, ok := value.(*PtrCode)
+ if ok {
+ value = ptr.value
+ }
+ structCode, ok := value.(*StructCode)
+ if ok {
+ return structCode
+ }
+ return nil
+}
+
+func (c *StructFieldCode) getAnonymousStruct() *StructCode {
+ if !c.isAnonymous {
+ return nil
+ }
+ return c.getStruct()
+}
+
+func optimizeStructHeader(code *Opcode, tag *runtime.StructTag) OpType {
+ headType := code.ToHeaderType(tag.IsString)
+ if tag.IsOmitEmpty {
+ headType = headType.HeadToOmitEmptyHead()
+ }
+ return headType
+}
+
+func optimizeStructField(code *Opcode, tag *runtime.StructTag) OpType {
+ fieldType := code.ToFieldType(tag.IsString)
+ if tag.IsOmitEmpty {
+ fieldType = fieldType.FieldToOmitEmptyField()
+ }
+ return fieldType
+}
+
+func (c *StructFieldCode) headerOpcodes(ctx *compileContext, field *Opcode, valueCodes Opcodes) Opcodes {
+ value := valueCodes.First()
+ op := optimizeStructHeader(value, c.tag)
+ field.Op = op
+ if value.Flags&MarshalerContextFlags != 0 {
+ field.Flags |= MarshalerContextFlags
+ }
+ field.NumBitSize = value.NumBitSize
+ field.PtrNum = value.PtrNum
+ field.FieldQuery = value.FieldQuery
+ fieldCodes := Opcodes{field}
+ if op.IsMultipleOpHead() {
+ field.Next = value
+ fieldCodes = fieldCodes.Add(valueCodes...)
+ } else {
+ ctx.decIndex()
+ }
+ return fieldCodes
+}
+
+func (c *StructFieldCode) fieldOpcodes(ctx *compileContext, field *Opcode, valueCodes Opcodes) Opcodes {
+ value := valueCodes.First()
+ op := optimizeStructField(value, c.tag)
+ field.Op = op
+ if value.Flags&MarshalerContextFlags != 0 {
+ field.Flags |= MarshalerContextFlags
+ }
+ field.NumBitSize = value.NumBitSize
+ field.PtrNum = value.PtrNum
+ field.FieldQuery = value.FieldQuery
+
+ fieldCodes := Opcodes{field}
+ if op.IsMultipleOpField() {
+ field.Next = value
+ fieldCodes = fieldCodes.Add(valueCodes...)
+ } else {
+ ctx.decIndex()
+ }
+ return fieldCodes
+}
+
+func (c *StructFieldCode) addStructEndCode(ctx *compileContext, codes Opcodes) Opcodes {
+ end := &Opcode{
+ Op: OpStructEnd,
+ Idx: opcodeOffset(ctx.ptrIndex),
+ DisplayIdx: ctx.opcodeIndex,
+ Indent: ctx.indent,
+ }
+ codes.Last().Next = end
+ code := codes.First()
+ for code.Op == OpStructField || code.Op == OpStructHead {
+ code = code.Next
+ }
+ for code.NextField != nil {
+ code = code.NextField
+ }
+ code.NextField = end
+
+ codes = codes.Add(end)
+ ctx.incOpcodeIndex()
+ return codes
+}
+
+func (c *StructFieldCode) structKey(ctx *compileContext) string {
+ if ctx.escapeKey {
+ rctx := &RuntimeContext{Option: &Option{Flag: HTMLEscapeOption}}
+ return fmt.Sprintf(`%s:`, string(AppendString(rctx, []byte{}, c.key)))
+ }
+ return fmt.Sprintf(`"%s":`, c.key)
+}
+
+func (c *StructFieldCode) flags() OpFlags {
+ var flags OpFlags
+ if c.isTaggedKey {
+ flags |= IsTaggedKeyFlags
+ }
+ if c.isNilableType {
+ flags |= IsNilableTypeFlags
+ }
+ if c.isNilCheck {
+ flags |= NilCheckFlags
+ }
+ if c.isAddrForMarshaler {
+ flags |= AddrForMarshalerFlags
+ }
+ if c.isNextOpPtrType {
+ flags |= IsNextOpPtrTypeFlags
+ }
+ if c.isAnonymous {
+ flags |= AnonymousKeyFlags
+ }
+ if c.isMarshalerContext {
+ flags |= MarshalerContextFlags
+ }
+ return flags
+}
+
+func (c *StructFieldCode) toValueOpcodes(ctx *compileContext) Opcodes {
+ if c.isAnonymous {
+ anonymCode, ok := c.value.(AnonymousCode)
+ if ok {
+ return anonymCode.ToAnonymousOpcode(ctx)
+ }
+ }
+ return c.value.ToOpcode(ctx)
+}
+
+func (c *StructFieldCode) ToOpcode(ctx *compileContext, isFirstField, isEndField bool) Opcodes {
+ field := &Opcode{
+ Idx: opcodeOffset(ctx.ptrIndex),
+ Flags: c.flags(),
+ Key: c.structKey(ctx),
+ Offset: uint32(c.offset),
+ Type: c.typ,
+ DisplayIdx: ctx.opcodeIndex,
+ Indent: ctx.indent,
+ DisplayKey: c.key,
+ }
+ ctx.incIndex()
+ valueCodes := c.toValueOpcodes(ctx)
+ if isFirstField {
+ codes := c.headerOpcodes(ctx, field, valueCodes)
+ if isEndField {
+ codes = c.addStructEndCode(ctx, codes)
+ }
+ return codes
+ }
+ codes := c.fieldOpcodes(ctx, field, valueCodes)
+ if isEndField {
+ if isEnableStructEndOptimization(c.value) {
+ field.Op = field.Op.FieldToEnd()
+ } else {
+ codes = c.addStructEndCode(ctx, codes)
+ }
+ }
+ return codes
+}
+
+func (c *StructFieldCode) ToAnonymousOpcode(ctx *compileContext, isFirstField, isEndField bool) Opcodes {
+ field := &Opcode{
+ Idx: opcodeOffset(ctx.ptrIndex),
+ Flags: c.flags() | AnonymousHeadFlags,
+ Key: c.structKey(ctx),
+ Offset: uint32(c.offset),
+ Type: c.typ,
+ DisplayIdx: ctx.opcodeIndex,
+ Indent: ctx.indent,
+ DisplayKey: c.key,
+ }
+ ctx.incIndex()
+ valueCodes := c.toValueOpcodes(ctx)
+ if isFirstField {
+ return c.headerOpcodes(ctx, field, valueCodes)
+ }
+ return c.fieldOpcodes(ctx, field, valueCodes)
+}
+
+func isEnableStructEndOptimization(value Code) bool {
+ switch value.Kind() {
+ case CodeKindInt,
+ CodeKindUint,
+ CodeKindFloat,
+ CodeKindString,
+ CodeKindBool,
+ CodeKindBytes:
+ return true
+ case CodeKindPtr:
+ return isEnableStructEndOptimization(value.(*PtrCode).value)
+ default:
+ return false
+ }
+}
+
+type InterfaceCode struct {
+ typ *runtime.Type
+ fieldQuery *FieldQuery
+ isPtr bool
+}
+
+func (c *InterfaceCode) Kind() CodeKind {
+ return CodeKindInterface
+}
+
+func (c *InterfaceCode) ToOpcode(ctx *compileContext) Opcodes {
+ var code *Opcode
+ switch {
+ case c.isPtr:
+ code = newOpCode(ctx, c.typ, OpInterfacePtr)
+ default:
+ code = newOpCode(ctx, c.typ, OpInterface)
+ }
+ code.FieldQuery = c.fieldQuery
+ if c.typ.NumMethod() > 0 {
+ code.Flags |= NonEmptyInterfaceFlags
+ }
+ ctx.incIndex()
+ return Opcodes{code}
+}
+
+func (c *InterfaceCode) Filter(query *FieldQuery) Code {
+ return &InterfaceCode{
+ typ: c.typ,
+ fieldQuery: query,
+ isPtr: c.isPtr,
+ }
+}
+
+type MarshalJSONCode struct {
+ typ *runtime.Type
+ fieldQuery *FieldQuery
+ isAddrForMarshaler bool
+ isNilableType bool
+ isMarshalerContext bool
+}
+
+func (c *MarshalJSONCode) Kind() CodeKind {
+ return CodeKindMarshalJSON
+}
+
+func (c *MarshalJSONCode) ToOpcode(ctx *compileContext) Opcodes {
+ code := newOpCode(ctx, c.typ, OpMarshalJSON)
+ code.FieldQuery = c.fieldQuery
+ if c.isAddrForMarshaler {
+ code.Flags |= AddrForMarshalerFlags
+ }
+ if c.isMarshalerContext {
+ code.Flags |= MarshalerContextFlags
+ }
+ if c.isNilableType {
+ code.Flags |= IsNilableTypeFlags
+ } else {
+ code.Flags &= ^IsNilableTypeFlags
+ }
+ ctx.incIndex()
+ return Opcodes{code}
+}
+
+func (c *MarshalJSONCode) Filter(query *FieldQuery) Code {
+ return &MarshalJSONCode{
+ typ: c.typ,
+ fieldQuery: query,
+ isAddrForMarshaler: c.isAddrForMarshaler,
+ isNilableType: c.isNilableType,
+ isMarshalerContext: c.isMarshalerContext,
+ }
+}
+
+type MarshalTextCode struct {
+ typ *runtime.Type
+ fieldQuery *FieldQuery
+ isAddrForMarshaler bool
+ isNilableType bool
+}
+
+func (c *MarshalTextCode) Kind() CodeKind {
+ return CodeKindMarshalText
+}
+
+func (c *MarshalTextCode) ToOpcode(ctx *compileContext) Opcodes {
+ code := newOpCode(ctx, c.typ, OpMarshalText)
+ code.FieldQuery = c.fieldQuery
+ if c.isAddrForMarshaler {
+ code.Flags |= AddrForMarshalerFlags
+ }
+ if c.isNilableType {
+ code.Flags |= IsNilableTypeFlags
+ } else {
+ code.Flags &= ^IsNilableTypeFlags
+ }
+ ctx.incIndex()
+ return Opcodes{code}
+}
+
+func (c *MarshalTextCode) Filter(query *FieldQuery) Code {
+ return &MarshalTextCode{
+ typ: c.typ,
+ fieldQuery: query,
+ isAddrForMarshaler: c.isAddrForMarshaler,
+ isNilableType: c.isNilableType,
+ }
+}
+
+type PtrCode struct {
+ typ *runtime.Type
+ value Code
+ ptrNum uint8
+}
+
+func (c *PtrCode) Kind() CodeKind {
+ return CodeKindPtr
+}
+
+func (c *PtrCode) ToOpcode(ctx *compileContext) Opcodes {
+ codes := c.value.ToOpcode(ctx)
+ codes.First().Op = convertPtrOp(codes.First())
+ codes.First().PtrNum = c.ptrNum
+ return codes
+}
+
+func (c *PtrCode) ToAnonymousOpcode(ctx *compileContext) Opcodes {
+ var codes Opcodes
+ anonymCode, ok := c.value.(AnonymousCode)
+ if ok {
+ codes = anonymCode.ToAnonymousOpcode(ctx)
+ } else {
+ codes = c.value.ToOpcode(ctx)
+ }
+ codes.First().Op = convertPtrOp(codes.First())
+ codes.First().PtrNum = c.ptrNum
+ return codes
+}
+
+func (c *PtrCode) Filter(query *FieldQuery) Code {
+ return &PtrCode{
+ typ: c.typ,
+ value: c.value.Filter(query),
+ ptrNum: c.ptrNum,
+ }
+}
+
+func convertPtrOp(code *Opcode) OpType {
+ ptrHeadOp := code.Op.HeadToPtrHead()
+ if code.Op != ptrHeadOp {
+ if code.PtrNum > 0 {
+ // ptr field and ptr head
+ code.PtrNum--
+ }
+ return ptrHeadOp
+ }
+ switch code.Op {
+ case OpInt:
+ return OpIntPtr
+ case OpUint:
+ return OpUintPtr
+ case OpFloat32:
+ return OpFloat32Ptr
+ case OpFloat64:
+ return OpFloat64Ptr
+ case OpString:
+ return OpStringPtr
+ case OpBool:
+ return OpBoolPtr
+ case OpBytes:
+ return OpBytesPtr
+ case OpNumber:
+ return OpNumberPtr
+ case OpArray:
+ return OpArrayPtr
+ case OpSlice:
+ return OpSlicePtr
+ case OpMap:
+ return OpMapPtr
+ case OpMarshalJSON:
+ return OpMarshalJSONPtr
+ case OpMarshalText:
+ return OpMarshalTextPtr
+ case OpInterface:
+ return OpInterfacePtr
+ case OpRecursive:
+ return OpRecursivePtr
+ }
+ return code.Op
+}
+
+func isEmbeddedStruct(field *StructFieldCode) bool {
+ if !field.isAnonymous {
+ return false
+ }
+ t := field.typ
+ if t.Kind() == reflect.Ptr {
+ t = t.Elem()
+ }
+ return t.Kind() == reflect.Struct
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/compact.go b/vendor/github.com/goccy/go-json/internal/encoder/compact.go
new file mode 100644
index 00000000..e287a6c0
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/compact.go
@@ -0,0 +1,286 @@
+package encoder
+
+import (
+ "bytes"
+ "fmt"
+ "strconv"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+)
+
+var (
+ isWhiteSpace = [256]bool{
+ ' ': true,
+ '\n': true,
+ '\t': true,
+ '\r': true,
+ }
+ isHTMLEscapeChar = [256]bool{
+ '<': true,
+ '>': true,
+ '&': true,
+ }
+ nul = byte('\000')
+)
+
+func Compact(buf *bytes.Buffer, src []byte, escape bool) error {
+ if len(src) == 0 {
+ return errors.ErrUnexpectedEndOfJSON("", 0)
+ }
+ buf.Grow(len(src))
+ dst := buf.Bytes()
+
+ ctx := TakeRuntimeContext()
+ ctxBuf := ctx.Buf[:0]
+ ctxBuf = append(append(ctxBuf, src...), nul)
+ ctx.Buf = ctxBuf
+
+ if err := compactAndWrite(buf, dst, ctxBuf, escape); err != nil {
+ ReleaseRuntimeContext(ctx)
+ return err
+ }
+ ReleaseRuntimeContext(ctx)
+ return nil
+}
+
+func compactAndWrite(buf *bytes.Buffer, dst []byte, src []byte, escape bool) error {
+ dst, err := compact(dst, src, escape)
+ if err != nil {
+ return err
+ }
+ if _, err := buf.Write(dst); err != nil {
+ return err
+ }
+ return nil
+}
+
+func compact(dst, src []byte, escape bool) ([]byte, error) {
+ buf, cursor, err := compactValue(dst, src, 0, escape)
+ if err != nil {
+ return nil, err
+ }
+ if err := validateEndBuf(src, cursor); err != nil {
+ return nil, err
+ }
+ return buf, nil
+}
+
+func validateEndBuf(src []byte, cursor int64) error {
+ for {
+ switch src[cursor] {
+ case ' ', '\t', '\n', '\r':
+ cursor++
+ continue
+ case nul:
+ return nil
+ }
+ return errors.ErrSyntax(
+ fmt.Sprintf("invalid character '%c' after top-level value", src[cursor]),
+ cursor+1,
+ )
+ }
+}
+
+func skipWhiteSpace(buf []byte, cursor int64) int64 {
+LOOP:
+ if isWhiteSpace[buf[cursor]] {
+ cursor++
+ goto LOOP
+ }
+ return cursor
+}
+
+func compactValue(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) {
+ for {
+ switch src[cursor] {
+ case ' ', '\t', '\n', '\r':
+ cursor++
+ continue
+ case '{':
+ return compactObject(dst, src, cursor, escape)
+ case '}':
+ return nil, 0, errors.ErrSyntax("unexpected character '}'", cursor)
+ case '[':
+ return compactArray(dst, src, cursor, escape)
+ case ']':
+ return nil, 0, errors.ErrSyntax("unexpected character ']'", cursor)
+ case '"':
+ return compactString(dst, src, cursor, escape)
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return compactNumber(dst, src, cursor)
+ case 't':
+ return compactTrue(dst, src, cursor)
+ case 'f':
+ return compactFalse(dst, src, cursor)
+ case 'n':
+ return compactNull(dst, src, cursor)
+ default:
+ return nil, 0, errors.ErrSyntax(fmt.Sprintf("unexpected character '%c'", src[cursor]), cursor)
+ }
+ }
+}
+
+func compactObject(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) {
+ if src[cursor] == '{' {
+ dst = append(dst, '{')
+ } else {
+ return nil, 0, errors.ErrExpected("expected { character for object value", cursor)
+ }
+ cursor = skipWhiteSpace(src, cursor+1)
+ if src[cursor] == '}' {
+ dst = append(dst, '}')
+ return dst, cursor + 1, nil
+ }
+ var err error
+ for {
+ cursor = skipWhiteSpace(src, cursor)
+ dst, cursor, err = compactString(dst, src, cursor, escape)
+ if err != nil {
+ return nil, 0, err
+ }
+ cursor = skipWhiteSpace(src, cursor)
+ if src[cursor] != ':' {
+ return nil, 0, errors.ErrExpected("colon after object key", cursor)
+ }
+ dst = append(dst, ':')
+ dst, cursor, err = compactValue(dst, src, cursor+1, escape)
+ if err != nil {
+ return nil, 0, err
+ }
+ cursor = skipWhiteSpace(src, cursor)
+ switch src[cursor] {
+ case '}':
+ dst = append(dst, '}')
+ cursor++
+ return dst, cursor, nil
+ case ',':
+ dst = append(dst, ',')
+ default:
+ return nil, 0, errors.ErrExpected("comma after object value", cursor)
+ }
+ cursor++
+ }
+}
+
+func compactArray(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) {
+ if src[cursor] == '[' {
+ dst = append(dst, '[')
+ } else {
+ return nil, 0, errors.ErrExpected("expected [ character for array value", cursor)
+ }
+ cursor = skipWhiteSpace(src, cursor+1)
+ if src[cursor] == ']' {
+ dst = append(dst, ']')
+ return dst, cursor + 1, nil
+ }
+ var err error
+ for {
+ dst, cursor, err = compactValue(dst, src, cursor, escape)
+ if err != nil {
+ return nil, 0, err
+ }
+ cursor = skipWhiteSpace(src, cursor)
+ switch src[cursor] {
+ case ']':
+ dst = append(dst, ']')
+ cursor++
+ return dst, cursor, nil
+ case ',':
+ dst = append(dst, ',')
+ default:
+ return nil, 0, errors.ErrExpected("comma after array value", cursor)
+ }
+ cursor++
+ }
+}
+
+func compactString(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) {
+ if src[cursor] != '"' {
+ return nil, 0, errors.ErrInvalidCharacter(src[cursor], "string", cursor)
+ }
+ start := cursor
+ for {
+ cursor++
+ c := src[cursor]
+ if escape {
+ if isHTMLEscapeChar[c] {
+ dst = append(dst, src[start:cursor]...)
+ dst = append(dst, `\u00`...)
+ dst = append(dst, hex[c>>4], hex[c&0xF])
+ start = cursor + 1
+ } else if c == 0xE2 && cursor+2 < int64(len(src)) && src[cursor+1] == 0x80 && src[cursor+2]&^1 == 0xA8 {
+ dst = append(dst, src[start:cursor]...)
+ dst = append(dst, `\u202`...)
+ dst = append(dst, hex[src[cursor+2]&0xF])
+ start = cursor + 3
+ cursor += 2
+ }
+ }
+ switch c {
+ case '\\':
+ cursor++
+ if src[cursor] == nul {
+ return nil, 0, errors.ErrUnexpectedEndOfJSON("string", int64(len(src)))
+ }
+ case '"':
+ cursor++
+ return append(dst, src[start:cursor]...), cursor, nil
+ case nul:
+ return nil, 0, errors.ErrUnexpectedEndOfJSON("string", int64(len(src)))
+ }
+ }
+}
+
+func compactNumber(dst, src []byte, cursor int64) ([]byte, int64, error) {
+ start := cursor
+ for {
+ cursor++
+ if floatTable[src[cursor]] {
+ continue
+ }
+ break
+ }
+ num := src[start:cursor]
+ if _, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&num)), 64); err != nil {
+ return nil, 0, err
+ }
+ dst = append(dst, num...)
+ return dst, cursor, nil
+}
+
+func compactTrue(dst, src []byte, cursor int64) ([]byte, int64, error) {
+ if cursor+3 >= int64(len(src)) {
+ return nil, 0, errors.ErrUnexpectedEndOfJSON("true", cursor)
+ }
+ if !bytes.Equal(src[cursor:cursor+4], []byte(`true`)) {
+ return nil, 0, errors.ErrInvalidCharacter(src[cursor], "true", cursor)
+ }
+ dst = append(dst, "true"...)
+ cursor += 4
+ return dst, cursor, nil
+}
+
+func compactFalse(dst, src []byte, cursor int64) ([]byte, int64, error) {
+ if cursor+4 >= int64(len(src)) {
+ return nil, 0, errors.ErrUnexpectedEndOfJSON("false", cursor)
+ }
+ if !bytes.Equal(src[cursor:cursor+5], []byte(`false`)) {
+ return nil, 0, errors.ErrInvalidCharacter(src[cursor], "false", cursor)
+ }
+ dst = append(dst, "false"...)
+ cursor += 5
+ return dst, cursor, nil
+}
+
+func compactNull(dst, src []byte, cursor int64) ([]byte, int64, error) {
+ if cursor+3 >= int64(len(src)) {
+ return nil, 0, errors.ErrUnexpectedEndOfJSON("null", cursor)
+ }
+ if !bytes.Equal(src[cursor:cursor+4], []byte(`null`)) {
+ return nil, 0, errors.ErrInvalidCharacter(src[cursor], "null", cursor)
+ }
+ dst = append(dst, "null"...)
+ cursor += 4
+ return dst, cursor, nil
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/compiler.go b/vendor/github.com/goccy/go-json/internal/encoder/compiler.go
new file mode 100644
index 00000000..37b7aa38
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/compiler.go
@@ -0,0 +1,935 @@
+package encoder
+
+import (
+ "context"
+ "encoding"
+ "encoding/json"
+ "reflect"
+ "sync/atomic"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type marshalerContext interface {
+ MarshalJSON(context.Context) ([]byte, error)
+}
+
+var (
+ marshalJSONType = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
+ marshalJSONContextType = reflect.TypeOf((*marshalerContext)(nil)).Elem()
+ marshalTextType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
+ jsonNumberType = reflect.TypeOf(json.Number(""))
+ cachedOpcodeSets []*OpcodeSet
+ cachedOpcodeMap unsafe.Pointer // map[uintptr]*OpcodeSet
+ typeAddr *runtime.TypeAddr
+)
+
+func init() {
+ typeAddr = runtime.AnalyzeTypeAddr()
+ if typeAddr == nil {
+ typeAddr = &runtime.TypeAddr{}
+ }
+ cachedOpcodeSets = make([]*OpcodeSet, typeAddr.AddrRange>>typeAddr.AddrShift+1)
+}
+
+func loadOpcodeMap() map[uintptr]*OpcodeSet {
+ p := atomic.LoadPointer(&cachedOpcodeMap)
+ return *(*map[uintptr]*OpcodeSet)(unsafe.Pointer(&p))
+}
+
+func storeOpcodeSet(typ uintptr, set *OpcodeSet, m map[uintptr]*OpcodeSet) {
+ newOpcodeMap := make(map[uintptr]*OpcodeSet, len(m)+1)
+ newOpcodeMap[typ] = set
+
+ for k, v := range m {
+ newOpcodeMap[k] = v
+ }
+
+ atomic.StorePointer(&cachedOpcodeMap, *(*unsafe.Pointer)(unsafe.Pointer(&newOpcodeMap)))
+}
+
+func compileToGetCodeSetSlowPath(typeptr uintptr) (*OpcodeSet, error) {
+ opcodeMap := loadOpcodeMap()
+ if codeSet, exists := opcodeMap[typeptr]; exists {
+ return codeSet, nil
+ }
+ codeSet, err := newCompiler().compile(typeptr)
+ if err != nil {
+ return nil, err
+ }
+ storeOpcodeSet(typeptr, codeSet, opcodeMap)
+ return codeSet, nil
+}
+
+func getFilteredCodeSetIfNeeded(ctx *RuntimeContext, codeSet *OpcodeSet) (*OpcodeSet, error) {
+ if (ctx.Option.Flag & ContextOption) == 0 {
+ return codeSet, nil
+ }
+ query := FieldQueryFromContext(ctx.Option.Context)
+ if query == nil {
+ return codeSet, nil
+ }
+ ctx.Option.Flag |= FieldQueryOption
+ cacheCodeSet := codeSet.getQueryCache(query.Hash())
+ if cacheCodeSet != nil {
+ return cacheCodeSet, nil
+ }
+ queryCodeSet, err := newCompiler().codeToOpcodeSet(codeSet.Type, codeSet.Code.Filter(query))
+ if err != nil {
+ return nil, err
+ }
+ codeSet.setQueryCache(query.Hash(), queryCodeSet)
+ return queryCodeSet, nil
+}
+
+type Compiler struct {
+ structTypeToCode map[uintptr]*StructCode
+}
+
+func newCompiler() *Compiler {
+ return &Compiler{
+ structTypeToCode: map[uintptr]*StructCode{},
+ }
+}
+
+func (c *Compiler) compile(typeptr uintptr) (*OpcodeSet, error) {
+ // noescape trick for header.typ ( reflect.*rtype )
+ typ := *(**runtime.Type)(unsafe.Pointer(&typeptr))
+ code, err := c.typeToCode(typ)
+ if err != nil {
+ return nil, err
+ }
+ return c.codeToOpcodeSet(typ, code)
+}
+
+func (c *Compiler) codeToOpcodeSet(typ *runtime.Type, code Code) (*OpcodeSet, error) {
+ noescapeKeyCode := c.codeToOpcode(&compileContext{
+ structTypeToCodes: map[uintptr]Opcodes{},
+ recursiveCodes: &Opcodes{},
+ }, typ, code)
+ if err := noescapeKeyCode.Validate(); err != nil {
+ return nil, err
+ }
+ escapeKeyCode := c.codeToOpcode(&compileContext{
+ structTypeToCodes: map[uintptr]Opcodes{},
+ recursiveCodes: &Opcodes{},
+ escapeKey: true,
+ }, typ, code)
+ noescapeKeyCode = copyOpcode(noescapeKeyCode)
+ escapeKeyCode = copyOpcode(escapeKeyCode)
+ setTotalLengthToInterfaceOp(noescapeKeyCode)
+ setTotalLengthToInterfaceOp(escapeKeyCode)
+ interfaceNoescapeKeyCode := copyToInterfaceOpcode(noescapeKeyCode)
+ interfaceEscapeKeyCode := copyToInterfaceOpcode(escapeKeyCode)
+ codeLength := noescapeKeyCode.TotalLength()
+ return &OpcodeSet{
+ Type: typ,
+ NoescapeKeyCode: noescapeKeyCode,
+ EscapeKeyCode: escapeKeyCode,
+ InterfaceNoescapeKeyCode: interfaceNoescapeKeyCode,
+ InterfaceEscapeKeyCode: interfaceEscapeKeyCode,
+ CodeLength: codeLength,
+ EndCode: ToEndCode(interfaceNoescapeKeyCode),
+ Code: code,
+ QueryCache: map[string]*OpcodeSet{},
+ }, nil
+}
+
+func (c *Compiler) typeToCode(typ *runtime.Type) (Code, error) {
+ switch {
+ case c.implementsMarshalJSON(typ):
+ return c.marshalJSONCode(typ)
+ case c.implementsMarshalText(typ):
+ return c.marshalTextCode(typ)
+ }
+
+ isPtr := false
+ orgType := typ
+ if typ.Kind() == reflect.Ptr {
+ typ = typ.Elem()
+ isPtr = true
+ }
+ switch {
+ case c.implementsMarshalJSON(typ):
+ return c.marshalJSONCode(orgType)
+ case c.implementsMarshalText(typ):
+ return c.marshalTextCode(orgType)
+ }
+ switch typ.Kind() {
+ case reflect.Slice:
+ elem := typ.Elem()
+ if elem.Kind() == reflect.Uint8 {
+ p := runtime.PtrTo(elem)
+ if !c.implementsMarshalJSONType(p) && !p.Implements(marshalTextType) {
+ return c.bytesCode(typ, isPtr)
+ }
+ }
+ return c.sliceCode(typ)
+ case reflect.Map:
+ if isPtr {
+ return c.ptrCode(runtime.PtrTo(typ))
+ }
+ return c.mapCode(typ)
+ case reflect.Struct:
+ return c.structCode(typ, isPtr)
+ case reflect.Int:
+ return c.intCode(typ, isPtr)
+ case reflect.Int8:
+ return c.int8Code(typ, isPtr)
+ case reflect.Int16:
+ return c.int16Code(typ, isPtr)
+ case reflect.Int32:
+ return c.int32Code(typ, isPtr)
+ case reflect.Int64:
+ return c.int64Code(typ, isPtr)
+ case reflect.Uint, reflect.Uintptr:
+ return c.uintCode(typ, isPtr)
+ case reflect.Uint8:
+ return c.uint8Code(typ, isPtr)
+ case reflect.Uint16:
+ return c.uint16Code(typ, isPtr)
+ case reflect.Uint32:
+ return c.uint32Code(typ, isPtr)
+ case reflect.Uint64:
+ return c.uint64Code(typ, isPtr)
+ case reflect.Float32:
+ return c.float32Code(typ, isPtr)
+ case reflect.Float64:
+ return c.float64Code(typ, isPtr)
+ case reflect.String:
+ return c.stringCode(typ, isPtr)
+ case reflect.Bool:
+ return c.boolCode(typ, isPtr)
+ case reflect.Interface:
+ return c.interfaceCode(typ, isPtr)
+ default:
+ if isPtr && typ.Implements(marshalTextType) {
+ typ = orgType
+ }
+ return c.typeToCodeWithPtr(typ, isPtr)
+ }
+}
+
+func (c *Compiler) typeToCodeWithPtr(typ *runtime.Type, isPtr bool) (Code, error) {
+ switch {
+ case c.implementsMarshalJSON(typ):
+ return c.marshalJSONCode(typ)
+ case c.implementsMarshalText(typ):
+ return c.marshalTextCode(typ)
+ }
+ switch typ.Kind() {
+ case reflect.Ptr:
+ return c.ptrCode(typ)
+ case reflect.Slice:
+ elem := typ.Elem()
+ if elem.Kind() == reflect.Uint8 {
+ p := runtime.PtrTo(elem)
+ if !c.implementsMarshalJSONType(p) && !p.Implements(marshalTextType) {
+ return c.bytesCode(typ, false)
+ }
+ }
+ return c.sliceCode(typ)
+ case reflect.Array:
+ return c.arrayCode(typ)
+ case reflect.Map:
+ return c.mapCode(typ)
+ case reflect.Struct:
+ return c.structCode(typ, isPtr)
+ case reflect.Interface:
+ return c.interfaceCode(typ, false)
+ case reflect.Int:
+ return c.intCode(typ, false)
+ case reflect.Int8:
+ return c.int8Code(typ, false)
+ case reflect.Int16:
+ return c.int16Code(typ, false)
+ case reflect.Int32:
+ return c.int32Code(typ, false)
+ case reflect.Int64:
+ return c.int64Code(typ, false)
+ case reflect.Uint:
+ return c.uintCode(typ, false)
+ case reflect.Uint8:
+ return c.uint8Code(typ, false)
+ case reflect.Uint16:
+ return c.uint16Code(typ, false)
+ case reflect.Uint32:
+ return c.uint32Code(typ, false)
+ case reflect.Uint64:
+ return c.uint64Code(typ, false)
+ case reflect.Uintptr:
+ return c.uintCode(typ, false)
+ case reflect.Float32:
+ return c.float32Code(typ, false)
+ case reflect.Float64:
+ return c.float64Code(typ, false)
+ case reflect.String:
+ return c.stringCode(typ, false)
+ case reflect.Bool:
+ return c.boolCode(typ, false)
+ }
+ return nil, &errors.UnsupportedTypeError{Type: runtime.RType2Type(typ)}
+}
+
+const intSize = 32 << (^uint(0) >> 63)
+
+//nolint:unparam
+func (c *Compiler) intCode(typ *runtime.Type, isPtr bool) (*IntCode, error) {
+ return &IntCode{typ: typ, bitSize: intSize, isPtr: isPtr}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) int8Code(typ *runtime.Type, isPtr bool) (*IntCode, error) {
+ return &IntCode{typ: typ, bitSize: 8, isPtr: isPtr}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) int16Code(typ *runtime.Type, isPtr bool) (*IntCode, error) {
+ return &IntCode{typ: typ, bitSize: 16, isPtr: isPtr}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) int32Code(typ *runtime.Type, isPtr bool) (*IntCode, error) {
+ return &IntCode{typ: typ, bitSize: 32, isPtr: isPtr}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) int64Code(typ *runtime.Type, isPtr bool) (*IntCode, error) {
+ return &IntCode{typ: typ, bitSize: 64, isPtr: isPtr}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) uintCode(typ *runtime.Type, isPtr bool) (*UintCode, error) {
+ return &UintCode{typ: typ, bitSize: intSize, isPtr: isPtr}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) uint8Code(typ *runtime.Type, isPtr bool) (*UintCode, error) {
+ return &UintCode{typ: typ, bitSize: 8, isPtr: isPtr}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) uint16Code(typ *runtime.Type, isPtr bool) (*UintCode, error) {
+ return &UintCode{typ: typ, bitSize: 16, isPtr: isPtr}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) uint32Code(typ *runtime.Type, isPtr bool) (*UintCode, error) {
+ return &UintCode{typ: typ, bitSize: 32, isPtr: isPtr}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) uint64Code(typ *runtime.Type, isPtr bool) (*UintCode, error) {
+ return &UintCode{typ: typ, bitSize: 64, isPtr: isPtr}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) float32Code(typ *runtime.Type, isPtr bool) (*FloatCode, error) {
+ return &FloatCode{typ: typ, bitSize: 32, isPtr: isPtr}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) float64Code(typ *runtime.Type, isPtr bool) (*FloatCode, error) {
+ return &FloatCode{typ: typ, bitSize: 64, isPtr: isPtr}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) stringCode(typ *runtime.Type, isPtr bool) (*StringCode, error) {
+ return &StringCode{typ: typ, isPtr: isPtr}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) boolCode(typ *runtime.Type, isPtr bool) (*BoolCode, error) {
+ return &BoolCode{typ: typ, isPtr: isPtr}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) intStringCode(typ *runtime.Type) (*IntCode, error) {
+ return &IntCode{typ: typ, bitSize: intSize, isString: true}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) int8StringCode(typ *runtime.Type) (*IntCode, error) {
+ return &IntCode{typ: typ, bitSize: 8, isString: true}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) int16StringCode(typ *runtime.Type) (*IntCode, error) {
+ return &IntCode{typ: typ, bitSize: 16, isString: true}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) int32StringCode(typ *runtime.Type) (*IntCode, error) {
+ return &IntCode{typ: typ, bitSize: 32, isString: true}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) int64StringCode(typ *runtime.Type) (*IntCode, error) {
+ return &IntCode{typ: typ, bitSize: 64, isString: true}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) uintStringCode(typ *runtime.Type) (*UintCode, error) {
+ return &UintCode{typ: typ, bitSize: intSize, isString: true}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) uint8StringCode(typ *runtime.Type) (*UintCode, error) {
+ return &UintCode{typ: typ, bitSize: 8, isString: true}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) uint16StringCode(typ *runtime.Type) (*UintCode, error) {
+ return &UintCode{typ: typ, bitSize: 16, isString: true}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) uint32StringCode(typ *runtime.Type) (*UintCode, error) {
+ return &UintCode{typ: typ, bitSize: 32, isString: true}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) uint64StringCode(typ *runtime.Type) (*UintCode, error) {
+ return &UintCode{typ: typ, bitSize: 64, isString: true}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) bytesCode(typ *runtime.Type, isPtr bool) (*BytesCode, error) {
+ return &BytesCode{typ: typ, isPtr: isPtr}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) interfaceCode(typ *runtime.Type, isPtr bool) (*InterfaceCode, error) {
+ return &InterfaceCode{typ: typ, isPtr: isPtr}, nil
+}
+
+//nolint:unparam
+func (c *Compiler) marshalJSONCode(typ *runtime.Type) (*MarshalJSONCode, error) {
+ return &MarshalJSONCode{
+ typ: typ,
+ isAddrForMarshaler: c.isPtrMarshalJSONType(typ),
+ isNilableType: c.isNilableType(typ),
+ isMarshalerContext: typ.Implements(marshalJSONContextType) || runtime.PtrTo(typ).Implements(marshalJSONContextType),
+ }, nil
+}
+
+//nolint:unparam
+func (c *Compiler) marshalTextCode(typ *runtime.Type) (*MarshalTextCode, error) {
+ return &MarshalTextCode{
+ typ: typ,
+ isAddrForMarshaler: c.isPtrMarshalTextType(typ),
+ isNilableType: c.isNilableType(typ),
+ }, nil
+}
+
+func (c *Compiler) ptrCode(typ *runtime.Type) (*PtrCode, error) {
+ code, err := c.typeToCodeWithPtr(typ.Elem(), true)
+ if err != nil {
+ return nil, err
+ }
+ ptr, ok := code.(*PtrCode)
+ if ok {
+ return &PtrCode{typ: typ, value: ptr.value, ptrNum: ptr.ptrNum + 1}, nil
+ }
+ return &PtrCode{typ: typ, value: code, ptrNum: 1}, nil
+}
+
+func (c *Compiler) sliceCode(typ *runtime.Type) (*SliceCode, error) {
+ elem := typ.Elem()
+ code, err := c.listElemCode(elem)
+ if err != nil {
+ return nil, err
+ }
+ if code.Kind() == CodeKindStruct {
+ structCode := code.(*StructCode)
+ structCode.enableIndirect()
+ }
+ return &SliceCode{typ: typ, value: code}, nil
+}
+
+func (c *Compiler) arrayCode(typ *runtime.Type) (*ArrayCode, error) {
+ elem := typ.Elem()
+ code, err := c.listElemCode(elem)
+ if err != nil {
+ return nil, err
+ }
+ if code.Kind() == CodeKindStruct {
+ structCode := code.(*StructCode)
+ structCode.enableIndirect()
+ }
+ return &ArrayCode{typ: typ, value: code}, nil
+}
+
+func (c *Compiler) mapCode(typ *runtime.Type) (*MapCode, error) {
+ keyCode, err := c.mapKeyCode(typ.Key())
+ if err != nil {
+ return nil, err
+ }
+ valueCode, err := c.mapValueCode(typ.Elem())
+ if err != nil {
+ return nil, err
+ }
+ if valueCode.Kind() == CodeKindStruct {
+ structCode := valueCode.(*StructCode)
+ structCode.enableIndirect()
+ }
+ return &MapCode{typ: typ, key: keyCode, value: valueCode}, nil
+}
+
+func (c *Compiler) listElemCode(typ *runtime.Type) (Code, error) {
+ switch {
+ case c.implementsMarshalJSONType(typ) || c.implementsMarshalJSONType(runtime.PtrTo(typ)):
+ return c.marshalJSONCode(typ)
+ case !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType):
+ return c.marshalTextCode(typ)
+ case typ.Kind() == reflect.Map:
+ return c.ptrCode(runtime.PtrTo(typ))
+ default:
+ // isPtr was originally used to indicate whether the type of top level is pointer.
+ // However, since the slice/array element is a specification that can get the pointer address, explicitly set isPtr to true.
+ // See here for related issues: https://github.com/goccy/go-json/issues/370
+ code, err := c.typeToCodeWithPtr(typ, true)
+ if err != nil {
+ return nil, err
+ }
+ ptr, ok := code.(*PtrCode)
+ if ok {
+ if ptr.value.Kind() == CodeKindMap {
+ ptr.ptrNum++
+ }
+ }
+ return code, nil
+ }
+}
+
+func (c *Compiler) mapKeyCode(typ *runtime.Type) (Code, error) {
+ switch {
+ case c.implementsMarshalText(typ):
+ return c.marshalTextCode(typ)
+ }
+ switch typ.Kind() {
+ case reflect.Ptr:
+ return c.ptrCode(typ)
+ case reflect.String:
+ return c.stringCode(typ, false)
+ case reflect.Int:
+ return c.intStringCode(typ)
+ case reflect.Int8:
+ return c.int8StringCode(typ)
+ case reflect.Int16:
+ return c.int16StringCode(typ)
+ case reflect.Int32:
+ return c.int32StringCode(typ)
+ case reflect.Int64:
+ return c.int64StringCode(typ)
+ case reflect.Uint:
+ return c.uintStringCode(typ)
+ case reflect.Uint8:
+ return c.uint8StringCode(typ)
+ case reflect.Uint16:
+ return c.uint16StringCode(typ)
+ case reflect.Uint32:
+ return c.uint32StringCode(typ)
+ case reflect.Uint64:
+ return c.uint64StringCode(typ)
+ case reflect.Uintptr:
+ return c.uintStringCode(typ)
+ }
+ return nil, &errors.UnsupportedTypeError{Type: runtime.RType2Type(typ)}
+}
+
+func (c *Compiler) mapValueCode(typ *runtime.Type) (Code, error) {
+ switch typ.Kind() {
+ case reflect.Map:
+ return c.ptrCode(runtime.PtrTo(typ))
+ default:
+ code, err := c.typeToCodeWithPtr(typ, false)
+ if err != nil {
+ return nil, err
+ }
+ ptr, ok := code.(*PtrCode)
+ if ok {
+ if ptr.value.Kind() == CodeKindMap {
+ ptr.ptrNum++
+ }
+ }
+ return code, nil
+ }
+}
+
+func (c *Compiler) structCode(typ *runtime.Type, isPtr bool) (*StructCode, error) {
+ typeptr := uintptr(unsafe.Pointer(typ))
+ if code, exists := c.structTypeToCode[typeptr]; exists {
+ derefCode := *code
+ derefCode.isRecursive = true
+ return &derefCode, nil
+ }
+ indirect := runtime.IfaceIndir(typ)
+ code := &StructCode{typ: typ, isPtr: isPtr, isIndirect: indirect}
+ c.structTypeToCode[typeptr] = code
+
+ fieldNum := typ.NumField()
+ tags := c.typeToStructTags(typ)
+ fields := []*StructFieldCode{}
+ for i, tag := range tags {
+ isOnlyOneFirstField := i == 0 && fieldNum == 1
+ field, err := c.structFieldCode(code, tag, isPtr, isOnlyOneFirstField)
+ if err != nil {
+ return nil, err
+ }
+ if field.isAnonymous {
+ structCode := field.getAnonymousStruct()
+ if structCode != nil {
+ structCode.removeFieldsByTags(tags)
+ if c.isAssignableIndirect(field, isPtr) {
+ if indirect {
+ structCode.isIndirect = true
+ } else {
+ structCode.isIndirect = false
+ }
+ }
+ }
+ } else {
+ structCode := field.getStruct()
+ if structCode != nil {
+ if indirect {
+ // if parent is indirect type, set child indirect property to true
+ structCode.isIndirect = true
+ } else {
+ // if parent is not indirect type, set child indirect property to false.
+ // but if parent's indirect is false and isPtr is true, then indirect must be true.
+ // Do this only if indirectConversion is enabled at the end of compileStruct.
+ structCode.isIndirect = false
+ }
+ }
+ }
+ fields = append(fields, field)
+ }
+ fieldMap := c.getFieldMap(fields)
+ duplicatedFieldMap := c.getDuplicatedFieldMap(fieldMap)
+ code.fields = c.filteredDuplicatedFields(fields, duplicatedFieldMap)
+ if !code.disableIndirectConversion && !indirect && isPtr {
+ code.enableIndirect()
+ }
+ delete(c.structTypeToCode, typeptr)
+ return code, nil
+}
+
+func toElemType(t *runtime.Type) *runtime.Type {
+ for t.Kind() == reflect.Ptr {
+ t = t.Elem()
+ }
+ return t
+}
+
+func (c *Compiler) structFieldCode(structCode *StructCode, tag *runtime.StructTag, isPtr, isOnlyOneFirstField bool) (*StructFieldCode, error) {
+ field := tag.Field
+ fieldType := runtime.Type2RType(field.Type)
+ isIndirectSpecialCase := isPtr && isOnlyOneFirstField
+ fieldCode := &StructFieldCode{
+ typ: fieldType,
+ key: tag.Key,
+ tag: tag,
+ offset: field.Offset,
+ isAnonymous: field.Anonymous && !tag.IsTaggedKey && toElemType(fieldType).Kind() == reflect.Struct,
+ isTaggedKey: tag.IsTaggedKey,
+ isNilableType: c.isNilableType(fieldType),
+ isNilCheck: true,
+ }
+ switch {
+ case c.isMovePointerPositionFromHeadToFirstMarshalJSONFieldCase(fieldType, isIndirectSpecialCase):
+ code, err := c.marshalJSONCode(fieldType)
+ if err != nil {
+ return nil, err
+ }
+ fieldCode.value = code
+ fieldCode.isAddrForMarshaler = true
+ fieldCode.isNilCheck = false
+ structCode.isIndirect = false
+ structCode.disableIndirectConversion = true
+ case c.isMovePointerPositionFromHeadToFirstMarshalTextFieldCase(fieldType, isIndirectSpecialCase):
+ code, err := c.marshalTextCode(fieldType)
+ if err != nil {
+ return nil, err
+ }
+ fieldCode.value = code
+ fieldCode.isAddrForMarshaler = true
+ fieldCode.isNilCheck = false
+ structCode.isIndirect = false
+ structCode.disableIndirectConversion = true
+ case isPtr && c.isPtrMarshalJSONType(fieldType):
+ // *struct{ field T }
+ // func (*T) MarshalJSON() ([]byte, error)
+ code, err := c.marshalJSONCode(fieldType)
+ if err != nil {
+ return nil, err
+ }
+ fieldCode.value = code
+ fieldCode.isAddrForMarshaler = true
+ fieldCode.isNilCheck = false
+ case isPtr && c.isPtrMarshalTextType(fieldType):
+ // *struct{ field T }
+ // func (*T) MarshalText() ([]byte, error)
+ code, err := c.marshalTextCode(fieldType)
+ if err != nil {
+ return nil, err
+ }
+ fieldCode.value = code
+ fieldCode.isAddrForMarshaler = true
+ fieldCode.isNilCheck = false
+ default:
+ code, err := c.typeToCodeWithPtr(fieldType, isPtr)
+ if err != nil {
+ return nil, err
+ }
+ switch code.Kind() {
+ case CodeKindPtr, CodeKindInterface:
+ fieldCode.isNextOpPtrType = true
+ }
+ fieldCode.value = code
+ }
+ return fieldCode, nil
+}
+
+func (c *Compiler) isAssignableIndirect(fieldCode *StructFieldCode, isPtr bool) bool {
+ if isPtr {
+ return false
+ }
+ codeType := fieldCode.value.Kind()
+ if codeType == CodeKindMarshalJSON {
+ return false
+ }
+ if codeType == CodeKindMarshalText {
+ return false
+ }
+ return true
+}
+
+func (c *Compiler) getFieldMap(fields []*StructFieldCode) map[string][]*StructFieldCode {
+ fieldMap := map[string][]*StructFieldCode{}
+ for _, field := range fields {
+ if field.isAnonymous {
+ for k, v := range c.getAnonymousFieldMap(field) {
+ fieldMap[k] = append(fieldMap[k], v...)
+ }
+ continue
+ }
+ fieldMap[field.key] = append(fieldMap[field.key], field)
+ }
+ return fieldMap
+}
+
+func (c *Compiler) getAnonymousFieldMap(field *StructFieldCode) map[string][]*StructFieldCode {
+ fieldMap := map[string][]*StructFieldCode{}
+ structCode := field.getAnonymousStruct()
+ if structCode == nil || structCode.isRecursive {
+ fieldMap[field.key] = append(fieldMap[field.key], field)
+ return fieldMap
+ }
+ for k, v := range c.getFieldMapFromAnonymousParent(structCode.fields) {
+ fieldMap[k] = append(fieldMap[k], v...)
+ }
+ return fieldMap
+}
+
+func (c *Compiler) getFieldMapFromAnonymousParent(fields []*StructFieldCode) map[string][]*StructFieldCode {
+ fieldMap := map[string][]*StructFieldCode{}
+ for _, field := range fields {
+ if field.isAnonymous {
+ for k, v := range c.getAnonymousFieldMap(field) {
+ // Do not handle tagged key when embedding more than once
+ for _, vv := range v {
+ vv.isTaggedKey = false
+ }
+ fieldMap[k] = append(fieldMap[k], v...)
+ }
+ continue
+ }
+ fieldMap[field.key] = append(fieldMap[field.key], field)
+ }
+ return fieldMap
+}
+
+func (c *Compiler) getDuplicatedFieldMap(fieldMap map[string][]*StructFieldCode) map[*StructFieldCode]struct{} {
+ duplicatedFieldMap := map[*StructFieldCode]struct{}{}
+ for _, fields := range fieldMap {
+ if len(fields) == 1 {
+ continue
+ }
+ if c.isTaggedKeyOnly(fields) {
+ for _, field := range fields {
+ if field.isTaggedKey {
+ continue
+ }
+ duplicatedFieldMap[field] = struct{}{}
+ }
+ } else {
+ for _, field := range fields {
+ duplicatedFieldMap[field] = struct{}{}
+ }
+ }
+ }
+ return duplicatedFieldMap
+}
+
+func (c *Compiler) filteredDuplicatedFields(fields []*StructFieldCode, duplicatedFieldMap map[*StructFieldCode]struct{}) []*StructFieldCode {
+ filteredFields := make([]*StructFieldCode, 0, len(fields))
+ for _, field := range fields {
+ if field.isAnonymous {
+ structCode := field.getAnonymousStruct()
+ if structCode != nil && !structCode.isRecursive {
+ structCode.fields = c.filteredDuplicatedFields(structCode.fields, duplicatedFieldMap)
+ if len(structCode.fields) > 0 {
+ filteredFields = append(filteredFields, field)
+ }
+ continue
+ }
+ }
+ if _, exists := duplicatedFieldMap[field]; exists {
+ continue
+ }
+ filteredFields = append(filteredFields, field)
+ }
+ return filteredFields
+}
+
+func (c *Compiler) isTaggedKeyOnly(fields []*StructFieldCode) bool {
+ var taggedKeyFieldCount int
+ for _, field := range fields {
+ if field.isTaggedKey {
+ taggedKeyFieldCount++
+ }
+ }
+ return taggedKeyFieldCount == 1
+}
+
+func (c *Compiler) typeToStructTags(typ *runtime.Type) runtime.StructTags {
+ tags := runtime.StructTags{}
+ fieldNum := typ.NumField()
+ for i := 0; i < fieldNum; i++ {
+ field := typ.Field(i)
+ if runtime.IsIgnoredStructField(field) {
+ continue
+ }
+ tags = append(tags, runtime.StructTagFromField(field))
+ }
+ return tags
+}
+
+// *struct{ field T } => struct { field *T }
+// func (*T) MarshalJSON() ([]byte, error)
+func (c *Compiler) isMovePointerPositionFromHeadToFirstMarshalJSONFieldCase(typ *runtime.Type, isIndirectSpecialCase bool) bool {
+ return isIndirectSpecialCase && !c.isNilableType(typ) && c.isPtrMarshalJSONType(typ)
+}
+
+// *struct{ field T } => struct { field *T }
+// func (*T) MarshalText() ([]byte, error)
+func (c *Compiler) isMovePointerPositionFromHeadToFirstMarshalTextFieldCase(typ *runtime.Type, isIndirectSpecialCase bool) bool {
+ return isIndirectSpecialCase && !c.isNilableType(typ) && c.isPtrMarshalTextType(typ)
+}
+
+func (c *Compiler) implementsMarshalJSON(typ *runtime.Type) bool {
+ if !c.implementsMarshalJSONType(typ) {
+ return false
+ }
+ if typ.Kind() != reflect.Ptr {
+ return true
+ }
+ // type kind is reflect.Ptr
+ if !c.implementsMarshalJSONType(typ.Elem()) {
+ return true
+ }
+ // needs to dereference
+ return false
+}
+
+func (c *Compiler) implementsMarshalText(typ *runtime.Type) bool {
+ if !typ.Implements(marshalTextType) {
+ return false
+ }
+ if typ.Kind() != reflect.Ptr {
+ return true
+ }
+ // type kind is reflect.Ptr
+ if !typ.Elem().Implements(marshalTextType) {
+ return true
+ }
+ // needs to dereference
+ return false
+}
+
+func (c *Compiler) isNilableType(typ *runtime.Type) bool {
+ if !runtime.IfaceIndir(typ) {
+ return true
+ }
+ switch typ.Kind() {
+ case reflect.Ptr:
+ return true
+ case reflect.Map:
+ return true
+ case reflect.Func:
+ return true
+ default:
+ return false
+ }
+}
+
+func (c *Compiler) implementsMarshalJSONType(typ *runtime.Type) bool {
+ return typ.Implements(marshalJSONType) || typ.Implements(marshalJSONContextType)
+}
+
+func (c *Compiler) isPtrMarshalJSONType(typ *runtime.Type) bool {
+ return !c.implementsMarshalJSONType(typ) && c.implementsMarshalJSONType(runtime.PtrTo(typ))
+}
+
+func (c *Compiler) isPtrMarshalTextType(typ *runtime.Type) bool {
+ return !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType)
+}
+
+func (c *Compiler) codeToOpcode(ctx *compileContext, typ *runtime.Type, code Code) *Opcode {
+ codes := code.ToOpcode(ctx)
+ codes.Last().Next = newEndOp(ctx, typ)
+ c.linkRecursiveCode(ctx)
+ return codes.First()
+}
+
+func (c *Compiler) linkRecursiveCode(ctx *compileContext) {
+ recursiveCodes := map[uintptr]*CompiledCode{}
+ for _, recursive := range *ctx.recursiveCodes {
+ typeptr := uintptr(unsafe.Pointer(recursive.Type))
+ codes := ctx.structTypeToCodes[typeptr]
+ if recursiveCode, ok := recursiveCodes[typeptr]; ok {
+ *recursive.Jmp = *recursiveCode
+ continue
+ }
+
+ code := copyOpcode(codes.First())
+ code.Op = code.Op.PtrHeadToHead()
+ lastCode := newEndOp(&compileContext{}, recursive.Type)
+ lastCode.Op = OpRecursiveEnd
+
+ // OpRecursiveEnd must set before call TotalLength
+ code.End.Next = lastCode
+
+ totalLength := code.TotalLength()
+
+ // Idx, ElemIdx, Length must set after call TotalLength
+ lastCode.Idx = uint32((totalLength + 1) * uintptrSize)
+ lastCode.ElemIdx = lastCode.Idx + uintptrSize
+ lastCode.Length = lastCode.Idx + 2*uintptrSize
+
+ // extend length to alloc slot for elemIdx + length
+ curTotalLength := uintptr(recursive.TotalLength()) + 3
+ nextTotalLength := uintptr(totalLength) + 3
+
+ compiled := recursive.Jmp
+ compiled.Code = code
+ compiled.CurLen = curTotalLength
+ compiled.NextLen = nextTotalLength
+ compiled.Linked = true
+
+ recursiveCodes[typeptr] = compiled
+ }
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go b/vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go
new file mode 100644
index 00000000..20c93cbf
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go
@@ -0,0 +1,32 @@
+//go:build !race
+// +build !race
+
+package encoder
+
+func CompileToGetCodeSet(ctx *RuntimeContext, typeptr uintptr) (*OpcodeSet, error) {
+ if typeptr > typeAddr.MaxTypeAddr || typeptr < typeAddr.BaseTypeAddr {
+ codeSet, err := compileToGetCodeSetSlowPath(typeptr)
+ if err != nil {
+ return nil, err
+ }
+ return getFilteredCodeSetIfNeeded(ctx, codeSet)
+ }
+ index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift
+ if codeSet := cachedOpcodeSets[index]; codeSet != nil {
+ filtered, err := getFilteredCodeSetIfNeeded(ctx, codeSet)
+ if err != nil {
+ return nil, err
+ }
+ return filtered, nil
+ }
+ codeSet, err := newCompiler().compile(typeptr)
+ if err != nil {
+ return nil, err
+ }
+ filtered, err := getFilteredCodeSetIfNeeded(ctx, codeSet)
+ if err != nil {
+ return nil, err
+ }
+ cachedOpcodeSets[index] = codeSet
+ return filtered, nil
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go b/vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go
new file mode 100644
index 00000000..13ba23fd
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go
@@ -0,0 +1,45 @@
+//go:build race
+// +build race
+
+package encoder
+
+import (
+ "sync"
+)
+
+var setsMu sync.RWMutex
+
+func CompileToGetCodeSet(ctx *RuntimeContext, typeptr uintptr) (*OpcodeSet, error) {
+ if typeptr > typeAddr.MaxTypeAddr || typeptr < typeAddr.BaseTypeAddr {
+ codeSet, err := compileToGetCodeSetSlowPath(typeptr)
+ if err != nil {
+ return nil, err
+ }
+ return getFilteredCodeSetIfNeeded(ctx, codeSet)
+ }
+ index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift
+ setsMu.RLock()
+ if codeSet := cachedOpcodeSets[index]; codeSet != nil {
+ filtered, err := getFilteredCodeSetIfNeeded(ctx, codeSet)
+ if err != nil {
+ setsMu.RUnlock()
+ return nil, err
+ }
+ setsMu.RUnlock()
+ return filtered, nil
+ }
+ setsMu.RUnlock()
+
+ codeSet, err := newCompiler().compile(typeptr)
+ if err != nil {
+ return nil, err
+ }
+ filtered, err := getFilteredCodeSetIfNeeded(ctx, codeSet)
+ if err != nil {
+ return nil, err
+ }
+ setsMu.Lock()
+ cachedOpcodeSets[index] = codeSet
+ setsMu.Unlock()
+ return filtered, nil
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/context.go b/vendor/github.com/goccy/go-json/internal/encoder/context.go
new file mode 100644
index 00000000..3833d0c8
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/context.go
@@ -0,0 +1,105 @@
+package encoder
+
+import (
+ "context"
+ "sync"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+type compileContext struct {
+ opcodeIndex uint32
+ ptrIndex int
+ indent uint32
+ escapeKey bool
+ structTypeToCodes map[uintptr]Opcodes
+ recursiveCodes *Opcodes
+}
+
+func (c *compileContext) incIndent() {
+ c.indent++
+}
+
+func (c *compileContext) decIndent() {
+ c.indent--
+}
+
+func (c *compileContext) incIndex() {
+ c.incOpcodeIndex()
+ c.incPtrIndex()
+}
+
+func (c *compileContext) decIndex() {
+ c.decOpcodeIndex()
+ c.decPtrIndex()
+}
+
+func (c *compileContext) incOpcodeIndex() {
+ c.opcodeIndex++
+}
+
+func (c *compileContext) decOpcodeIndex() {
+ c.opcodeIndex--
+}
+
+func (c *compileContext) incPtrIndex() {
+ c.ptrIndex++
+}
+
+func (c *compileContext) decPtrIndex() {
+ c.ptrIndex--
+}
+
+const (
+ bufSize = 1024
+)
+
+var (
+ runtimeContextPool = sync.Pool{
+ New: func() interface{} {
+ return &RuntimeContext{
+ Buf: make([]byte, 0, bufSize),
+ Ptrs: make([]uintptr, 128),
+ KeepRefs: make([]unsafe.Pointer, 0, 8),
+ Option: &Option{},
+ }
+ },
+ }
+)
+
+type RuntimeContext struct {
+ Context context.Context
+ Buf []byte
+ MarshalBuf []byte
+ Ptrs []uintptr
+ KeepRefs []unsafe.Pointer
+ SeenPtr []uintptr
+ BaseIndent uint32
+ Prefix []byte
+ IndentStr []byte
+ Option *Option
+}
+
+func (c *RuntimeContext) Init(p uintptr, codelen int) {
+ if len(c.Ptrs) < codelen {
+ c.Ptrs = make([]uintptr, codelen)
+ }
+ c.Ptrs[0] = p
+ c.KeepRefs = c.KeepRefs[:0]
+ c.SeenPtr = c.SeenPtr[:0]
+ c.BaseIndent = 0
+}
+
+func (c *RuntimeContext) Ptr() uintptr {
+ header := (*runtime.SliceHeader)(unsafe.Pointer(&c.Ptrs))
+ return uintptr(header.Data)
+}
+
+func TakeRuntimeContext() *RuntimeContext {
+ return runtimeContextPool.Get().(*RuntimeContext)
+}
+
+func ReleaseRuntimeContext(ctx *RuntimeContext) {
+ runtimeContextPool.Put(ctx)
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/decode_rune.go b/vendor/github.com/goccy/go-json/internal/encoder/decode_rune.go
new file mode 100644
index 00000000..35c959d4
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/decode_rune.go
@@ -0,0 +1,126 @@
+package encoder
+
+import "unicode/utf8"
+
+const (
+ // The default lowest and highest continuation byte.
+ locb = 128 //0b10000000
+ hicb = 191 //0b10111111
+
+ // These names of these constants are chosen to give nice alignment in the
+ // table below. The first nibble is an index into acceptRanges or F for
+ // special one-byte cases. The second nibble is the Rune length or the
+ // Status for the special one-byte case.
+ xx = 0xF1 // invalid: size 1
+ as = 0xF0 // ASCII: size 1
+ s1 = 0x02 // accept 0, size 2
+ s2 = 0x13 // accept 1, size 3
+ s3 = 0x03 // accept 0, size 3
+ s4 = 0x23 // accept 2, size 3
+ s5 = 0x34 // accept 3, size 4
+ s6 = 0x04 // accept 0, size 4
+ s7 = 0x44 // accept 4, size 4
+)
+
+// first is information about the first byte in a UTF-8 sequence.
+var first = [256]uint8{
+ // 1 2 3 4 5 6 7 8 9 A B C D E F
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x00-0x0F
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x10-0x1F
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x20-0x2F
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x30-0x3F
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x40-0x4F
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x50-0x5F
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x60-0x6F
+ as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, as, // 0x70-0x7F
+ // 1 2 3 4 5 6 7 8 9 A B C D E F
+ xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0x80-0x8F
+ xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0x90-0x9F
+ xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xA0-0xAF
+ xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xB0-0xBF
+ xx, xx, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, // 0xC0-0xCF
+ s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, s1, // 0xD0-0xDF
+ s2, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s3, s4, s3, s3, // 0xE0-0xEF
+ s5, s6, s6, s6, s7, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, // 0xF0-0xFF
+}
+
+const (
+ lineSep = byte(168) //'\u2028'
+ paragraphSep = byte(169) //'\u2029'
+)
+
+type decodeRuneState int
+
+const (
+ validUTF8State decodeRuneState = iota
+ runeErrorState
+ lineSepState
+ paragraphSepState
+)
+
+func decodeRuneInString(s string) (decodeRuneState, int) {
+ n := len(s)
+ s0 := s[0]
+ x := first[s0]
+ if x >= as {
+ // The following code simulates an additional check for x == xx and
+ // handling the ASCII and invalid cases accordingly. This mask-and-or
+ // approach prevents an additional branch.
+ mask := rune(x) << 31 >> 31 // Create 0x0000 or 0xFFFF.
+ if rune(s[0])&^mask|utf8.RuneError&mask == utf8.RuneError {
+ return runeErrorState, 1
+ }
+ return validUTF8State, 1
+ }
+ sz := int(x & 7)
+ if n < sz {
+ return runeErrorState, 1
+ }
+ s1 := s[1]
+ switch x >> 4 {
+ case 0:
+ if s1 < locb || hicb < s1 {
+ return runeErrorState, 1
+ }
+ case 1:
+ if s1 < 0xA0 || hicb < s1 {
+ return runeErrorState, 1
+ }
+ case 2:
+ if s1 < locb || 0x9F < s1 {
+ return runeErrorState, 1
+ }
+ case 3:
+ if s1 < 0x90 || hicb < s1 {
+ return runeErrorState, 1
+ }
+ case 4:
+ if s1 < locb || 0x8F < s1 {
+ return runeErrorState, 1
+ }
+ }
+ if sz <= 2 {
+ return validUTF8State, 2
+ }
+ s2 := s[2]
+ if s2 < locb || hicb < s2 {
+ return runeErrorState, 1
+ }
+ if sz <= 3 {
+ // separator character prefixes: [2]byte{226, 128}
+ if s0 == 226 && s1 == 128 {
+ switch s2 {
+ case lineSep:
+ return lineSepState, 3
+ case paragraphSep:
+ return paragraphSepState, 3
+ }
+ }
+ return validUTF8State, 3
+ }
+ s3 := s[3]
+ if s3 < locb || hicb < s3 {
+ return runeErrorState, 1
+ }
+ return validUTF8State, 4
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/encoder.go b/vendor/github.com/goccy/go-json/internal/encoder/encoder.go
new file mode 100644
index 00000000..14eb6a0d
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/encoder.go
@@ -0,0 +1,596 @@
+package encoder
+
+import (
+ "bytes"
+ "encoding"
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "math"
+ "reflect"
+ "strconv"
+ "strings"
+ "sync"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/errors"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+func (t OpType) IsMultipleOpHead() bool {
+ switch t {
+ case OpStructHead:
+ return true
+ case OpStructHeadSlice:
+ return true
+ case OpStructHeadArray:
+ return true
+ case OpStructHeadMap:
+ return true
+ case OpStructHeadStruct:
+ return true
+ case OpStructHeadOmitEmpty:
+ return true
+ case OpStructHeadOmitEmptySlice:
+ return true
+ case OpStructHeadOmitEmptyArray:
+ return true
+ case OpStructHeadOmitEmptyMap:
+ return true
+ case OpStructHeadOmitEmptyStruct:
+ return true
+ case OpStructHeadSlicePtr:
+ return true
+ case OpStructHeadOmitEmptySlicePtr:
+ return true
+ case OpStructHeadArrayPtr:
+ return true
+ case OpStructHeadOmitEmptyArrayPtr:
+ return true
+ case OpStructHeadMapPtr:
+ return true
+ case OpStructHeadOmitEmptyMapPtr:
+ return true
+ }
+ return false
+}
+
+func (t OpType) IsMultipleOpField() bool {
+ switch t {
+ case OpStructField:
+ return true
+ case OpStructFieldSlice:
+ return true
+ case OpStructFieldArray:
+ return true
+ case OpStructFieldMap:
+ return true
+ case OpStructFieldStruct:
+ return true
+ case OpStructFieldOmitEmpty:
+ return true
+ case OpStructFieldOmitEmptySlice:
+ return true
+ case OpStructFieldOmitEmptyArray:
+ return true
+ case OpStructFieldOmitEmptyMap:
+ return true
+ case OpStructFieldOmitEmptyStruct:
+ return true
+ case OpStructFieldSlicePtr:
+ return true
+ case OpStructFieldOmitEmptySlicePtr:
+ return true
+ case OpStructFieldArrayPtr:
+ return true
+ case OpStructFieldOmitEmptyArrayPtr:
+ return true
+ case OpStructFieldMapPtr:
+ return true
+ case OpStructFieldOmitEmptyMapPtr:
+ return true
+ }
+ return false
+}
+
+type OpcodeSet struct {
+ Type *runtime.Type
+ NoescapeKeyCode *Opcode
+ EscapeKeyCode *Opcode
+ InterfaceNoescapeKeyCode *Opcode
+ InterfaceEscapeKeyCode *Opcode
+ CodeLength int
+ EndCode *Opcode
+ Code Code
+ QueryCache map[string]*OpcodeSet
+ cacheMu sync.RWMutex
+}
+
+func (s *OpcodeSet) getQueryCache(hash string) *OpcodeSet {
+ s.cacheMu.RLock()
+ codeSet := s.QueryCache[hash]
+ s.cacheMu.RUnlock()
+ return codeSet
+}
+
+func (s *OpcodeSet) setQueryCache(hash string, codeSet *OpcodeSet) {
+ s.cacheMu.Lock()
+ s.QueryCache[hash] = codeSet
+ s.cacheMu.Unlock()
+}
+
+type CompiledCode struct {
+ Code *Opcode
+ Linked bool // whether recursive code already have linked
+ CurLen uintptr
+ NextLen uintptr
+}
+
+const StartDetectingCyclesAfter = 1000
+
+func Load(base uintptr, idx uintptr) uintptr {
+ addr := base + idx
+ return **(**uintptr)(unsafe.Pointer(&addr))
+}
+
+func Store(base uintptr, idx uintptr, p uintptr) {
+ addr := base + idx
+ **(**uintptr)(unsafe.Pointer(&addr)) = p
+}
+
+func LoadNPtr(base uintptr, idx uintptr, ptrNum int) uintptr {
+ addr := base + idx
+ p := **(**uintptr)(unsafe.Pointer(&addr))
+ if p == 0 {
+ return 0
+ }
+ return PtrToPtr(p)
+ /*
+ for i := 0; i < ptrNum; i++ {
+ if p == 0 {
+ return p
+ }
+ p = PtrToPtr(p)
+ }
+ return p
+ */
+}
+
+func PtrToUint64(p uintptr) uint64 { return **(**uint64)(unsafe.Pointer(&p)) }
+func PtrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) }
+func PtrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) }
+func PtrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) }
+func PtrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) }
+func PtrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) }
+func PtrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) }
+func PtrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) }
+func PtrToPtr(p uintptr) uintptr {
+ return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
+}
+func PtrToNPtr(p uintptr, ptrNum int) uintptr {
+ for i := 0; i < ptrNum; i++ {
+ if p == 0 {
+ return 0
+ }
+ p = PtrToPtr(p)
+ }
+ return p
+}
+
+func PtrToUnsafePtr(p uintptr) unsafe.Pointer {
+ return *(*unsafe.Pointer)(unsafe.Pointer(&p))
+}
+func PtrToInterface(code *Opcode, p uintptr) interface{} {
+ return *(*interface{})(unsafe.Pointer(&emptyInterface{
+ typ: code.Type,
+ ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
+ }))
+}
+
+func ErrUnsupportedValue(code *Opcode, ptr uintptr) *errors.UnsupportedValueError {
+ v := *(*interface{})(unsafe.Pointer(&emptyInterface{
+ typ: code.Type,
+ ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)),
+ }))
+ return &errors.UnsupportedValueError{
+ Value: reflect.ValueOf(v),
+ Str: fmt.Sprintf("encountered a cycle via %s", code.Type),
+ }
+}
+
+func ErrUnsupportedFloat(v float64) *errors.UnsupportedValueError {
+ return &errors.UnsupportedValueError{
+ Value: reflect.ValueOf(v),
+ Str: strconv.FormatFloat(v, 'g', -1, 64),
+ }
+}
+
+func ErrMarshalerWithCode(code *Opcode, err error) *errors.MarshalerError {
+ return &errors.MarshalerError{
+ Type: runtime.RType2Type(code.Type),
+ Err: err,
+ }
+}
+
+type emptyInterface struct {
+ typ *runtime.Type
+ ptr unsafe.Pointer
+}
+
+type MapItem struct {
+ Key []byte
+ Value []byte
+}
+
+type Mapslice struct {
+ Items []MapItem
+}
+
+func (m *Mapslice) Len() int {
+ return len(m.Items)
+}
+
+func (m *Mapslice) Less(i, j int) bool {
+ return bytes.Compare(m.Items[i].Key, m.Items[j].Key) < 0
+}
+
+func (m *Mapslice) Swap(i, j int) {
+ m.Items[i], m.Items[j] = m.Items[j], m.Items[i]
+}
+
+//nolint:structcheck,unused
+type mapIter struct {
+ key unsafe.Pointer
+ elem unsafe.Pointer
+ t unsafe.Pointer
+ h unsafe.Pointer
+ buckets unsafe.Pointer
+ bptr unsafe.Pointer
+ overflow unsafe.Pointer
+ oldoverflow unsafe.Pointer
+ startBucket uintptr
+ offset uint8
+ wrapped bool
+ B uint8
+ i uint8
+ bucket uintptr
+ checkBucket uintptr
+}
+
+type MapContext struct {
+ Start int
+ First int
+ Idx int
+ Slice *Mapslice
+ Buf []byte
+ Len int
+ Iter mapIter
+}
+
+var mapContextPool = sync.Pool{
+ New: func() interface{} {
+ return &MapContext{
+ Slice: &Mapslice{},
+ }
+ },
+}
+
+func NewMapContext(mapLen int, unorderedMap bool) *MapContext {
+ ctx := mapContextPool.Get().(*MapContext)
+ if !unorderedMap {
+ if len(ctx.Slice.Items) < mapLen {
+ ctx.Slice.Items = make([]MapItem, mapLen)
+ } else {
+ ctx.Slice.Items = ctx.Slice.Items[:mapLen]
+ }
+ }
+ ctx.Buf = ctx.Buf[:0]
+ ctx.Iter = mapIter{}
+ ctx.Idx = 0
+ ctx.Len = mapLen
+ return ctx
+}
+
+func ReleaseMapContext(c *MapContext) {
+ mapContextPool.Put(c)
+}
+
+//go:linkname MapIterInit runtime.mapiterinit
+//go:noescape
+func MapIterInit(mapType *runtime.Type, m unsafe.Pointer, it *mapIter)
+
+//go:linkname MapIterKey reflect.mapiterkey
+//go:noescape
+func MapIterKey(it *mapIter) unsafe.Pointer
+
+//go:linkname MapIterNext reflect.mapiternext
+//go:noescape
+func MapIterNext(it *mapIter)
+
+//go:linkname MapLen reflect.maplen
+//go:noescape
+func MapLen(m unsafe.Pointer) int
+
+func AppendByteSlice(_ *RuntimeContext, b []byte, src []byte) []byte {
+ if src == nil {
+ return append(b, `null`...)
+ }
+ encodedLen := base64.StdEncoding.EncodedLen(len(src))
+ b = append(b, '"')
+ pos := len(b)
+ remainLen := cap(b[pos:])
+ var buf []byte
+ if remainLen > encodedLen {
+ buf = b[pos : pos+encodedLen]
+ } else {
+ buf = make([]byte, encodedLen)
+ }
+ base64.StdEncoding.Encode(buf, src)
+ return append(append(b, buf...), '"')
+}
+
+func AppendFloat32(_ *RuntimeContext, b []byte, v float32) []byte {
+ f64 := float64(v)
+ abs := math.Abs(f64)
+ fmt := byte('f')
+ // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
+ if abs != 0 {
+ f32 := float32(abs)
+ if f32 < 1e-6 || f32 >= 1e21 {
+ fmt = 'e'
+ }
+ }
+ return strconv.AppendFloat(b, f64, fmt, -1, 32)
+}
+
+func AppendFloat64(_ *RuntimeContext, b []byte, v float64) []byte {
+ abs := math.Abs(v)
+ fmt := byte('f')
+ // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
+ if abs != 0 {
+ if abs < 1e-6 || abs >= 1e21 {
+ fmt = 'e'
+ }
+ }
+ return strconv.AppendFloat(b, v, fmt, -1, 64)
+}
+
+func AppendBool(_ *RuntimeContext, b []byte, v bool) []byte {
+ if v {
+ return append(b, "true"...)
+ }
+ return append(b, "false"...)
+}
+
+var (
+ floatTable = [256]bool{
+ '0': true,
+ '1': true,
+ '2': true,
+ '3': true,
+ '4': true,
+ '5': true,
+ '6': true,
+ '7': true,
+ '8': true,
+ '9': true,
+ '.': true,
+ 'e': true,
+ 'E': true,
+ '+': true,
+ '-': true,
+ }
+)
+
+func AppendNumber(_ *RuntimeContext, b []byte, n json.Number) ([]byte, error) {
+ if len(n) == 0 {
+ return append(b, '0'), nil
+ }
+ for i := 0; i < len(n); i++ {
+ if !floatTable[n[i]] {
+ return nil, fmt.Errorf("json: invalid number literal %q", n)
+ }
+ }
+ b = append(b, n...)
+ return b, nil
+}
+
+func AppendMarshalJSON(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) {
+ rv := reflect.ValueOf(v) // convert by dynamic interface type
+ if (code.Flags & AddrForMarshalerFlags) != 0 {
+ if rv.CanAddr() {
+ rv = rv.Addr()
+ } else {
+ newV := reflect.New(rv.Type())
+ newV.Elem().Set(rv)
+ rv = newV
+ }
+ }
+ v = rv.Interface()
+ var bb []byte
+ if (code.Flags & MarshalerContextFlags) != 0 {
+ marshaler, ok := v.(marshalerContext)
+ if !ok {
+ return AppendNull(ctx, b), nil
+ }
+ stdctx := ctx.Option.Context
+ if ctx.Option.Flag&FieldQueryOption != 0 {
+ stdctx = SetFieldQueryToContext(stdctx, code.FieldQuery)
+ }
+ b, err := marshaler.MarshalJSON(stdctx)
+ if err != nil {
+ return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
+ }
+ bb = b
+ } else {
+ marshaler, ok := v.(json.Marshaler)
+ if !ok {
+ return AppendNull(ctx, b), nil
+ }
+ b, err := marshaler.MarshalJSON()
+ if err != nil {
+ return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
+ }
+ bb = b
+ }
+ marshalBuf := ctx.MarshalBuf[:0]
+ marshalBuf = append(append(marshalBuf, bb...), nul)
+ compactedBuf, err := compact(b, marshalBuf, (ctx.Option.Flag&HTMLEscapeOption) != 0)
+ if err != nil {
+ return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
+ }
+ ctx.MarshalBuf = marshalBuf
+ return compactedBuf, nil
+}
+
+func AppendMarshalJSONIndent(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) {
+ rv := reflect.ValueOf(v) // convert by dynamic interface type
+ if (code.Flags & AddrForMarshalerFlags) != 0 {
+ if rv.CanAddr() {
+ rv = rv.Addr()
+ } else {
+ newV := reflect.New(rv.Type())
+ newV.Elem().Set(rv)
+ rv = newV
+ }
+ }
+ v = rv.Interface()
+ var bb []byte
+ if (code.Flags & MarshalerContextFlags) != 0 {
+ marshaler, ok := v.(marshalerContext)
+ if !ok {
+ return AppendNull(ctx, b), nil
+ }
+ b, err := marshaler.MarshalJSON(ctx.Option.Context)
+ if err != nil {
+ return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
+ }
+ bb = b
+ } else {
+ marshaler, ok := v.(json.Marshaler)
+ if !ok {
+ return AppendNull(ctx, b), nil
+ }
+ b, err := marshaler.MarshalJSON()
+ if err != nil {
+ return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
+ }
+ bb = b
+ }
+ marshalBuf := ctx.MarshalBuf[:0]
+ marshalBuf = append(append(marshalBuf, bb...), nul)
+ indentedBuf, err := doIndent(
+ b,
+ marshalBuf,
+ string(ctx.Prefix)+strings.Repeat(string(ctx.IndentStr), int(ctx.BaseIndent+code.Indent)),
+ string(ctx.IndentStr),
+ (ctx.Option.Flag&HTMLEscapeOption) != 0,
+ )
+ if err != nil {
+ return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
+ }
+ ctx.MarshalBuf = marshalBuf
+ return indentedBuf, nil
+}
+
+func AppendMarshalText(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) {
+ rv := reflect.ValueOf(v) // convert by dynamic interface type
+ if (code.Flags & AddrForMarshalerFlags) != 0 {
+ if rv.CanAddr() {
+ rv = rv.Addr()
+ } else {
+ newV := reflect.New(rv.Type())
+ newV.Elem().Set(rv)
+ rv = newV
+ }
+ }
+ v = rv.Interface()
+ marshaler, ok := v.(encoding.TextMarshaler)
+ if !ok {
+ return AppendNull(ctx, b), nil
+ }
+ bytes, err := marshaler.MarshalText()
+ if err != nil {
+ return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
+ }
+ return AppendString(ctx, b, *(*string)(unsafe.Pointer(&bytes))), nil
+}
+
+func AppendMarshalTextIndent(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) {
+ rv := reflect.ValueOf(v) // convert by dynamic interface type
+ if (code.Flags & AddrForMarshalerFlags) != 0 {
+ if rv.CanAddr() {
+ rv = rv.Addr()
+ } else {
+ newV := reflect.New(rv.Type())
+ newV.Elem().Set(rv)
+ rv = newV
+ }
+ }
+ v = rv.Interface()
+ marshaler, ok := v.(encoding.TextMarshaler)
+ if !ok {
+ return AppendNull(ctx, b), nil
+ }
+ bytes, err := marshaler.MarshalText()
+ if err != nil {
+ return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err}
+ }
+ return AppendString(ctx, b, *(*string)(unsafe.Pointer(&bytes))), nil
+}
+
+func AppendNull(_ *RuntimeContext, b []byte) []byte {
+ return append(b, "null"...)
+}
+
+func AppendComma(_ *RuntimeContext, b []byte) []byte {
+ return append(b, ',')
+}
+
+func AppendCommaIndent(_ *RuntimeContext, b []byte) []byte {
+ return append(b, ',', '\n')
+}
+
+func AppendStructEnd(_ *RuntimeContext, b []byte) []byte {
+ return append(b, '}', ',')
+}
+
+func AppendStructEndIndent(ctx *RuntimeContext, code *Opcode, b []byte) []byte {
+ b = append(b, '\n')
+ b = append(b, ctx.Prefix...)
+ indentNum := ctx.BaseIndent + code.Indent - 1
+ for i := uint32(0); i < indentNum; i++ {
+ b = append(b, ctx.IndentStr...)
+ }
+ return append(b, '}', ',', '\n')
+}
+
+func AppendIndent(ctx *RuntimeContext, b []byte, indent uint32) []byte {
+ b = append(b, ctx.Prefix...)
+ indentNum := ctx.BaseIndent + indent
+ for i := uint32(0); i < indentNum; i++ {
+ b = append(b, ctx.IndentStr...)
+ }
+ return b
+}
+
+func IsNilForMarshaler(v interface{}) bool {
+ rv := reflect.ValueOf(v)
+ switch rv.Kind() {
+ case reflect.Bool:
+ return !rv.Bool()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return rv.Int() == 0
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return rv.Uint() == 0
+ case reflect.Float32, reflect.Float64:
+ return math.Float64bits(rv.Float()) == 0
+ case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Func:
+ return rv.IsNil()
+ case reflect.Slice:
+ return rv.IsNil() || rv.Len() == 0
+ case reflect.String:
+ return rv.Len() == 0
+ }
+ return false
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/indent.go b/vendor/github.com/goccy/go-json/internal/encoder/indent.go
new file mode 100644
index 00000000..dfe04b5e
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/indent.go
@@ -0,0 +1,211 @@
+package encoder
+
+import (
+ "bytes"
+ "fmt"
+
+ "github.com/goccy/go-json/internal/errors"
+)
+
+func takeIndentSrcRuntimeContext(src []byte) (*RuntimeContext, []byte) {
+ ctx := TakeRuntimeContext()
+ buf := ctx.Buf[:0]
+ buf = append(append(buf, src...), nul)
+ ctx.Buf = buf
+ return ctx, buf
+}
+
+func Indent(buf *bytes.Buffer, src []byte, prefix, indentStr string) error {
+ if len(src) == 0 {
+ return errors.ErrUnexpectedEndOfJSON("", 0)
+ }
+
+ srcCtx, srcBuf := takeIndentSrcRuntimeContext(src)
+ dstCtx := TakeRuntimeContext()
+ dst := dstCtx.Buf[:0]
+
+ dst, err := indentAndWrite(buf, dst, srcBuf, prefix, indentStr)
+ if err != nil {
+ ReleaseRuntimeContext(srcCtx)
+ ReleaseRuntimeContext(dstCtx)
+ return err
+ }
+ dstCtx.Buf = dst
+ ReleaseRuntimeContext(srcCtx)
+ ReleaseRuntimeContext(dstCtx)
+ return nil
+}
+
+func indentAndWrite(buf *bytes.Buffer, dst []byte, src []byte, prefix, indentStr string) ([]byte, error) {
+ dst, err := doIndent(dst, src, prefix, indentStr, false)
+ if err != nil {
+ return nil, err
+ }
+ if _, err := buf.Write(dst); err != nil {
+ return nil, err
+ }
+ return dst, nil
+}
+
+func doIndent(dst, src []byte, prefix, indentStr string, escape bool) ([]byte, error) {
+ buf, cursor, err := indentValue(dst, src, 0, 0, []byte(prefix), []byte(indentStr), escape)
+ if err != nil {
+ return nil, err
+ }
+ if err := validateEndBuf(src, cursor); err != nil {
+ return nil, err
+ }
+ return buf, nil
+}
+
+func indentValue(
+ dst []byte,
+ src []byte,
+ indentNum int,
+ cursor int64,
+ prefix []byte,
+ indentBytes []byte,
+ escape bool) ([]byte, int64, error) {
+ for {
+ switch src[cursor] {
+ case ' ', '\t', '\n', '\r':
+ cursor++
+ continue
+ case '{':
+ return indentObject(dst, src, indentNum, cursor, prefix, indentBytes, escape)
+ case '}':
+ return nil, 0, errors.ErrSyntax("unexpected character '}'", cursor)
+ case '[':
+ return indentArray(dst, src, indentNum, cursor, prefix, indentBytes, escape)
+ case ']':
+ return nil, 0, errors.ErrSyntax("unexpected character ']'", cursor)
+ case '"':
+ return compactString(dst, src, cursor, escape)
+ case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return compactNumber(dst, src, cursor)
+ case 't':
+ return compactTrue(dst, src, cursor)
+ case 'f':
+ return compactFalse(dst, src, cursor)
+ case 'n':
+ return compactNull(dst, src, cursor)
+ default:
+ return nil, 0, errors.ErrSyntax(fmt.Sprintf("unexpected character '%c'", src[cursor]), cursor)
+ }
+ }
+}
+
+func indentObject(
+ dst []byte,
+ src []byte,
+ indentNum int,
+ cursor int64,
+ prefix []byte,
+ indentBytes []byte,
+ escape bool) ([]byte, int64, error) {
+ if src[cursor] == '{' {
+ dst = append(dst, '{')
+ } else {
+ return nil, 0, errors.ErrExpected("expected { character for object value", cursor)
+ }
+ cursor = skipWhiteSpace(src, cursor+1)
+ if src[cursor] == '}' {
+ dst = append(dst, '}')
+ return dst, cursor + 1, nil
+ }
+ indentNum++
+ var err error
+ for {
+ dst = append(append(dst, '\n'), prefix...)
+ for i := 0; i < indentNum; i++ {
+ dst = append(dst, indentBytes...)
+ }
+ cursor = skipWhiteSpace(src, cursor)
+ dst, cursor, err = compactString(dst, src, cursor, escape)
+ if err != nil {
+ return nil, 0, err
+ }
+ cursor = skipWhiteSpace(src, cursor)
+ if src[cursor] != ':' {
+ return nil, 0, errors.ErrSyntax(
+ fmt.Sprintf("invalid character '%c' after object key", src[cursor]),
+ cursor+1,
+ )
+ }
+ dst = append(dst, ':', ' ')
+ dst, cursor, err = indentValue(dst, src, indentNum, cursor+1, prefix, indentBytes, escape)
+ if err != nil {
+ return nil, 0, err
+ }
+ cursor = skipWhiteSpace(src, cursor)
+ switch src[cursor] {
+ case '}':
+ dst = append(append(dst, '\n'), prefix...)
+ for i := 0; i < indentNum-1; i++ {
+ dst = append(dst, indentBytes...)
+ }
+ dst = append(dst, '}')
+ cursor++
+ return dst, cursor, nil
+ case ',':
+ dst = append(dst, ',')
+ default:
+ return nil, 0, errors.ErrSyntax(
+ fmt.Sprintf("invalid character '%c' after object key:value pair", src[cursor]),
+ cursor+1,
+ )
+ }
+ cursor++
+ }
+}
+
+func indentArray(
+ dst []byte,
+ src []byte,
+ indentNum int,
+ cursor int64,
+ prefix []byte,
+ indentBytes []byte,
+ escape bool) ([]byte, int64, error) {
+ if src[cursor] == '[' {
+ dst = append(dst, '[')
+ } else {
+ return nil, 0, errors.ErrExpected("expected [ character for array value", cursor)
+ }
+ cursor = skipWhiteSpace(src, cursor+1)
+ if src[cursor] == ']' {
+ dst = append(dst, ']')
+ return dst, cursor + 1, nil
+ }
+ indentNum++
+ var err error
+ for {
+ dst = append(append(dst, '\n'), prefix...)
+ for i := 0; i < indentNum; i++ {
+ dst = append(dst, indentBytes...)
+ }
+ dst, cursor, err = indentValue(dst, src, indentNum, cursor, prefix, indentBytes, escape)
+ if err != nil {
+ return nil, 0, err
+ }
+ cursor = skipWhiteSpace(src, cursor)
+ switch src[cursor] {
+ case ']':
+ dst = append(append(dst, '\n'), prefix...)
+ for i := 0; i < indentNum-1; i++ {
+ dst = append(dst, indentBytes...)
+ }
+ dst = append(dst, ']')
+ cursor++
+ return dst, cursor, nil
+ case ',':
+ dst = append(dst, ',')
+ default:
+ return nil, 0, errors.ErrSyntax(
+ fmt.Sprintf("invalid character '%c' after array value", src[cursor]),
+ cursor+1,
+ )
+ }
+ cursor++
+ }
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/int.go b/vendor/github.com/goccy/go-json/internal/encoder/int.go
new file mode 100644
index 00000000..8b5febea
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/int.go
@@ -0,0 +1,176 @@
+// This files's processing codes are inspired by https://github.com/segmentio/encoding.
+// The license notation is as follows.
+//
+// # MIT License
+//
+// Copyright (c) 2019 Segment.io, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+package encoder
+
+import (
+ "unsafe"
+)
+
+var endianness int
+
+func init() {
+ var b [2]byte
+ *(*uint16)(unsafe.Pointer(&b)) = uint16(0xABCD)
+
+ switch b[0] {
+ case 0xCD:
+ endianness = 0 // LE
+ case 0xAB:
+ endianness = 1 // BE
+ default:
+ panic("could not determine endianness")
+ }
+}
+
+// "00010203...96979899" cast to []uint16
+var intLELookup = [100]uint16{
+ 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530, 0x3630, 0x3730, 0x3830, 0x3930,
+ 0x3031, 0x3131, 0x3231, 0x3331, 0x3431, 0x3531, 0x3631, 0x3731, 0x3831, 0x3931,
+ 0x3032, 0x3132, 0x3232, 0x3332, 0x3432, 0x3532, 0x3632, 0x3732, 0x3832, 0x3932,
+ 0x3033, 0x3133, 0x3233, 0x3333, 0x3433, 0x3533, 0x3633, 0x3733, 0x3833, 0x3933,
+ 0x3034, 0x3134, 0x3234, 0x3334, 0x3434, 0x3534, 0x3634, 0x3734, 0x3834, 0x3934,
+ 0x3035, 0x3135, 0x3235, 0x3335, 0x3435, 0x3535, 0x3635, 0x3735, 0x3835, 0x3935,
+ 0x3036, 0x3136, 0x3236, 0x3336, 0x3436, 0x3536, 0x3636, 0x3736, 0x3836, 0x3936,
+ 0x3037, 0x3137, 0x3237, 0x3337, 0x3437, 0x3537, 0x3637, 0x3737, 0x3837, 0x3937,
+ 0x3038, 0x3138, 0x3238, 0x3338, 0x3438, 0x3538, 0x3638, 0x3738, 0x3838, 0x3938,
+ 0x3039, 0x3139, 0x3239, 0x3339, 0x3439, 0x3539, 0x3639, 0x3739, 0x3839, 0x3939,
+}
+
+var intBELookup = [100]uint16{
+ 0x3030, 0x3031, 0x3032, 0x3033, 0x3034, 0x3035, 0x3036, 0x3037, 0x3038, 0x3039,
+ 0x3130, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3138, 0x3139,
+ 0x3230, 0x3231, 0x3232, 0x3233, 0x3234, 0x3235, 0x3236, 0x3237, 0x3238, 0x3239,
+ 0x3330, 0x3331, 0x3332, 0x3333, 0x3334, 0x3335, 0x3336, 0x3337, 0x3338, 0x3339,
+ 0x3430, 0x3431, 0x3432, 0x3433, 0x3434, 0x3435, 0x3436, 0x3437, 0x3438, 0x3439,
+ 0x3530, 0x3531, 0x3532, 0x3533, 0x3534, 0x3535, 0x3536, 0x3537, 0x3538, 0x3539,
+ 0x3630, 0x3631, 0x3632, 0x3633, 0x3634, 0x3635, 0x3636, 0x3637, 0x3638, 0x3639,
+ 0x3730, 0x3731, 0x3732, 0x3733, 0x3734, 0x3735, 0x3736, 0x3737, 0x3738, 0x3739,
+ 0x3830, 0x3831, 0x3832, 0x3833, 0x3834, 0x3835, 0x3836, 0x3837, 0x3838, 0x3839,
+ 0x3930, 0x3931, 0x3932, 0x3933, 0x3934, 0x3935, 0x3936, 0x3937, 0x3938, 0x3939,
+}
+
+var intLookup = [2]*[100]uint16{&intLELookup, &intBELookup}
+
+func numMask(numBitSize uint8) uint64 {
+ return 1<>(code.NumBitSize-1))&1 == 1
+ if !negative {
+ if n < 10 {
+ return append(out, byte(n+'0'))
+ } else if n < 100 {
+ u := intLELookup[n]
+ return append(out, byte(u), byte(u>>8))
+ }
+ } else {
+ n = -n & mask
+ }
+
+ lookup := intLookup[endianness]
+
+ var b [22]byte
+ u := (*[11]uint16)(unsafe.Pointer(&b))
+ i := 11
+
+ for n >= 100 {
+ j := n % 100
+ n /= 100
+ i--
+ u[i] = lookup[j]
+ }
+
+ i--
+ u[i] = lookup[n]
+
+ i *= 2 // convert to byte index
+ if n < 10 {
+ i++ // remove leading zero
+ }
+ if negative {
+ i--
+ b[i] = '-'
+ }
+
+ return append(out, b[i:]...)
+}
+
+func AppendUint(_ *RuntimeContext, out []byte, p uintptr, code *Opcode) []byte {
+ var u64 uint64
+ switch code.NumBitSize {
+ case 8:
+ u64 = (uint64)(**(**uint8)(unsafe.Pointer(&p)))
+ case 16:
+ u64 = (uint64)(**(**uint16)(unsafe.Pointer(&p)))
+ case 32:
+ u64 = (uint64)(**(**uint32)(unsafe.Pointer(&p)))
+ case 64:
+ u64 = **(**uint64)(unsafe.Pointer(&p))
+ }
+ mask := numMask(code.NumBitSize)
+ n := u64 & mask
+ if n < 10 {
+ return append(out, byte(n+'0'))
+ } else if n < 100 {
+ u := intLELookup[n]
+ return append(out, byte(u), byte(u>>8))
+ }
+
+ lookup := intLookup[endianness]
+
+ var b [22]byte
+ u := (*[11]uint16)(unsafe.Pointer(&b))
+ i := 11
+
+ for n >= 100 {
+ j := n % 100
+ n /= 100
+ i--
+ u[i] = lookup[j]
+ }
+
+ i--
+ u[i] = lookup[n]
+
+ i *= 2 // convert to byte index
+ if n < 10 {
+ i++ // remove leading zero
+ }
+ return append(out, b[i:]...)
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/map112.go b/vendor/github.com/goccy/go-json/internal/encoder/map112.go
new file mode 100644
index 00000000..e96ffadf
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/map112.go
@@ -0,0 +1,9 @@
+//go:build !go1.13
+// +build !go1.13
+
+package encoder
+
+import "unsafe"
+
+//go:linkname MapIterValue reflect.mapitervalue
+func MapIterValue(it *mapIter) unsafe.Pointer
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/map113.go b/vendor/github.com/goccy/go-json/internal/encoder/map113.go
new file mode 100644
index 00000000..9b69dcc3
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/map113.go
@@ -0,0 +1,9 @@
+//go:build go1.13
+// +build go1.13
+
+package encoder
+
+import "unsafe"
+
+//go:linkname MapIterValue reflect.mapiterelem
+func MapIterValue(it *mapIter) unsafe.Pointer
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/opcode.go b/vendor/github.com/goccy/go-json/internal/encoder/opcode.go
new file mode 100644
index 00000000..df22f554
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/opcode.go
@@ -0,0 +1,752 @@
+package encoder
+
+import (
+ "bytes"
+ "fmt"
+ "sort"
+ "strings"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+const uintptrSize = 4 << (^uintptr(0) >> 63)
+
+type OpFlags uint16
+
+const (
+ AnonymousHeadFlags OpFlags = 1 << 0
+ AnonymousKeyFlags OpFlags = 1 << 1
+ IndirectFlags OpFlags = 1 << 2
+ IsTaggedKeyFlags OpFlags = 1 << 3
+ NilCheckFlags OpFlags = 1 << 4
+ AddrForMarshalerFlags OpFlags = 1 << 5
+ IsNextOpPtrTypeFlags OpFlags = 1 << 6
+ IsNilableTypeFlags OpFlags = 1 << 7
+ MarshalerContextFlags OpFlags = 1 << 8
+ NonEmptyInterfaceFlags OpFlags = 1 << 9
+)
+
+type Opcode struct {
+ Op OpType // operation type
+ Idx uint32 // offset to access ptr
+ Next *Opcode // next opcode
+ End *Opcode // array/slice/struct/map end
+ NextField *Opcode // next struct field
+ Key string // struct field key
+ Offset uint32 // offset size from struct header
+ PtrNum uint8 // pointer number: e.g. double pointer is 2.
+ NumBitSize uint8
+ Flags OpFlags
+
+ Type *runtime.Type // go type
+ Jmp *CompiledCode // for recursive call
+ FieldQuery *FieldQuery // field query for Interface / MarshalJSON / MarshalText
+ ElemIdx uint32 // offset to access array/slice elem
+ Length uint32 // offset to access slice length or array length
+ Indent uint32 // indent number
+ Size uint32 // array/slice elem size
+ DisplayIdx uint32 // opcode index
+ DisplayKey string // key text to display
+}
+
+func (c *Opcode) Validate() error {
+ var prevIdx uint32
+ for code := c; !code.IsEnd(); {
+ if prevIdx != 0 {
+ if code.DisplayIdx != prevIdx+1 {
+ return fmt.Errorf(
+ "invalid index. previous display index is %d but next is %d. dump = %s",
+ prevIdx, code.DisplayIdx, c.Dump(),
+ )
+ }
+ }
+ prevIdx = code.DisplayIdx
+ code = code.IterNext()
+ }
+ return nil
+}
+
+func (c *Opcode) IterNext() *Opcode {
+ if c == nil {
+ return nil
+ }
+ switch c.Op.CodeType() {
+ case CodeArrayElem, CodeSliceElem, CodeMapKey:
+ return c.End
+ default:
+ return c.Next
+ }
+}
+
+func (c *Opcode) IsEnd() bool {
+ if c == nil {
+ return true
+ }
+ return c.Op == OpEnd || c.Op == OpInterfaceEnd || c.Op == OpRecursiveEnd
+}
+
+func (c *Opcode) MaxIdx() uint32 {
+ max := uint32(0)
+ for _, value := range []uint32{
+ c.Idx,
+ c.ElemIdx,
+ c.Length,
+ c.Size,
+ } {
+ if max < value {
+ max = value
+ }
+ }
+ return max
+}
+
+func (c *Opcode) ToHeaderType(isString bool) OpType {
+ switch c.Op {
+ case OpInt:
+ if isString {
+ return OpStructHeadIntString
+ }
+ return OpStructHeadInt
+ case OpIntPtr:
+ if isString {
+ return OpStructHeadIntPtrString
+ }
+ return OpStructHeadIntPtr
+ case OpUint:
+ if isString {
+ return OpStructHeadUintString
+ }
+ return OpStructHeadUint
+ case OpUintPtr:
+ if isString {
+ return OpStructHeadUintPtrString
+ }
+ return OpStructHeadUintPtr
+ case OpFloat32:
+ if isString {
+ return OpStructHeadFloat32String
+ }
+ return OpStructHeadFloat32
+ case OpFloat32Ptr:
+ if isString {
+ return OpStructHeadFloat32PtrString
+ }
+ return OpStructHeadFloat32Ptr
+ case OpFloat64:
+ if isString {
+ return OpStructHeadFloat64String
+ }
+ return OpStructHeadFloat64
+ case OpFloat64Ptr:
+ if isString {
+ return OpStructHeadFloat64PtrString
+ }
+ return OpStructHeadFloat64Ptr
+ case OpString:
+ if isString {
+ return OpStructHeadStringString
+ }
+ return OpStructHeadString
+ case OpStringPtr:
+ if isString {
+ return OpStructHeadStringPtrString
+ }
+ return OpStructHeadStringPtr
+ case OpNumber:
+ if isString {
+ return OpStructHeadNumberString
+ }
+ return OpStructHeadNumber
+ case OpNumberPtr:
+ if isString {
+ return OpStructHeadNumberPtrString
+ }
+ return OpStructHeadNumberPtr
+ case OpBool:
+ if isString {
+ return OpStructHeadBoolString
+ }
+ return OpStructHeadBool
+ case OpBoolPtr:
+ if isString {
+ return OpStructHeadBoolPtrString
+ }
+ return OpStructHeadBoolPtr
+ case OpBytes:
+ return OpStructHeadBytes
+ case OpBytesPtr:
+ return OpStructHeadBytesPtr
+ case OpMap:
+ return OpStructHeadMap
+ case OpMapPtr:
+ c.Op = OpMap
+ return OpStructHeadMapPtr
+ case OpArray:
+ return OpStructHeadArray
+ case OpArrayPtr:
+ c.Op = OpArray
+ return OpStructHeadArrayPtr
+ case OpSlice:
+ return OpStructHeadSlice
+ case OpSlicePtr:
+ c.Op = OpSlice
+ return OpStructHeadSlicePtr
+ case OpMarshalJSON:
+ return OpStructHeadMarshalJSON
+ case OpMarshalJSONPtr:
+ return OpStructHeadMarshalJSONPtr
+ case OpMarshalText:
+ return OpStructHeadMarshalText
+ case OpMarshalTextPtr:
+ return OpStructHeadMarshalTextPtr
+ }
+ return OpStructHead
+}
+
+func (c *Opcode) ToFieldType(isString bool) OpType {
+ switch c.Op {
+ case OpInt:
+ if isString {
+ return OpStructFieldIntString
+ }
+ return OpStructFieldInt
+ case OpIntPtr:
+ if isString {
+ return OpStructFieldIntPtrString
+ }
+ return OpStructFieldIntPtr
+ case OpUint:
+ if isString {
+ return OpStructFieldUintString
+ }
+ return OpStructFieldUint
+ case OpUintPtr:
+ if isString {
+ return OpStructFieldUintPtrString
+ }
+ return OpStructFieldUintPtr
+ case OpFloat32:
+ if isString {
+ return OpStructFieldFloat32String
+ }
+ return OpStructFieldFloat32
+ case OpFloat32Ptr:
+ if isString {
+ return OpStructFieldFloat32PtrString
+ }
+ return OpStructFieldFloat32Ptr
+ case OpFloat64:
+ if isString {
+ return OpStructFieldFloat64String
+ }
+ return OpStructFieldFloat64
+ case OpFloat64Ptr:
+ if isString {
+ return OpStructFieldFloat64PtrString
+ }
+ return OpStructFieldFloat64Ptr
+ case OpString:
+ if isString {
+ return OpStructFieldStringString
+ }
+ return OpStructFieldString
+ case OpStringPtr:
+ if isString {
+ return OpStructFieldStringPtrString
+ }
+ return OpStructFieldStringPtr
+ case OpNumber:
+ if isString {
+ return OpStructFieldNumberString
+ }
+ return OpStructFieldNumber
+ case OpNumberPtr:
+ if isString {
+ return OpStructFieldNumberPtrString
+ }
+ return OpStructFieldNumberPtr
+ case OpBool:
+ if isString {
+ return OpStructFieldBoolString
+ }
+ return OpStructFieldBool
+ case OpBoolPtr:
+ if isString {
+ return OpStructFieldBoolPtrString
+ }
+ return OpStructFieldBoolPtr
+ case OpBytes:
+ return OpStructFieldBytes
+ case OpBytesPtr:
+ return OpStructFieldBytesPtr
+ case OpMap:
+ return OpStructFieldMap
+ case OpMapPtr:
+ c.Op = OpMap
+ return OpStructFieldMapPtr
+ case OpArray:
+ return OpStructFieldArray
+ case OpArrayPtr:
+ c.Op = OpArray
+ return OpStructFieldArrayPtr
+ case OpSlice:
+ return OpStructFieldSlice
+ case OpSlicePtr:
+ c.Op = OpSlice
+ return OpStructFieldSlicePtr
+ case OpMarshalJSON:
+ return OpStructFieldMarshalJSON
+ case OpMarshalJSONPtr:
+ return OpStructFieldMarshalJSONPtr
+ case OpMarshalText:
+ return OpStructFieldMarshalText
+ case OpMarshalTextPtr:
+ return OpStructFieldMarshalTextPtr
+ }
+ return OpStructField
+}
+
+func newOpCode(ctx *compileContext, typ *runtime.Type, op OpType) *Opcode {
+ return newOpCodeWithNext(ctx, typ, op, newEndOp(ctx, typ))
+}
+
+func opcodeOffset(idx int) uint32 {
+ return uint32(idx) * uintptrSize
+}
+
+func getCodeAddrByIdx(head *Opcode, idx uint32) *Opcode {
+ addr := uintptr(unsafe.Pointer(head)) + uintptr(idx)*unsafe.Sizeof(Opcode{})
+ return *(**Opcode)(unsafe.Pointer(&addr))
+}
+
+func copyOpcode(code *Opcode) *Opcode {
+ codeNum := ToEndCode(code).DisplayIdx + 1
+ codeSlice := make([]Opcode, codeNum)
+ head := (*Opcode)((*runtime.SliceHeader)(unsafe.Pointer(&codeSlice)).Data)
+ ptr := head
+ c := code
+ for {
+ *ptr = Opcode{
+ Op: c.Op,
+ Key: c.Key,
+ PtrNum: c.PtrNum,
+ NumBitSize: c.NumBitSize,
+ Flags: c.Flags,
+ Idx: c.Idx,
+ Offset: c.Offset,
+ Type: c.Type,
+ FieldQuery: c.FieldQuery,
+ DisplayIdx: c.DisplayIdx,
+ DisplayKey: c.DisplayKey,
+ ElemIdx: c.ElemIdx,
+ Length: c.Length,
+ Size: c.Size,
+ Indent: c.Indent,
+ Jmp: c.Jmp,
+ }
+ if c.End != nil {
+ ptr.End = getCodeAddrByIdx(head, c.End.DisplayIdx)
+ }
+ if c.NextField != nil {
+ ptr.NextField = getCodeAddrByIdx(head, c.NextField.DisplayIdx)
+ }
+ if c.Next != nil {
+ ptr.Next = getCodeAddrByIdx(head, c.Next.DisplayIdx)
+ }
+ if c.IsEnd() {
+ break
+ }
+ ptr = getCodeAddrByIdx(head, c.DisplayIdx+1)
+ c = c.IterNext()
+ }
+ return head
+}
+
+func setTotalLengthToInterfaceOp(code *Opcode) {
+ for c := code; !c.IsEnd(); {
+ if c.Op == OpInterface || c.Op == OpInterfacePtr {
+ c.Length = uint32(code.TotalLength())
+ }
+ c = c.IterNext()
+ }
+}
+
+func ToEndCode(code *Opcode) *Opcode {
+ c := code
+ for !c.IsEnd() {
+ c = c.IterNext()
+ }
+ return c
+}
+
+func copyToInterfaceOpcode(code *Opcode) *Opcode {
+ copied := copyOpcode(code)
+ c := copied
+ c = ToEndCode(c)
+ c.Idx += uintptrSize
+ c.ElemIdx = c.Idx + uintptrSize
+ c.Length = c.Idx + 2*uintptrSize
+ c.Op = OpInterfaceEnd
+ return copied
+}
+
+func newOpCodeWithNext(ctx *compileContext, typ *runtime.Type, op OpType, next *Opcode) *Opcode {
+ return &Opcode{
+ Op: op,
+ Idx: opcodeOffset(ctx.ptrIndex),
+ Next: next,
+ Type: typ,
+ DisplayIdx: ctx.opcodeIndex,
+ Indent: ctx.indent,
+ }
+}
+
+func newEndOp(ctx *compileContext, typ *runtime.Type) *Opcode {
+ return newOpCodeWithNext(ctx, typ, OpEnd, nil)
+}
+
+func (c *Opcode) TotalLength() int {
+ var idx int
+ code := c
+ for !code.IsEnd() {
+ maxIdx := int(code.MaxIdx() / uintptrSize)
+ if idx < maxIdx {
+ idx = maxIdx
+ }
+ if code.Op == OpRecursiveEnd {
+ break
+ }
+ code = code.IterNext()
+ }
+ maxIdx := int(code.MaxIdx() / uintptrSize)
+ if idx < maxIdx {
+ idx = maxIdx
+ }
+ return idx + 1
+}
+
+func (c *Opcode) dumpHead(code *Opcode) string {
+ var length uint32
+ if code.Op.CodeType() == CodeArrayHead {
+ length = code.Length
+ } else {
+ length = code.Length / uintptrSize
+ }
+ return fmt.Sprintf(
+ `[%03d]%s%s ([idx:%d][elemIdx:%d][length:%d])`,
+ code.DisplayIdx,
+ strings.Repeat("-", int(code.Indent)),
+ code.Op,
+ code.Idx/uintptrSize,
+ code.ElemIdx/uintptrSize,
+ length,
+ )
+}
+
+func (c *Opcode) dumpMapHead(code *Opcode) string {
+ return fmt.Sprintf(
+ `[%03d]%s%s ([idx:%d])`,
+ code.DisplayIdx,
+ strings.Repeat("-", int(code.Indent)),
+ code.Op,
+ code.Idx/uintptrSize,
+ )
+}
+
+func (c *Opcode) dumpMapEnd(code *Opcode) string {
+ return fmt.Sprintf(
+ `[%03d]%s%s ([idx:%d])`,
+ code.DisplayIdx,
+ strings.Repeat("-", int(code.Indent)),
+ code.Op,
+ code.Idx/uintptrSize,
+ )
+}
+
+func (c *Opcode) dumpElem(code *Opcode) string {
+ var length uint32
+ if code.Op.CodeType() == CodeArrayElem {
+ length = code.Length
+ } else {
+ length = code.Length / uintptrSize
+ }
+ return fmt.Sprintf(
+ `[%03d]%s%s ([idx:%d][elemIdx:%d][length:%d][size:%d])`,
+ code.DisplayIdx,
+ strings.Repeat("-", int(code.Indent)),
+ code.Op,
+ code.Idx/uintptrSize,
+ code.ElemIdx/uintptrSize,
+ length,
+ code.Size,
+ )
+}
+
+func (c *Opcode) dumpField(code *Opcode) string {
+ return fmt.Sprintf(
+ `[%03d]%s%s ([idx:%d][key:%s][offset:%d])`,
+ code.DisplayIdx,
+ strings.Repeat("-", int(code.Indent)),
+ code.Op,
+ code.Idx/uintptrSize,
+ code.DisplayKey,
+ code.Offset,
+ )
+}
+
+func (c *Opcode) dumpKey(code *Opcode) string {
+ return fmt.Sprintf(
+ `[%03d]%s%s ([idx:%d])`,
+ code.DisplayIdx,
+ strings.Repeat("-", int(code.Indent)),
+ code.Op,
+ code.Idx/uintptrSize,
+ )
+}
+
+func (c *Opcode) dumpValue(code *Opcode) string {
+ return fmt.Sprintf(
+ `[%03d]%s%s ([idx:%d])`,
+ code.DisplayIdx,
+ strings.Repeat("-", int(code.Indent)),
+ code.Op,
+ code.Idx/uintptrSize,
+ )
+}
+
+func (c *Opcode) Dump() string {
+ codes := []string{}
+ for code := c; !code.IsEnd(); {
+ switch code.Op.CodeType() {
+ case CodeSliceHead:
+ codes = append(codes, c.dumpHead(code))
+ code = code.Next
+ case CodeMapHead:
+ codes = append(codes, c.dumpMapHead(code))
+ code = code.Next
+ case CodeArrayElem, CodeSliceElem:
+ codes = append(codes, c.dumpElem(code))
+ code = code.End
+ case CodeMapKey:
+ codes = append(codes, c.dumpKey(code))
+ code = code.End
+ case CodeMapValue:
+ codes = append(codes, c.dumpValue(code))
+ code = code.Next
+ case CodeMapEnd:
+ codes = append(codes, c.dumpMapEnd(code))
+ code = code.Next
+ case CodeStructField:
+ codes = append(codes, c.dumpField(code))
+ code = code.Next
+ case CodeStructEnd:
+ codes = append(codes, c.dumpField(code))
+ code = code.Next
+ default:
+ codes = append(codes, fmt.Sprintf(
+ "[%03d]%s%s ([idx:%d])",
+ code.DisplayIdx,
+ strings.Repeat("-", int(code.Indent)),
+ code.Op,
+ code.Idx/uintptrSize,
+ ))
+ code = code.Next
+ }
+ }
+ return strings.Join(codes, "\n")
+}
+
+func (c *Opcode) DumpDOT() string {
+ type edge struct {
+ from, to *Opcode
+ label string
+ weight int
+ }
+ var edges []edge
+
+ b := &bytes.Buffer{}
+ fmt.Fprintf(b, "digraph \"%p\" {\n", c.Type)
+ fmt.Fprintln(b, "mclimit=1.5;\nrankdir=TD;\nordering=out;\nnode[shape=box];")
+ for code := c; !code.IsEnd(); {
+ label := code.Op.String()
+ fmt.Fprintf(b, "\"%p\" [label=%q];\n", code, label)
+ if p := code.Next; p != nil {
+ edges = append(edges, edge{
+ from: code,
+ to: p,
+ label: "Next",
+ weight: 10,
+ })
+ }
+ if p := code.NextField; p != nil {
+ edges = append(edges, edge{
+ from: code,
+ to: p,
+ label: "NextField",
+ weight: 2,
+ })
+ }
+ if p := code.End; p != nil {
+ edges = append(edges, edge{
+ from: code,
+ to: p,
+ label: "End",
+ weight: 1,
+ })
+ }
+ if p := code.Jmp; p != nil {
+ edges = append(edges, edge{
+ from: code,
+ to: p.Code,
+ label: "Jmp",
+ weight: 1,
+ })
+ }
+
+ switch code.Op.CodeType() {
+ case CodeSliceHead:
+ code = code.Next
+ case CodeMapHead:
+ code = code.Next
+ case CodeArrayElem, CodeSliceElem:
+ code = code.End
+ case CodeMapKey:
+ code = code.End
+ case CodeMapValue:
+ code = code.Next
+ case CodeMapEnd:
+ code = code.Next
+ case CodeStructField:
+ code = code.Next
+ case CodeStructEnd:
+ code = code.Next
+ default:
+ code = code.Next
+ }
+ if code.IsEnd() {
+ fmt.Fprintf(b, "\"%p\" [label=%q];\n", code, code.Op.String())
+ }
+ }
+ sort.Slice(edges, func(i, j int) bool {
+ return edges[i].to.DisplayIdx < edges[j].to.DisplayIdx
+ })
+ for _, e := range edges {
+ fmt.Fprintf(b, "\"%p\" -> \"%p\" [label=%q][weight=%d];\n", e.from, e.to, e.label, e.weight)
+ }
+ fmt.Fprint(b, "}")
+ return b.String()
+}
+
+func newSliceHeaderCode(ctx *compileContext, typ *runtime.Type) *Opcode {
+ idx := opcodeOffset(ctx.ptrIndex)
+ ctx.incPtrIndex()
+ elemIdx := opcodeOffset(ctx.ptrIndex)
+ ctx.incPtrIndex()
+ length := opcodeOffset(ctx.ptrIndex)
+ return &Opcode{
+ Op: OpSlice,
+ Type: typ,
+ Idx: idx,
+ DisplayIdx: ctx.opcodeIndex,
+ ElemIdx: elemIdx,
+ Length: length,
+ Indent: ctx.indent,
+ }
+}
+
+func newSliceElemCode(ctx *compileContext, typ *runtime.Type, head *Opcode, size uintptr) *Opcode {
+ return &Opcode{
+ Op: OpSliceElem,
+ Type: typ,
+ Idx: head.Idx,
+ DisplayIdx: ctx.opcodeIndex,
+ ElemIdx: head.ElemIdx,
+ Length: head.Length,
+ Indent: ctx.indent,
+ Size: uint32(size),
+ }
+}
+
+func newArrayHeaderCode(ctx *compileContext, typ *runtime.Type, alen int) *Opcode {
+ idx := opcodeOffset(ctx.ptrIndex)
+ ctx.incPtrIndex()
+ elemIdx := opcodeOffset(ctx.ptrIndex)
+ return &Opcode{
+ Op: OpArray,
+ Type: typ,
+ Idx: idx,
+ DisplayIdx: ctx.opcodeIndex,
+ ElemIdx: elemIdx,
+ Indent: ctx.indent,
+ Length: uint32(alen),
+ }
+}
+
+func newArrayElemCode(ctx *compileContext, typ *runtime.Type, head *Opcode, length int, size uintptr) *Opcode {
+ return &Opcode{
+ Op: OpArrayElem,
+ Type: typ,
+ Idx: head.Idx,
+ DisplayIdx: ctx.opcodeIndex,
+ ElemIdx: head.ElemIdx,
+ Length: uint32(length),
+ Indent: ctx.indent,
+ Size: uint32(size),
+ }
+}
+
+func newMapHeaderCode(ctx *compileContext, typ *runtime.Type) *Opcode {
+ idx := opcodeOffset(ctx.ptrIndex)
+ ctx.incPtrIndex()
+ return &Opcode{
+ Op: OpMap,
+ Type: typ,
+ Idx: idx,
+ DisplayIdx: ctx.opcodeIndex,
+ Indent: ctx.indent,
+ }
+}
+
+func newMapKeyCode(ctx *compileContext, typ *runtime.Type, head *Opcode) *Opcode {
+ return &Opcode{
+ Op: OpMapKey,
+ Type: typ,
+ Idx: head.Idx,
+ DisplayIdx: ctx.opcodeIndex,
+ Indent: ctx.indent,
+ }
+}
+
+func newMapValueCode(ctx *compileContext, typ *runtime.Type, head *Opcode) *Opcode {
+ return &Opcode{
+ Op: OpMapValue,
+ Type: typ,
+ Idx: head.Idx,
+ DisplayIdx: ctx.opcodeIndex,
+ Indent: ctx.indent,
+ }
+}
+
+func newMapEndCode(ctx *compileContext, typ *runtime.Type, head *Opcode) *Opcode {
+ return &Opcode{
+ Op: OpMapEnd,
+ Type: typ,
+ Idx: head.Idx,
+ DisplayIdx: ctx.opcodeIndex,
+ Indent: ctx.indent,
+ Next: newEndOp(ctx, typ),
+ }
+}
+
+func newRecursiveCode(ctx *compileContext, typ *runtime.Type, jmp *CompiledCode) *Opcode {
+ return &Opcode{
+ Op: OpRecursive,
+ Type: typ,
+ Idx: opcodeOffset(ctx.ptrIndex),
+ Next: newEndOp(ctx, typ),
+ DisplayIdx: ctx.opcodeIndex,
+ Indent: ctx.indent,
+ Jmp: jmp,
+ }
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/option.go b/vendor/github.com/goccy/go-json/internal/encoder/option.go
new file mode 100644
index 00000000..12c58e46
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/option.go
@@ -0,0 +1,48 @@
+package encoder
+
+import (
+ "context"
+ "io"
+)
+
+type OptionFlag uint8
+
+const (
+ HTMLEscapeOption OptionFlag = 1 << iota
+ IndentOption
+ UnorderedMapOption
+ DebugOption
+ ColorizeOption
+ ContextOption
+ NormalizeUTF8Option
+ FieldQueryOption
+)
+
+type Option struct {
+ Flag OptionFlag
+ ColorScheme *ColorScheme
+ Context context.Context
+ DebugOut io.Writer
+ DebugDOTOut io.WriteCloser
+}
+
+type EncodeFormat struct {
+ Header string
+ Footer string
+}
+
+type EncodeFormatScheme struct {
+ Int EncodeFormat
+ Uint EncodeFormat
+ Float EncodeFormat
+ Bool EncodeFormat
+ String EncodeFormat
+ Binary EncodeFormat
+ ObjectKey EncodeFormat
+ Null EncodeFormat
+}
+
+type (
+ ColorScheme = EncodeFormatScheme
+ ColorFormat = EncodeFormat
+)
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/optype.go b/vendor/github.com/goccy/go-json/internal/encoder/optype.go
new file mode 100644
index 00000000..5c1241b4
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/optype.go
@@ -0,0 +1,932 @@
+// Code generated by internal/cmd/generator. DO NOT EDIT!
+package encoder
+
+import (
+ "strings"
+)
+
+type CodeType int
+
+const (
+ CodeOp CodeType = 0
+ CodeArrayHead CodeType = 1
+ CodeArrayElem CodeType = 2
+ CodeSliceHead CodeType = 3
+ CodeSliceElem CodeType = 4
+ CodeMapHead CodeType = 5
+ CodeMapKey CodeType = 6
+ CodeMapValue CodeType = 7
+ CodeMapEnd CodeType = 8
+ CodeRecursive CodeType = 9
+ CodeStructField CodeType = 10
+ CodeStructEnd CodeType = 11
+)
+
+var opTypeStrings = [400]string{
+ "End",
+ "Interface",
+ "Ptr",
+ "SliceElem",
+ "SliceEnd",
+ "ArrayElem",
+ "ArrayEnd",
+ "MapKey",
+ "MapValue",
+ "MapEnd",
+ "Recursive",
+ "RecursivePtr",
+ "RecursiveEnd",
+ "InterfaceEnd",
+ "Int",
+ "Uint",
+ "Float32",
+ "Float64",
+ "Bool",
+ "String",
+ "Bytes",
+ "Number",
+ "Array",
+ "Map",
+ "Slice",
+ "Struct",
+ "MarshalJSON",
+ "MarshalText",
+ "IntString",
+ "UintString",
+ "Float32String",
+ "Float64String",
+ "BoolString",
+ "StringString",
+ "NumberString",
+ "IntPtr",
+ "UintPtr",
+ "Float32Ptr",
+ "Float64Ptr",
+ "BoolPtr",
+ "StringPtr",
+ "BytesPtr",
+ "NumberPtr",
+ "ArrayPtr",
+ "MapPtr",
+ "SlicePtr",
+ "MarshalJSONPtr",
+ "MarshalTextPtr",
+ "InterfacePtr",
+ "IntPtrString",
+ "UintPtrString",
+ "Float32PtrString",
+ "Float64PtrString",
+ "BoolPtrString",
+ "StringPtrString",
+ "NumberPtrString",
+ "StructHeadInt",
+ "StructHeadOmitEmptyInt",
+ "StructPtrHeadInt",
+ "StructPtrHeadOmitEmptyInt",
+ "StructHeadUint",
+ "StructHeadOmitEmptyUint",
+ "StructPtrHeadUint",
+ "StructPtrHeadOmitEmptyUint",
+ "StructHeadFloat32",
+ "StructHeadOmitEmptyFloat32",
+ "StructPtrHeadFloat32",
+ "StructPtrHeadOmitEmptyFloat32",
+ "StructHeadFloat64",
+ "StructHeadOmitEmptyFloat64",
+ "StructPtrHeadFloat64",
+ "StructPtrHeadOmitEmptyFloat64",
+ "StructHeadBool",
+ "StructHeadOmitEmptyBool",
+ "StructPtrHeadBool",
+ "StructPtrHeadOmitEmptyBool",
+ "StructHeadString",
+ "StructHeadOmitEmptyString",
+ "StructPtrHeadString",
+ "StructPtrHeadOmitEmptyString",
+ "StructHeadBytes",
+ "StructHeadOmitEmptyBytes",
+ "StructPtrHeadBytes",
+ "StructPtrHeadOmitEmptyBytes",
+ "StructHeadNumber",
+ "StructHeadOmitEmptyNumber",
+ "StructPtrHeadNumber",
+ "StructPtrHeadOmitEmptyNumber",
+ "StructHeadArray",
+ "StructHeadOmitEmptyArray",
+ "StructPtrHeadArray",
+ "StructPtrHeadOmitEmptyArray",
+ "StructHeadMap",
+ "StructHeadOmitEmptyMap",
+ "StructPtrHeadMap",
+ "StructPtrHeadOmitEmptyMap",
+ "StructHeadSlice",
+ "StructHeadOmitEmptySlice",
+ "StructPtrHeadSlice",
+ "StructPtrHeadOmitEmptySlice",
+ "StructHeadStruct",
+ "StructHeadOmitEmptyStruct",
+ "StructPtrHeadStruct",
+ "StructPtrHeadOmitEmptyStruct",
+ "StructHeadMarshalJSON",
+ "StructHeadOmitEmptyMarshalJSON",
+ "StructPtrHeadMarshalJSON",
+ "StructPtrHeadOmitEmptyMarshalJSON",
+ "StructHeadMarshalText",
+ "StructHeadOmitEmptyMarshalText",
+ "StructPtrHeadMarshalText",
+ "StructPtrHeadOmitEmptyMarshalText",
+ "StructHeadIntString",
+ "StructHeadOmitEmptyIntString",
+ "StructPtrHeadIntString",
+ "StructPtrHeadOmitEmptyIntString",
+ "StructHeadUintString",
+ "StructHeadOmitEmptyUintString",
+ "StructPtrHeadUintString",
+ "StructPtrHeadOmitEmptyUintString",
+ "StructHeadFloat32String",
+ "StructHeadOmitEmptyFloat32String",
+ "StructPtrHeadFloat32String",
+ "StructPtrHeadOmitEmptyFloat32String",
+ "StructHeadFloat64String",
+ "StructHeadOmitEmptyFloat64String",
+ "StructPtrHeadFloat64String",
+ "StructPtrHeadOmitEmptyFloat64String",
+ "StructHeadBoolString",
+ "StructHeadOmitEmptyBoolString",
+ "StructPtrHeadBoolString",
+ "StructPtrHeadOmitEmptyBoolString",
+ "StructHeadStringString",
+ "StructHeadOmitEmptyStringString",
+ "StructPtrHeadStringString",
+ "StructPtrHeadOmitEmptyStringString",
+ "StructHeadNumberString",
+ "StructHeadOmitEmptyNumberString",
+ "StructPtrHeadNumberString",
+ "StructPtrHeadOmitEmptyNumberString",
+ "StructHeadIntPtr",
+ "StructHeadOmitEmptyIntPtr",
+ "StructPtrHeadIntPtr",
+ "StructPtrHeadOmitEmptyIntPtr",
+ "StructHeadUintPtr",
+ "StructHeadOmitEmptyUintPtr",
+ "StructPtrHeadUintPtr",
+ "StructPtrHeadOmitEmptyUintPtr",
+ "StructHeadFloat32Ptr",
+ "StructHeadOmitEmptyFloat32Ptr",
+ "StructPtrHeadFloat32Ptr",
+ "StructPtrHeadOmitEmptyFloat32Ptr",
+ "StructHeadFloat64Ptr",
+ "StructHeadOmitEmptyFloat64Ptr",
+ "StructPtrHeadFloat64Ptr",
+ "StructPtrHeadOmitEmptyFloat64Ptr",
+ "StructHeadBoolPtr",
+ "StructHeadOmitEmptyBoolPtr",
+ "StructPtrHeadBoolPtr",
+ "StructPtrHeadOmitEmptyBoolPtr",
+ "StructHeadStringPtr",
+ "StructHeadOmitEmptyStringPtr",
+ "StructPtrHeadStringPtr",
+ "StructPtrHeadOmitEmptyStringPtr",
+ "StructHeadBytesPtr",
+ "StructHeadOmitEmptyBytesPtr",
+ "StructPtrHeadBytesPtr",
+ "StructPtrHeadOmitEmptyBytesPtr",
+ "StructHeadNumberPtr",
+ "StructHeadOmitEmptyNumberPtr",
+ "StructPtrHeadNumberPtr",
+ "StructPtrHeadOmitEmptyNumberPtr",
+ "StructHeadArrayPtr",
+ "StructHeadOmitEmptyArrayPtr",
+ "StructPtrHeadArrayPtr",
+ "StructPtrHeadOmitEmptyArrayPtr",
+ "StructHeadMapPtr",
+ "StructHeadOmitEmptyMapPtr",
+ "StructPtrHeadMapPtr",
+ "StructPtrHeadOmitEmptyMapPtr",
+ "StructHeadSlicePtr",
+ "StructHeadOmitEmptySlicePtr",
+ "StructPtrHeadSlicePtr",
+ "StructPtrHeadOmitEmptySlicePtr",
+ "StructHeadMarshalJSONPtr",
+ "StructHeadOmitEmptyMarshalJSONPtr",
+ "StructPtrHeadMarshalJSONPtr",
+ "StructPtrHeadOmitEmptyMarshalJSONPtr",
+ "StructHeadMarshalTextPtr",
+ "StructHeadOmitEmptyMarshalTextPtr",
+ "StructPtrHeadMarshalTextPtr",
+ "StructPtrHeadOmitEmptyMarshalTextPtr",
+ "StructHeadInterfacePtr",
+ "StructHeadOmitEmptyInterfacePtr",
+ "StructPtrHeadInterfacePtr",
+ "StructPtrHeadOmitEmptyInterfacePtr",
+ "StructHeadIntPtrString",
+ "StructHeadOmitEmptyIntPtrString",
+ "StructPtrHeadIntPtrString",
+ "StructPtrHeadOmitEmptyIntPtrString",
+ "StructHeadUintPtrString",
+ "StructHeadOmitEmptyUintPtrString",
+ "StructPtrHeadUintPtrString",
+ "StructPtrHeadOmitEmptyUintPtrString",
+ "StructHeadFloat32PtrString",
+ "StructHeadOmitEmptyFloat32PtrString",
+ "StructPtrHeadFloat32PtrString",
+ "StructPtrHeadOmitEmptyFloat32PtrString",
+ "StructHeadFloat64PtrString",
+ "StructHeadOmitEmptyFloat64PtrString",
+ "StructPtrHeadFloat64PtrString",
+ "StructPtrHeadOmitEmptyFloat64PtrString",
+ "StructHeadBoolPtrString",
+ "StructHeadOmitEmptyBoolPtrString",
+ "StructPtrHeadBoolPtrString",
+ "StructPtrHeadOmitEmptyBoolPtrString",
+ "StructHeadStringPtrString",
+ "StructHeadOmitEmptyStringPtrString",
+ "StructPtrHeadStringPtrString",
+ "StructPtrHeadOmitEmptyStringPtrString",
+ "StructHeadNumberPtrString",
+ "StructHeadOmitEmptyNumberPtrString",
+ "StructPtrHeadNumberPtrString",
+ "StructPtrHeadOmitEmptyNumberPtrString",
+ "StructHead",
+ "StructHeadOmitEmpty",
+ "StructPtrHead",
+ "StructPtrHeadOmitEmpty",
+ "StructFieldInt",
+ "StructFieldOmitEmptyInt",
+ "StructEndInt",
+ "StructEndOmitEmptyInt",
+ "StructFieldUint",
+ "StructFieldOmitEmptyUint",
+ "StructEndUint",
+ "StructEndOmitEmptyUint",
+ "StructFieldFloat32",
+ "StructFieldOmitEmptyFloat32",
+ "StructEndFloat32",
+ "StructEndOmitEmptyFloat32",
+ "StructFieldFloat64",
+ "StructFieldOmitEmptyFloat64",
+ "StructEndFloat64",
+ "StructEndOmitEmptyFloat64",
+ "StructFieldBool",
+ "StructFieldOmitEmptyBool",
+ "StructEndBool",
+ "StructEndOmitEmptyBool",
+ "StructFieldString",
+ "StructFieldOmitEmptyString",
+ "StructEndString",
+ "StructEndOmitEmptyString",
+ "StructFieldBytes",
+ "StructFieldOmitEmptyBytes",
+ "StructEndBytes",
+ "StructEndOmitEmptyBytes",
+ "StructFieldNumber",
+ "StructFieldOmitEmptyNumber",
+ "StructEndNumber",
+ "StructEndOmitEmptyNumber",
+ "StructFieldArray",
+ "StructFieldOmitEmptyArray",
+ "StructEndArray",
+ "StructEndOmitEmptyArray",
+ "StructFieldMap",
+ "StructFieldOmitEmptyMap",
+ "StructEndMap",
+ "StructEndOmitEmptyMap",
+ "StructFieldSlice",
+ "StructFieldOmitEmptySlice",
+ "StructEndSlice",
+ "StructEndOmitEmptySlice",
+ "StructFieldStruct",
+ "StructFieldOmitEmptyStruct",
+ "StructEndStruct",
+ "StructEndOmitEmptyStruct",
+ "StructFieldMarshalJSON",
+ "StructFieldOmitEmptyMarshalJSON",
+ "StructEndMarshalJSON",
+ "StructEndOmitEmptyMarshalJSON",
+ "StructFieldMarshalText",
+ "StructFieldOmitEmptyMarshalText",
+ "StructEndMarshalText",
+ "StructEndOmitEmptyMarshalText",
+ "StructFieldIntString",
+ "StructFieldOmitEmptyIntString",
+ "StructEndIntString",
+ "StructEndOmitEmptyIntString",
+ "StructFieldUintString",
+ "StructFieldOmitEmptyUintString",
+ "StructEndUintString",
+ "StructEndOmitEmptyUintString",
+ "StructFieldFloat32String",
+ "StructFieldOmitEmptyFloat32String",
+ "StructEndFloat32String",
+ "StructEndOmitEmptyFloat32String",
+ "StructFieldFloat64String",
+ "StructFieldOmitEmptyFloat64String",
+ "StructEndFloat64String",
+ "StructEndOmitEmptyFloat64String",
+ "StructFieldBoolString",
+ "StructFieldOmitEmptyBoolString",
+ "StructEndBoolString",
+ "StructEndOmitEmptyBoolString",
+ "StructFieldStringString",
+ "StructFieldOmitEmptyStringString",
+ "StructEndStringString",
+ "StructEndOmitEmptyStringString",
+ "StructFieldNumberString",
+ "StructFieldOmitEmptyNumberString",
+ "StructEndNumberString",
+ "StructEndOmitEmptyNumberString",
+ "StructFieldIntPtr",
+ "StructFieldOmitEmptyIntPtr",
+ "StructEndIntPtr",
+ "StructEndOmitEmptyIntPtr",
+ "StructFieldUintPtr",
+ "StructFieldOmitEmptyUintPtr",
+ "StructEndUintPtr",
+ "StructEndOmitEmptyUintPtr",
+ "StructFieldFloat32Ptr",
+ "StructFieldOmitEmptyFloat32Ptr",
+ "StructEndFloat32Ptr",
+ "StructEndOmitEmptyFloat32Ptr",
+ "StructFieldFloat64Ptr",
+ "StructFieldOmitEmptyFloat64Ptr",
+ "StructEndFloat64Ptr",
+ "StructEndOmitEmptyFloat64Ptr",
+ "StructFieldBoolPtr",
+ "StructFieldOmitEmptyBoolPtr",
+ "StructEndBoolPtr",
+ "StructEndOmitEmptyBoolPtr",
+ "StructFieldStringPtr",
+ "StructFieldOmitEmptyStringPtr",
+ "StructEndStringPtr",
+ "StructEndOmitEmptyStringPtr",
+ "StructFieldBytesPtr",
+ "StructFieldOmitEmptyBytesPtr",
+ "StructEndBytesPtr",
+ "StructEndOmitEmptyBytesPtr",
+ "StructFieldNumberPtr",
+ "StructFieldOmitEmptyNumberPtr",
+ "StructEndNumberPtr",
+ "StructEndOmitEmptyNumberPtr",
+ "StructFieldArrayPtr",
+ "StructFieldOmitEmptyArrayPtr",
+ "StructEndArrayPtr",
+ "StructEndOmitEmptyArrayPtr",
+ "StructFieldMapPtr",
+ "StructFieldOmitEmptyMapPtr",
+ "StructEndMapPtr",
+ "StructEndOmitEmptyMapPtr",
+ "StructFieldSlicePtr",
+ "StructFieldOmitEmptySlicePtr",
+ "StructEndSlicePtr",
+ "StructEndOmitEmptySlicePtr",
+ "StructFieldMarshalJSONPtr",
+ "StructFieldOmitEmptyMarshalJSONPtr",
+ "StructEndMarshalJSONPtr",
+ "StructEndOmitEmptyMarshalJSONPtr",
+ "StructFieldMarshalTextPtr",
+ "StructFieldOmitEmptyMarshalTextPtr",
+ "StructEndMarshalTextPtr",
+ "StructEndOmitEmptyMarshalTextPtr",
+ "StructFieldInterfacePtr",
+ "StructFieldOmitEmptyInterfacePtr",
+ "StructEndInterfacePtr",
+ "StructEndOmitEmptyInterfacePtr",
+ "StructFieldIntPtrString",
+ "StructFieldOmitEmptyIntPtrString",
+ "StructEndIntPtrString",
+ "StructEndOmitEmptyIntPtrString",
+ "StructFieldUintPtrString",
+ "StructFieldOmitEmptyUintPtrString",
+ "StructEndUintPtrString",
+ "StructEndOmitEmptyUintPtrString",
+ "StructFieldFloat32PtrString",
+ "StructFieldOmitEmptyFloat32PtrString",
+ "StructEndFloat32PtrString",
+ "StructEndOmitEmptyFloat32PtrString",
+ "StructFieldFloat64PtrString",
+ "StructFieldOmitEmptyFloat64PtrString",
+ "StructEndFloat64PtrString",
+ "StructEndOmitEmptyFloat64PtrString",
+ "StructFieldBoolPtrString",
+ "StructFieldOmitEmptyBoolPtrString",
+ "StructEndBoolPtrString",
+ "StructEndOmitEmptyBoolPtrString",
+ "StructFieldStringPtrString",
+ "StructFieldOmitEmptyStringPtrString",
+ "StructEndStringPtrString",
+ "StructEndOmitEmptyStringPtrString",
+ "StructFieldNumberPtrString",
+ "StructFieldOmitEmptyNumberPtrString",
+ "StructEndNumberPtrString",
+ "StructEndOmitEmptyNumberPtrString",
+ "StructField",
+ "StructFieldOmitEmpty",
+ "StructEnd",
+ "StructEndOmitEmpty",
+}
+
+type OpType uint16
+
+const (
+ OpEnd OpType = 0
+ OpInterface OpType = 1
+ OpPtr OpType = 2
+ OpSliceElem OpType = 3
+ OpSliceEnd OpType = 4
+ OpArrayElem OpType = 5
+ OpArrayEnd OpType = 6
+ OpMapKey OpType = 7
+ OpMapValue OpType = 8
+ OpMapEnd OpType = 9
+ OpRecursive OpType = 10
+ OpRecursivePtr OpType = 11
+ OpRecursiveEnd OpType = 12
+ OpInterfaceEnd OpType = 13
+ OpInt OpType = 14
+ OpUint OpType = 15
+ OpFloat32 OpType = 16
+ OpFloat64 OpType = 17
+ OpBool OpType = 18
+ OpString OpType = 19
+ OpBytes OpType = 20
+ OpNumber OpType = 21
+ OpArray OpType = 22
+ OpMap OpType = 23
+ OpSlice OpType = 24
+ OpStruct OpType = 25
+ OpMarshalJSON OpType = 26
+ OpMarshalText OpType = 27
+ OpIntString OpType = 28
+ OpUintString OpType = 29
+ OpFloat32String OpType = 30
+ OpFloat64String OpType = 31
+ OpBoolString OpType = 32
+ OpStringString OpType = 33
+ OpNumberString OpType = 34
+ OpIntPtr OpType = 35
+ OpUintPtr OpType = 36
+ OpFloat32Ptr OpType = 37
+ OpFloat64Ptr OpType = 38
+ OpBoolPtr OpType = 39
+ OpStringPtr OpType = 40
+ OpBytesPtr OpType = 41
+ OpNumberPtr OpType = 42
+ OpArrayPtr OpType = 43
+ OpMapPtr OpType = 44
+ OpSlicePtr OpType = 45
+ OpMarshalJSONPtr OpType = 46
+ OpMarshalTextPtr OpType = 47
+ OpInterfacePtr OpType = 48
+ OpIntPtrString OpType = 49
+ OpUintPtrString OpType = 50
+ OpFloat32PtrString OpType = 51
+ OpFloat64PtrString OpType = 52
+ OpBoolPtrString OpType = 53
+ OpStringPtrString OpType = 54
+ OpNumberPtrString OpType = 55
+ OpStructHeadInt OpType = 56
+ OpStructHeadOmitEmptyInt OpType = 57
+ OpStructPtrHeadInt OpType = 58
+ OpStructPtrHeadOmitEmptyInt OpType = 59
+ OpStructHeadUint OpType = 60
+ OpStructHeadOmitEmptyUint OpType = 61
+ OpStructPtrHeadUint OpType = 62
+ OpStructPtrHeadOmitEmptyUint OpType = 63
+ OpStructHeadFloat32 OpType = 64
+ OpStructHeadOmitEmptyFloat32 OpType = 65
+ OpStructPtrHeadFloat32 OpType = 66
+ OpStructPtrHeadOmitEmptyFloat32 OpType = 67
+ OpStructHeadFloat64 OpType = 68
+ OpStructHeadOmitEmptyFloat64 OpType = 69
+ OpStructPtrHeadFloat64 OpType = 70
+ OpStructPtrHeadOmitEmptyFloat64 OpType = 71
+ OpStructHeadBool OpType = 72
+ OpStructHeadOmitEmptyBool OpType = 73
+ OpStructPtrHeadBool OpType = 74
+ OpStructPtrHeadOmitEmptyBool OpType = 75
+ OpStructHeadString OpType = 76
+ OpStructHeadOmitEmptyString OpType = 77
+ OpStructPtrHeadString OpType = 78
+ OpStructPtrHeadOmitEmptyString OpType = 79
+ OpStructHeadBytes OpType = 80
+ OpStructHeadOmitEmptyBytes OpType = 81
+ OpStructPtrHeadBytes OpType = 82
+ OpStructPtrHeadOmitEmptyBytes OpType = 83
+ OpStructHeadNumber OpType = 84
+ OpStructHeadOmitEmptyNumber OpType = 85
+ OpStructPtrHeadNumber OpType = 86
+ OpStructPtrHeadOmitEmptyNumber OpType = 87
+ OpStructHeadArray OpType = 88
+ OpStructHeadOmitEmptyArray OpType = 89
+ OpStructPtrHeadArray OpType = 90
+ OpStructPtrHeadOmitEmptyArray OpType = 91
+ OpStructHeadMap OpType = 92
+ OpStructHeadOmitEmptyMap OpType = 93
+ OpStructPtrHeadMap OpType = 94
+ OpStructPtrHeadOmitEmptyMap OpType = 95
+ OpStructHeadSlice OpType = 96
+ OpStructHeadOmitEmptySlice OpType = 97
+ OpStructPtrHeadSlice OpType = 98
+ OpStructPtrHeadOmitEmptySlice OpType = 99
+ OpStructHeadStruct OpType = 100
+ OpStructHeadOmitEmptyStruct OpType = 101
+ OpStructPtrHeadStruct OpType = 102
+ OpStructPtrHeadOmitEmptyStruct OpType = 103
+ OpStructHeadMarshalJSON OpType = 104
+ OpStructHeadOmitEmptyMarshalJSON OpType = 105
+ OpStructPtrHeadMarshalJSON OpType = 106
+ OpStructPtrHeadOmitEmptyMarshalJSON OpType = 107
+ OpStructHeadMarshalText OpType = 108
+ OpStructHeadOmitEmptyMarshalText OpType = 109
+ OpStructPtrHeadMarshalText OpType = 110
+ OpStructPtrHeadOmitEmptyMarshalText OpType = 111
+ OpStructHeadIntString OpType = 112
+ OpStructHeadOmitEmptyIntString OpType = 113
+ OpStructPtrHeadIntString OpType = 114
+ OpStructPtrHeadOmitEmptyIntString OpType = 115
+ OpStructHeadUintString OpType = 116
+ OpStructHeadOmitEmptyUintString OpType = 117
+ OpStructPtrHeadUintString OpType = 118
+ OpStructPtrHeadOmitEmptyUintString OpType = 119
+ OpStructHeadFloat32String OpType = 120
+ OpStructHeadOmitEmptyFloat32String OpType = 121
+ OpStructPtrHeadFloat32String OpType = 122
+ OpStructPtrHeadOmitEmptyFloat32String OpType = 123
+ OpStructHeadFloat64String OpType = 124
+ OpStructHeadOmitEmptyFloat64String OpType = 125
+ OpStructPtrHeadFloat64String OpType = 126
+ OpStructPtrHeadOmitEmptyFloat64String OpType = 127
+ OpStructHeadBoolString OpType = 128
+ OpStructHeadOmitEmptyBoolString OpType = 129
+ OpStructPtrHeadBoolString OpType = 130
+ OpStructPtrHeadOmitEmptyBoolString OpType = 131
+ OpStructHeadStringString OpType = 132
+ OpStructHeadOmitEmptyStringString OpType = 133
+ OpStructPtrHeadStringString OpType = 134
+ OpStructPtrHeadOmitEmptyStringString OpType = 135
+ OpStructHeadNumberString OpType = 136
+ OpStructHeadOmitEmptyNumberString OpType = 137
+ OpStructPtrHeadNumberString OpType = 138
+ OpStructPtrHeadOmitEmptyNumberString OpType = 139
+ OpStructHeadIntPtr OpType = 140
+ OpStructHeadOmitEmptyIntPtr OpType = 141
+ OpStructPtrHeadIntPtr OpType = 142
+ OpStructPtrHeadOmitEmptyIntPtr OpType = 143
+ OpStructHeadUintPtr OpType = 144
+ OpStructHeadOmitEmptyUintPtr OpType = 145
+ OpStructPtrHeadUintPtr OpType = 146
+ OpStructPtrHeadOmitEmptyUintPtr OpType = 147
+ OpStructHeadFloat32Ptr OpType = 148
+ OpStructHeadOmitEmptyFloat32Ptr OpType = 149
+ OpStructPtrHeadFloat32Ptr OpType = 150
+ OpStructPtrHeadOmitEmptyFloat32Ptr OpType = 151
+ OpStructHeadFloat64Ptr OpType = 152
+ OpStructHeadOmitEmptyFloat64Ptr OpType = 153
+ OpStructPtrHeadFloat64Ptr OpType = 154
+ OpStructPtrHeadOmitEmptyFloat64Ptr OpType = 155
+ OpStructHeadBoolPtr OpType = 156
+ OpStructHeadOmitEmptyBoolPtr OpType = 157
+ OpStructPtrHeadBoolPtr OpType = 158
+ OpStructPtrHeadOmitEmptyBoolPtr OpType = 159
+ OpStructHeadStringPtr OpType = 160
+ OpStructHeadOmitEmptyStringPtr OpType = 161
+ OpStructPtrHeadStringPtr OpType = 162
+ OpStructPtrHeadOmitEmptyStringPtr OpType = 163
+ OpStructHeadBytesPtr OpType = 164
+ OpStructHeadOmitEmptyBytesPtr OpType = 165
+ OpStructPtrHeadBytesPtr OpType = 166
+ OpStructPtrHeadOmitEmptyBytesPtr OpType = 167
+ OpStructHeadNumberPtr OpType = 168
+ OpStructHeadOmitEmptyNumberPtr OpType = 169
+ OpStructPtrHeadNumberPtr OpType = 170
+ OpStructPtrHeadOmitEmptyNumberPtr OpType = 171
+ OpStructHeadArrayPtr OpType = 172
+ OpStructHeadOmitEmptyArrayPtr OpType = 173
+ OpStructPtrHeadArrayPtr OpType = 174
+ OpStructPtrHeadOmitEmptyArrayPtr OpType = 175
+ OpStructHeadMapPtr OpType = 176
+ OpStructHeadOmitEmptyMapPtr OpType = 177
+ OpStructPtrHeadMapPtr OpType = 178
+ OpStructPtrHeadOmitEmptyMapPtr OpType = 179
+ OpStructHeadSlicePtr OpType = 180
+ OpStructHeadOmitEmptySlicePtr OpType = 181
+ OpStructPtrHeadSlicePtr OpType = 182
+ OpStructPtrHeadOmitEmptySlicePtr OpType = 183
+ OpStructHeadMarshalJSONPtr OpType = 184
+ OpStructHeadOmitEmptyMarshalJSONPtr OpType = 185
+ OpStructPtrHeadMarshalJSONPtr OpType = 186
+ OpStructPtrHeadOmitEmptyMarshalJSONPtr OpType = 187
+ OpStructHeadMarshalTextPtr OpType = 188
+ OpStructHeadOmitEmptyMarshalTextPtr OpType = 189
+ OpStructPtrHeadMarshalTextPtr OpType = 190
+ OpStructPtrHeadOmitEmptyMarshalTextPtr OpType = 191
+ OpStructHeadInterfacePtr OpType = 192
+ OpStructHeadOmitEmptyInterfacePtr OpType = 193
+ OpStructPtrHeadInterfacePtr OpType = 194
+ OpStructPtrHeadOmitEmptyInterfacePtr OpType = 195
+ OpStructHeadIntPtrString OpType = 196
+ OpStructHeadOmitEmptyIntPtrString OpType = 197
+ OpStructPtrHeadIntPtrString OpType = 198
+ OpStructPtrHeadOmitEmptyIntPtrString OpType = 199
+ OpStructHeadUintPtrString OpType = 200
+ OpStructHeadOmitEmptyUintPtrString OpType = 201
+ OpStructPtrHeadUintPtrString OpType = 202
+ OpStructPtrHeadOmitEmptyUintPtrString OpType = 203
+ OpStructHeadFloat32PtrString OpType = 204
+ OpStructHeadOmitEmptyFloat32PtrString OpType = 205
+ OpStructPtrHeadFloat32PtrString OpType = 206
+ OpStructPtrHeadOmitEmptyFloat32PtrString OpType = 207
+ OpStructHeadFloat64PtrString OpType = 208
+ OpStructHeadOmitEmptyFloat64PtrString OpType = 209
+ OpStructPtrHeadFloat64PtrString OpType = 210
+ OpStructPtrHeadOmitEmptyFloat64PtrString OpType = 211
+ OpStructHeadBoolPtrString OpType = 212
+ OpStructHeadOmitEmptyBoolPtrString OpType = 213
+ OpStructPtrHeadBoolPtrString OpType = 214
+ OpStructPtrHeadOmitEmptyBoolPtrString OpType = 215
+ OpStructHeadStringPtrString OpType = 216
+ OpStructHeadOmitEmptyStringPtrString OpType = 217
+ OpStructPtrHeadStringPtrString OpType = 218
+ OpStructPtrHeadOmitEmptyStringPtrString OpType = 219
+ OpStructHeadNumberPtrString OpType = 220
+ OpStructHeadOmitEmptyNumberPtrString OpType = 221
+ OpStructPtrHeadNumberPtrString OpType = 222
+ OpStructPtrHeadOmitEmptyNumberPtrString OpType = 223
+ OpStructHead OpType = 224
+ OpStructHeadOmitEmpty OpType = 225
+ OpStructPtrHead OpType = 226
+ OpStructPtrHeadOmitEmpty OpType = 227
+ OpStructFieldInt OpType = 228
+ OpStructFieldOmitEmptyInt OpType = 229
+ OpStructEndInt OpType = 230
+ OpStructEndOmitEmptyInt OpType = 231
+ OpStructFieldUint OpType = 232
+ OpStructFieldOmitEmptyUint OpType = 233
+ OpStructEndUint OpType = 234
+ OpStructEndOmitEmptyUint OpType = 235
+ OpStructFieldFloat32 OpType = 236
+ OpStructFieldOmitEmptyFloat32 OpType = 237
+ OpStructEndFloat32 OpType = 238
+ OpStructEndOmitEmptyFloat32 OpType = 239
+ OpStructFieldFloat64 OpType = 240
+ OpStructFieldOmitEmptyFloat64 OpType = 241
+ OpStructEndFloat64 OpType = 242
+ OpStructEndOmitEmptyFloat64 OpType = 243
+ OpStructFieldBool OpType = 244
+ OpStructFieldOmitEmptyBool OpType = 245
+ OpStructEndBool OpType = 246
+ OpStructEndOmitEmptyBool OpType = 247
+ OpStructFieldString OpType = 248
+ OpStructFieldOmitEmptyString OpType = 249
+ OpStructEndString OpType = 250
+ OpStructEndOmitEmptyString OpType = 251
+ OpStructFieldBytes OpType = 252
+ OpStructFieldOmitEmptyBytes OpType = 253
+ OpStructEndBytes OpType = 254
+ OpStructEndOmitEmptyBytes OpType = 255
+ OpStructFieldNumber OpType = 256
+ OpStructFieldOmitEmptyNumber OpType = 257
+ OpStructEndNumber OpType = 258
+ OpStructEndOmitEmptyNumber OpType = 259
+ OpStructFieldArray OpType = 260
+ OpStructFieldOmitEmptyArray OpType = 261
+ OpStructEndArray OpType = 262
+ OpStructEndOmitEmptyArray OpType = 263
+ OpStructFieldMap OpType = 264
+ OpStructFieldOmitEmptyMap OpType = 265
+ OpStructEndMap OpType = 266
+ OpStructEndOmitEmptyMap OpType = 267
+ OpStructFieldSlice OpType = 268
+ OpStructFieldOmitEmptySlice OpType = 269
+ OpStructEndSlice OpType = 270
+ OpStructEndOmitEmptySlice OpType = 271
+ OpStructFieldStruct OpType = 272
+ OpStructFieldOmitEmptyStruct OpType = 273
+ OpStructEndStruct OpType = 274
+ OpStructEndOmitEmptyStruct OpType = 275
+ OpStructFieldMarshalJSON OpType = 276
+ OpStructFieldOmitEmptyMarshalJSON OpType = 277
+ OpStructEndMarshalJSON OpType = 278
+ OpStructEndOmitEmptyMarshalJSON OpType = 279
+ OpStructFieldMarshalText OpType = 280
+ OpStructFieldOmitEmptyMarshalText OpType = 281
+ OpStructEndMarshalText OpType = 282
+ OpStructEndOmitEmptyMarshalText OpType = 283
+ OpStructFieldIntString OpType = 284
+ OpStructFieldOmitEmptyIntString OpType = 285
+ OpStructEndIntString OpType = 286
+ OpStructEndOmitEmptyIntString OpType = 287
+ OpStructFieldUintString OpType = 288
+ OpStructFieldOmitEmptyUintString OpType = 289
+ OpStructEndUintString OpType = 290
+ OpStructEndOmitEmptyUintString OpType = 291
+ OpStructFieldFloat32String OpType = 292
+ OpStructFieldOmitEmptyFloat32String OpType = 293
+ OpStructEndFloat32String OpType = 294
+ OpStructEndOmitEmptyFloat32String OpType = 295
+ OpStructFieldFloat64String OpType = 296
+ OpStructFieldOmitEmptyFloat64String OpType = 297
+ OpStructEndFloat64String OpType = 298
+ OpStructEndOmitEmptyFloat64String OpType = 299
+ OpStructFieldBoolString OpType = 300
+ OpStructFieldOmitEmptyBoolString OpType = 301
+ OpStructEndBoolString OpType = 302
+ OpStructEndOmitEmptyBoolString OpType = 303
+ OpStructFieldStringString OpType = 304
+ OpStructFieldOmitEmptyStringString OpType = 305
+ OpStructEndStringString OpType = 306
+ OpStructEndOmitEmptyStringString OpType = 307
+ OpStructFieldNumberString OpType = 308
+ OpStructFieldOmitEmptyNumberString OpType = 309
+ OpStructEndNumberString OpType = 310
+ OpStructEndOmitEmptyNumberString OpType = 311
+ OpStructFieldIntPtr OpType = 312
+ OpStructFieldOmitEmptyIntPtr OpType = 313
+ OpStructEndIntPtr OpType = 314
+ OpStructEndOmitEmptyIntPtr OpType = 315
+ OpStructFieldUintPtr OpType = 316
+ OpStructFieldOmitEmptyUintPtr OpType = 317
+ OpStructEndUintPtr OpType = 318
+ OpStructEndOmitEmptyUintPtr OpType = 319
+ OpStructFieldFloat32Ptr OpType = 320
+ OpStructFieldOmitEmptyFloat32Ptr OpType = 321
+ OpStructEndFloat32Ptr OpType = 322
+ OpStructEndOmitEmptyFloat32Ptr OpType = 323
+ OpStructFieldFloat64Ptr OpType = 324
+ OpStructFieldOmitEmptyFloat64Ptr OpType = 325
+ OpStructEndFloat64Ptr OpType = 326
+ OpStructEndOmitEmptyFloat64Ptr OpType = 327
+ OpStructFieldBoolPtr OpType = 328
+ OpStructFieldOmitEmptyBoolPtr OpType = 329
+ OpStructEndBoolPtr OpType = 330
+ OpStructEndOmitEmptyBoolPtr OpType = 331
+ OpStructFieldStringPtr OpType = 332
+ OpStructFieldOmitEmptyStringPtr OpType = 333
+ OpStructEndStringPtr OpType = 334
+ OpStructEndOmitEmptyStringPtr OpType = 335
+ OpStructFieldBytesPtr OpType = 336
+ OpStructFieldOmitEmptyBytesPtr OpType = 337
+ OpStructEndBytesPtr OpType = 338
+ OpStructEndOmitEmptyBytesPtr OpType = 339
+ OpStructFieldNumberPtr OpType = 340
+ OpStructFieldOmitEmptyNumberPtr OpType = 341
+ OpStructEndNumberPtr OpType = 342
+ OpStructEndOmitEmptyNumberPtr OpType = 343
+ OpStructFieldArrayPtr OpType = 344
+ OpStructFieldOmitEmptyArrayPtr OpType = 345
+ OpStructEndArrayPtr OpType = 346
+ OpStructEndOmitEmptyArrayPtr OpType = 347
+ OpStructFieldMapPtr OpType = 348
+ OpStructFieldOmitEmptyMapPtr OpType = 349
+ OpStructEndMapPtr OpType = 350
+ OpStructEndOmitEmptyMapPtr OpType = 351
+ OpStructFieldSlicePtr OpType = 352
+ OpStructFieldOmitEmptySlicePtr OpType = 353
+ OpStructEndSlicePtr OpType = 354
+ OpStructEndOmitEmptySlicePtr OpType = 355
+ OpStructFieldMarshalJSONPtr OpType = 356
+ OpStructFieldOmitEmptyMarshalJSONPtr OpType = 357
+ OpStructEndMarshalJSONPtr OpType = 358
+ OpStructEndOmitEmptyMarshalJSONPtr OpType = 359
+ OpStructFieldMarshalTextPtr OpType = 360
+ OpStructFieldOmitEmptyMarshalTextPtr OpType = 361
+ OpStructEndMarshalTextPtr OpType = 362
+ OpStructEndOmitEmptyMarshalTextPtr OpType = 363
+ OpStructFieldInterfacePtr OpType = 364
+ OpStructFieldOmitEmptyInterfacePtr OpType = 365
+ OpStructEndInterfacePtr OpType = 366
+ OpStructEndOmitEmptyInterfacePtr OpType = 367
+ OpStructFieldIntPtrString OpType = 368
+ OpStructFieldOmitEmptyIntPtrString OpType = 369
+ OpStructEndIntPtrString OpType = 370
+ OpStructEndOmitEmptyIntPtrString OpType = 371
+ OpStructFieldUintPtrString OpType = 372
+ OpStructFieldOmitEmptyUintPtrString OpType = 373
+ OpStructEndUintPtrString OpType = 374
+ OpStructEndOmitEmptyUintPtrString OpType = 375
+ OpStructFieldFloat32PtrString OpType = 376
+ OpStructFieldOmitEmptyFloat32PtrString OpType = 377
+ OpStructEndFloat32PtrString OpType = 378
+ OpStructEndOmitEmptyFloat32PtrString OpType = 379
+ OpStructFieldFloat64PtrString OpType = 380
+ OpStructFieldOmitEmptyFloat64PtrString OpType = 381
+ OpStructEndFloat64PtrString OpType = 382
+ OpStructEndOmitEmptyFloat64PtrString OpType = 383
+ OpStructFieldBoolPtrString OpType = 384
+ OpStructFieldOmitEmptyBoolPtrString OpType = 385
+ OpStructEndBoolPtrString OpType = 386
+ OpStructEndOmitEmptyBoolPtrString OpType = 387
+ OpStructFieldStringPtrString OpType = 388
+ OpStructFieldOmitEmptyStringPtrString OpType = 389
+ OpStructEndStringPtrString OpType = 390
+ OpStructEndOmitEmptyStringPtrString OpType = 391
+ OpStructFieldNumberPtrString OpType = 392
+ OpStructFieldOmitEmptyNumberPtrString OpType = 393
+ OpStructEndNumberPtrString OpType = 394
+ OpStructEndOmitEmptyNumberPtrString OpType = 395
+ OpStructField OpType = 396
+ OpStructFieldOmitEmpty OpType = 397
+ OpStructEnd OpType = 398
+ OpStructEndOmitEmpty OpType = 399
+)
+
+func (t OpType) String() string {
+ if int(t) >= 400 {
+ return ""
+ }
+ return opTypeStrings[int(t)]
+}
+
+func (t OpType) CodeType() CodeType {
+ if strings.Contains(t.String(), "Struct") {
+ if strings.Contains(t.String(), "End") {
+ return CodeStructEnd
+ }
+ return CodeStructField
+ }
+ switch t {
+ case OpArray, OpArrayPtr:
+ return CodeArrayHead
+ case OpArrayElem:
+ return CodeArrayElem
+ case OpSlice, OpSlicePtr:
+ return CodeSliceHead
+ case OpSliceElem:
+ return CodeSliceElem
+ case OpMap, OpMapPtr:
+ return CodeMapHead
+ case OpMapKey:
+ return CodeMapKey
+ case OpMapValue:
+ return CodeMapValue
+ case OpMapEnd:
+ return CodeMapEnd
+ }
+
+ return CodeOp
+}
+
+func (t OpType) HeadToPtrHead() OpType {
+ if strings.Index(t.String(), "PtrHead") > 0 {
+ return t
+ }
+
+ idx := strings.Index(t.String(), "Head")
+ if idx == -1 {
+ return t
+ }
+ suffix := "PtrHead" + t.String()[idx+len("Head"):]
+
+ const toPtrOffset = 2
+ if strings.Contains(OpType(int(t)+toPtrOffset).String(), suffix) {
+ return OpType(int(t) + toPtrOffset)
+ }
+ return t
+}
+
+func (t OpType) HeadToOmitEmptyHead() OpType {
+ const toOmitEmptyOffset = 1
+ if strings.Contains(OpType(int(t)+toOmitEmptyOffset).String(), "OmitEmpty") {
+ return OpType(int(t) + toOmitEmptyOffset)
+ }
+
+ return t
+}
+
+func (t OpType) PtrHeadToHead() OpType {
+ idx := strings.Index(t.String(), "PtrHead")
+ if idx == -1 {
+ return t
+ }
+ suffix := t.String()[idx+len("Ptr"):]
+
+ const toPtrOffset = 2
+ if strings.Contains(OpType(int(t)-toPtrOffset).String(), suffix) {
+ return OpType(int(t) - toPtrOffset)
+ }
+ return t
+}
+
+func (t OpType) FieldToEnd() OpType {
+ idx := strings.Index(t.String(), "Field")
+ if idx == -1 {
+ return t
+ }
+ suffix := t.String()[idx+len("Field"):]
+ if suffix == "" || suffix == "OmitEmpty" {
+ return t
+ }
+ const toEndOffset = 2
+ if strings.Contains(OpType(int(t)+toEndOffset).String(), "End"+suffix) {
+ return OpType(int(t) + toEndOffset)
+ }
+ return t
+}
+
+func (t OpType) FieldToOmitEmptyField() OpType {
+ const toOmitEmptyOffset = 1
+ if strings.Contains(OpType(int(t)+toOmitEmptyOffset).String(), "OmitEmpty") {
+ return OpType(int(t) + toOmitEmptyOffset)
+ }
+ return t
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/query.go b/vendor/github.com/goccy/go-json/internal/encoder/query.go
new file mode 100644
index 00000000..1e1850cc
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/query.go
@@ -0,0 +1,135 @@
+package encoder
+
+import (
+ "context"
+ "fmt"
+ "reflect"
+)
+
+var (
+ Marshal func(interface{}) ([]byte, error)
+ Unmarshal func([]byte, interface{}) error
+)
+
+type FieldQuery struct {
+ Name string
+ Fields []*FieldQuery
+ hash string
+}
+
+func (q *FieldQuery) Hash() string {
+ if q.hash != "" {
+ return q.hash
+ }
+ b, _ := Marshal(q)
+ q.hash = string(b)
+ return q.hash
+}
+
+func (q *FieldQuery) MarshalJSON() ([]byte, error) {
+ if q.Name != "" {
+ if len(q.Fields) > 0 {
+ return Marshal(map[string][]*FieldQuery{q.Name: q.Fields})
+ }
+ return Marshal(q.Name)
+ }
+ return Marshal(q.Fields)
+}
+
+func (q *FieldQuery) QueryString() (FieldQueryString, error) {
+ b, err := Marshal(q)
+ if err != nil {
+ return "", err
+ }
+ return FieldQueryString(b), nil
+}
+
+type FieldQueryString string
+
+func (s FieldQueryString) Build() (*FieldQuery, error) {
+ var query interface{}
+ if err := Unmarshal([]byte(s), &query); err != nil {
+ return nil, err
+ }
+ return s.build(reflect.ValueOf(query))
+}
+
+func (s FieldQueryString) build(v reflect.Value) (*FieldQuery, error) {
+ switch v.Type().Kind() {
+ case reflect.String:
+ return s.buildString(v)
+ case reflect.Map:
+ return s.buildMap(v)
+ case reflect.Slice:
+ return s.buildSlice(v)
+ case reflect.Interface:
+ return s.build(reflect.ValueOf(v.Interface()))
+ }
+ return nil, fmt.Errorf("failed to build field query")
+}
+
+func (s FieldQueryString) buildString(v reflect.Value) (*FieldQuery, error) {
+ b := []byte(v.String())
+ switch b[0] {
+ case '[', '{':
+ var query interface{}
+ if err := Unmarshal(b, &query); err != nil {
+ return nil, err
+ }
+ if str, ok := query.(string); ok {
+ return &FieldQuery{Name: str}, nil
+ }
+ return s.build(reflect.ValueOf(query))
+ }
+ return &FieldQuery{Name: string(b)}, nil
+}
+
+func (s FieldQueryString) buildSlice(v reflect.Value) (*FieldQuery, error) {
+ fields := make([]*FieldQuery, 0, v.Len())
+ for i := 0; i < v.Len(); i++ {
+ def, err := s.build(v.Index(i))
+ if err != nil {
+ return nil, err
+ }
+ fields = append(fields, def)
+ }
+ return &FieldQuery{Fields: fields}, nil
+}
+
+func (s FieldQueryString) buildMap(v reflect.Value) (*FieldQuery, error) {
+ keys := v.MapKeys()
+ if len(keys) != 1 {
+ return nil, fmt.Errorf("failed to build field query object")
+ }
+ key := keys[0]
+ if key.Type().Kind() != reflect.String {
+ return nil, fmt.Errorf("failed to build field query. invalid object key type")
+ }
+ name := key.String()
+ def, err := s.build(v.MapIndex(key))
+ if err != nil {
+ return nil, err
+ }
+ return &FieldQuery{
+ Name: name,
+ Fields: def.Fields,
+ }, nil
+}
+
+type queryKey struct{}
+
+func FieldQueryFromContext(ctx context.Context) *FieldQuery {
+ query := ctx.Value(queryKey{})
+ if query == nil {
+ return nil
+ }
+ q, ok := query.(*FieldQuery)
+ if !ok {
+ return nil
+ }
+ return q
+}
+
+func SetFieldQueryToContext(ctx context.Context, query *FieldQuery) context.Context {
+ return context.WithValue(ctx, queryKey{}, query)
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/string.go b/vendor/github.com/goccy/go-json/internal/encoder/string.go
new file mode 100644
index 00000000..4abb8416
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/string.go
@@ -0,0 +1,483 @@
+// This files's string processing codes are inspired by https://github.com/segmentio/encoding.
+// The license notation is as follows.
+//
+// # MIT License
+//
+// Copyright (c) 2019 Segment.io, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+package encoder
+
+import (
+ "math/bits"
+ "reflect"
+ "unsafe"
+)
+
+const (
+ lsb = 0x0101010101010101
+ msb = 0x8080808080808080
+)
+
+var hex = "0123456789abcdef"
+
+//nolint:govet
+func stringToUint64Slice(s string) []uint64 {
+ return *(*[]uint64)(unsafe.Pointer(&reflect.SliceHeader{
+ Data: ((*reflect.StringHeader)(unsafe.Pointer(&s))).Data,
+ Len: len(s) / 8,
+ Cap: len(s) / 8,
+ }))
+}
+
+func AppendString(ctx *RuntimeContext, buf []byte, s string) []byte {
+ if ctx.Option.Flag&HTMLEscapeOption != 0 {
+ if ctx.Option.Flag&NormalizeUTF8Option != 0 {
+ return appendNormalizedHTMLString(buf, s)
+ }
+ return appendHTMLString(buf, s)
+ }
+ if ctx.Option.Flag&NormalizeUTF8Option != 0 {
+ return appendNormalizedString(buf, s)
+ }
+ return appendString(buf, s)
+}
+
+func appendNormalizedHTMLString(buf []byte, s string) []byte {
+ valLen := len(s)
+ if valLen == 0 {
+ return append(buf, `""`...)
+ }
+ buf = append(buf, '"')
+ var (
+ i, j int
+ )
+ if valLen >= 8 {
+ chunks := stringToUint64Slice(s)
+ for _, n := range chunks {
+ // combine masks before checking for the MSB of each byte. We include
+ // `n` in the mask to check whether any of the *input* byte MSBs were
+ // set (i.e. the byte was outside the ASCII range).
+ mask := n | (n - (lsb * 0x20)) |
+ ((n ^ (lsb * '"')) - lsb) |
+ ((n ^ (lsb * '\\')) - lsb) |
+ ((n ^ (lsb * '<')) - lsb) |
+ ((n ^ (lsb * '>')) - lsb) |
+ ((n ^ (lsb * '&')) - lsb)
+ if (mask & msb) != 0 {
+ j = bits.TrailingZeros64(mask&msb) / 8
+ goto ESCAPE_END
+ }
+ }
+ for i := len(chunks) * 8; i < valLen; i++ {
+ if needEscapeHTMLNormalizeUTF8[s[i]] {
+ j = i
+ goto ESCAPE_END
+ }
+ }
+ // no found any escape characters.
+ return append(append(buf, s...), '"')
+ }
+ESCAPE_END:
+ for j < valLen {
+ c := s[j]
+
+ if !needEscapeHTMLNormalizeUTF8[c] {
+ // fast path: most of the time, printable ascii characters are used
+ j++
+ continue
+ }
+
+ switch c {
+ case '\\', '"':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, '\\', c)
+ i = j + 1
+ j = j + 1
+ continue
+
+ case '\n':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, '\\', 'n')
+ i = j + 1
+ j = j + 1
+ continue
+
+ case '\r':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, '\\', 'r')
+ i = j + 1
+ j = j + 1
+ continue
+
+ case '\t':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, '\\', 't')
+ i = j + 1
+ j = j + 1
+ continue
+
+ case '<', '>', '&':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, `\u00`...)
+ buf = append(buf, hex[c>>4], hex[c&0xF])
+ i = j + 1
+ j = j + 1
+ continue
+
+ case 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, // 0x00-0x0F
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F: // 0x10-0x1F
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, `\u00`...)
+ buf = append(buf, hex[c>>4], hex[c&0xF])
+ i = j + 1
+ j = j + 1
+ continue
+ }
+ state, size := decodeRuneInString(s[j:])
+ switch state {
+ case runeErrorState:
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, `\ufffd`...)
+ i = j + 1
+ j = j + 1
+ continue
+ // U+2028 is LINE SEPARATOR.
+ // U+2029 is PARAGRAPH SEPARATOR.
+ // They are both technically valid characters in JSON strings,
+ // but don't work in JSONP, which has to be evaluated as JavaScript,
+ // and can lead to security holes there. It is valid JSON to
+ // escape them, so we do so unconditionally.
+ // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
+ case lineSepState:
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, `\u2028`...)
+ i = j + 3
+ j = j + 3
+ continue
+ case paragraphSepState:
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, `\u2029`...)
+ i = j + 3
+ j = j + 3
+ continue
+ }
+ j += size
+ }
+
+ return append(append(buf, s[i:]...), '"')
+}
+
+func appendHTMLString(buf []byte, s string) []byte {
+ valLen := len(s)
+ if valLen == 0 {
+ return append(buf, `""`...)
+ }
+ buf = append(buf, '"')
+ var (
+ i, j int
+ )
+ if valLen >= 8 {
+ chunks := stringToUint64Slice(s)
+ for _, n := range chunks {
+ // combine masks before checking for the MSB of each byte. We include
+ // `n` in the mask to check whether any of the *input* byte MSBs were
+ // set (i.e. the byte was outside the ASCII range).
+ mask := n | (n - (lsb * 0x20)) |
+ ((n ^ (lsb * '"')) - lsb) |
+ ((n ^ (lsb * '\\')) - lsb) |
+ ((n ^ (lsb * '<')) - lsb) |
+ ((n ^ (lsb * '>')) - lsb) |
+ ((n ^ (lsb * '&')) - lsb)
+ if (mask & msb) != 0 {
+ j = bits.TrailingZeros64(mask&msb) / 8
+ goto ESCAPE_END
+ }
+ }
+ for i := len(chunks) * 8; i < valLen; i++ {
+ if needEscapeHTML[s[i]] {
+ j = i
+ goto ESCAPE_END
+ }
+ }
+ // no found any escape characters.
+ return append(append(buf, s...), '"')
+ }
+ESCAPE_END:
+ for j < valLen {
+ c := s[j]
+
+ if !needEscapeHTML[c] {
+ // fast path: most of the time, printable ascii characters are used
+ j++
+ continue
+ }
+
+ switch c {
+ case '\\', '"':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, '\\', c)
+ i = j + 1
+ j = j + 1
+ continue
+
+ case '\n':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, '\\', 'n')
+ i = j + 1
+ j = j + 1
+ continue
+
+ case '\r':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, '\\', 'r')
+ i = j + 1
+ j = j + 1
+ continue
+
+ case '\t':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, '\\', 't')
+ i = j + 1
+ j = j + 1
+ continue
+
+ case '<', '>', '&':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, `\u00`...)
+ buf = append(buf, hex[c>>4], hex[c&0xF])
+ i = j + 1
+ j = j + 1
+ continue
+
+ case 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, // 0x00-0x0F
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F: // 0x10-0x1F
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, `\u00`...)
+ buf = append(buf, hex[c>>4], hex[c&0xF])
+ i = j + 1
+ j = j + 1
+ continue
+ }
+ j++
+ }
+
+ return append(append(buf, s[i:]...), '"')
+}
+
+func appendNormalizedString(buf []byte, s string) []byte {
+ valLen := len(s)
+ if valLen == 0 {
+ return append(buf, `""`...)
+ }
+ buf = append(buf, '"')
+ var (
+ i, j int
+ )
+ if valLen >= 8 {
+ chunks := stringToUint64Slice(s)
+ for _, n := range chunks {
+ // combine masks before checking for the MSB of each byte. We include
+ // `n` in the mask to check whether any of the *input* byte MSBs were
+ // set (i.e. the byte was outside the ASCII range).
+ mask := n | (n - (lsb * 0x20)) |
+ ((n ^ (lsb * '"')) - lsb) |
+ ((n ^ (lsb * '\\')) - lsb)
+ if (mask & msb) != 0 {
+ j = bits.TrailingZeros64(mask&msb) / 8
+ goto ESCAPE_END
+ }
+ }
+ valLen := len(s)
+ for i := len(chunks) * 8; i < valLen; i++ {
+ if needEscapeNormalizeUTF8[s[i]] {
+ j = i
+ goto ESCAPE_END
+ }
+ }
+ return append(append(buf, s...), '"')
+ }
+ESCAPE_END:
+ for j < valLen {
+ c := s[j]
+
+ if !needEscapeNormalizeUTF8[c] {
+ // fast path: most of the time, printable ascii characters are used
+ j++
+ continue
+ }
+
+ switch c {
+ case '\\', '"':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, '\\', c)
+ i = j + 1
+ j = j + 1
+ continue
+
+ case '\n':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, '\\', 'n')
+ i = j + 1
+ j = j + 1
+ continue
+
+ case '\r':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, '\\', 'r')
+ i = j + 1
+ j = j + 1
+ continue
+
+ case '\t':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, '\\', 't')
+ i = j + 1
+ j = j + 1
+ continue
+
+ case 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, // 0x00-0x0F
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F: // 0x10-0x1F
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, `\u00`...)
+ buf = append(buf, hex[c>>4], hex[c&0xF])
+ i = j + 1
+ j = j + 1
+ continue
+ }
+
+ state, size := decodeRuneInString(s[j:])
+ switch state {
+ case runeErrorState:
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, `\ufffd`...)
+ i = j + 1
+ j = j + 1
+ continue
+ // U+2028 is LINE SEPARATOR.
+ // U+2029 is PARAGRAPH SEPARATOR.
+ // They are both technically valid characters in JSON strings,
+ // but don't work in JSONP, which has to be evaluated as JavaScript,
+ // and can lead to security holes there. It is valid JSON to
+ // escape them, so we do so unconditionally.
+ // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
+ case lineSepState:
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, `\u2028`...)
+ i = j + 3
+ j = j + 3
+ continue
+ case paragraphSepState:
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, `\u2029`...)
+ i = j + 3
+ j = j + 3
+ continue
+ }
+ j += size
+ }
+
+ return append(append(buf, s[i:]...), '"')
+}
+
+func appendString(buf []byte, s string) []byte {
+ valLen := len(s)
+ if valLen == 0 {
+ return append(buf, `""`...)
+ }
+ buf = append(buf, '"')
+ var (
+ i, j int
+ )
+ if valLen >= 8 {
+ chunks := stringToUint64Slice(s)
+ for _, n := range chunks {
+ // combine masks before checking for the MSB of each byte. We include
+ // `n` in the mask to check whether any of the *input* byte MSBs were
+ // set (i.e. the byte was outside the ASCII range).
+ mask := n | (n - (lsb * 0x20)) |
+ ((n ^ (lsb * '"')) - lsb) |
+ ((n ^ (lsb * '\\')) - lsb)
+ if (mask & msb) != 0 {
+ j = bits.TrailingZeros64(mask&msb) / 8
+ goto ESCAPE_END
+ }
+ }
+ valLen := len(s)
+ for i := len(chunks) * 8; i < valLen; i++ {
+ if needEscape[s[i]] {
+ j = i
+ goto ESCAPE_END
+ }
+ }
+ return append(append(buf, s...), '"')
+ }
+ESCAPE_END:
+ for j < valLen {
+ c := s[j]
+
+ if !needEscape[c] {
+ // fast path: most of the time, printable ascii characters are used
+ j++
+ continue
+ }
+
+ switch c {
+ case '\\', '"':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, '\\', c)
+ i = j + 1
+ j = j + 1
+ continue
+
+ case '\n':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, '\\', 'n')
+ i = j + 1
+ j = j + 1
+ continue
+
+ case '\r':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, '\\', 'r')
+ i = j + 1
+ j = j + 1
+ continue
+
+ case '\t':
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, '\\', 't')
+ i = j + 1
+ j = j + 1
+ continue
+
+ case 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0B, 0x0C, 0x0E, 0x0F, // 0x00-0x0F
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F: // 0x10-0x1F
+ buf = append(buf, s[i:j]...)
+ buf = append(buf, `\u00`...)
+ buf = append(buf, hex[c>>4], hex[c&0xF])
+ i = j + 1
+ j = j + 1
+ continue
+ }
+ j++
+ }
+
+ return append(append(buf, s[i:]...), '"')
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/string_table.go b/vendor/github.com/goccy/go-json/internal/encoder/string_table.go
new file mode 100644
index 00000000..ebe42c92
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/string_table.go
@@ -0,0 +1,415 @@
+package encoder
+
+var needEscapeHTMLNormalizeUTF8 = [256]bool{
+ '"': true,
+ '&': true,
+ '<': true,
+ '>': true,
+ '\\': true,
+ 0x00: true,
+ 0x01: true,
+ 0x02: true,
+ 0x03: true,
+ 0x04: true,
+ 0x05: true,
+ 0x06: true,
+ 0x07: true,
+ 0x08: true,
+ 0x09: true,
+ 0x0a: true,
+ 0x0b: true,
+ 0x0c: true,
+ 0x0d: true,
+ 0x0e: true,
+ 0x0f: true,
+ 0x10: true,
+ 0x11: true,
+ 0x12: true,
+ 0x13: true,
+ 0x14: true,
+ 0x15: true,
+ 0x16: true,
+ 0x17: true,
+ 0x18: true,
+ 0x19: true,
+ 0x1a: true,
+ 0x1b: true,
+ 0x1c: true,
+ 0x1d: true,
+ 0x1e: true,
+ 0x1f: true,
+ /* 0x20 - 0x7f */
+ 0x80: true,
+ 0x81: true,
+ 0x82: true,
+ 0x83: true,
+ 0x84: true,
+ 0x85: true,
+ 0x86: true,
+ 0x87: true,
+ 0x88: true,
+ 0x89: true,
+ 0x8a: true,
+ 0x8b: true,
+ 0x8c: true,
+ 0x8d: true,
+ 0x8e: true,
+ 0x8f: true,
+ 0x90: true,
+ 0x91: true,
+ 0x92: true,
+ 0x93: true,
+ 0x94: true,
+ 0x95: true,
+ 0x96: true,
+ 0x97: true,
+ 0x98: true,
+ 0x99: true,
+ 0x9a: true,
+ 0x9b: true,
+ 0x9c: true,
+ 0x9d: true,
+ 0x9e: true,
+ 0x9f: true,
+ 0xa0: true,
+ 0xa1: true,
+ 0xa2: true,
+ 0xa3: true,
+ 0xa4: true,
+ 0xa5: true,
+ 0xa6: true,
+ 0xa7: true,
+ 0xa8: true,
+ 0xa9: true,
+ 0xaa: true,
+ 0xab: true,
+ 0xac: true,
+ 0xad: true,
+ 0xae: true,
+ 0xaf: true,
+ 0xb0: true,
+ 0xb1: true,
+ 0xb2: true,
+ 0xb3: true,
+ 0xb4: true,
+ 0xb5: true,
+ 0xb6: true,
+ 0xb7: true,
+ 0xb8: true,
+ 0xb9: true,
+ 0xba: true,
+ 0xbb: true,
+ 0xbc: true,
+ 0xbd: true,
+ 0xbe: true,
+ 0xbf: true,
+ 0xc0: true,
+ 0xc1: true,
+ 0xc2: true,
+ 0xc3: true,
+ 0xc4: true,
+ 0xc5: true,
+ 0xc6: true,
+ 0xc7: true,
+ 0xc8: true,
+ 0xc9: true,
+ 0xca: true,
+ 0xcb: true,
+ 0xcc: true,
+ 0xcd: true,
+ 0xce: true,
+ 0xcf: true,
+ 0xd0: true,
+ 0xd1: true,
+ 0xd2: true,
+ 0xd3: true,
+ 0xd4: true,
+ 0xd5: true,
+ 0xd6: true,
+ 0xd7: true,
+ 0xd8: true,
+ 0xd9: true,
+ 0xda: true,
+ 0xdb: true,
+ 0xdc: true,
+ 0xdd: true,
+ 0xde: true,
+ 0xdf: true,
+ 0xe0: true,
+ 0xe1: true,
+ 0xe2: true,
+ 0xe3: true,
+ 0xe4: true,
+ 0xe5: true,
+ 0xe6: true,
+ 0xe7: true,
+ 0xe8: true,
+ 0xe9: true,
+ 0xea: true,
+ 0xeb: true,
+ 0xec: true,
+ 0xed: true,
+ 0xee: true,
+ 0xef: true,
+ 0xf0: true,
+ 0xf1: true,
+ 0xf2: true,
+ 0xf3: true,
+ 0xf4: true,
+ 0xf5: true,
+ 0xf6: true,
+ 0xf7: true,
+ 0xf8: true,
+ 0xf9: true,
+ 0xfa: true,
+ 0xfb: true,
+ 0xfc: true,
+ 0xfd: true,
+ 0xfe: true,
+ 0xff: true,
+}
+
+var needEscapeNormalizeUTF8 = [256]bool{
+ '"': true,
+ '\\': true,
+ 0x00: true,
+ 0x01: true,
+ 0x02: true,
+ 0x03: true,
+ 0x04: true,
+ 0x05: true,
+ 0x06: true,
+ 0x07: true,
+ 0x08: true,
+ 0x09: true,
+ 0x0a: true,
+ 0x0b: true,
+ 0x0c: true,
+ 0x0d: true,
+ 0x0e: true,
+ 0x0f: true,
+ 0x10: true,
+ 0x11: true,
+ 0x12: true,
+ 0x13: true,
+ 0x14: true,
+ 0x15: true,
+ 0x16: true,
+ 0x17: true,
+ 0x18: true,
+ 0x19: true,
+ 0x1a: true,
+ 0x1b: true,
+ 0x1c: true,
+ 0x1d: true,
+ 0x1e: true,
+ 0x1f: true,
+ /* 0x20 - 0x7f */
+ 0x80: true,
+ 0x81: true,
+ 0x82: true,
+ 0x83: true,
+ 0x84: true,
+ 0x85: true,
+ 0x86: true,
+ 0x87: true,
+ 0x88: true,
+ 0x89: true,
+ 0x8a: true,
+ 0x8b: true,
+ 0x8c: true,
+ 0x8d: true,
+ 0x8e: true,
+ 0x8f: true,
+ 0x90: true,
+ 0x91: true,
+ 0x92: true,
+ 0x93: true,
+ 0x94: true,
+ 0x95: true,
+ 0x96: true,
+ 0x97: true,
+ 0x98: true,
+ 0x99: true,
+ 0x9a: true,
+ 0x9b: true,
+ 0x9c: true,
+ 0x9d: true,
+ 0x9e: true,
+ 0x9f: true,
+ 0xa0: true,
+ 0xa1: true,
+ 0xa2: true,
+ 0xa3: true,
+ 0xa4: true,
+ 0xa5: true,
+ 0xa6: true,
+ 0xa7: true,
+ 0xa8: true,
+ 0xa9: true,
+ 0xaa: true,
+ 0xab: true,
+ 0xac: true,
+ 0xad: true,
+ 0xae: true,
+ 0xaf: true,
+ 0xb0: true,
+ 0xb1: true,
+ 0xb2: true,
+ 0xb3: true,
+ 0xb4: true,
+ 0xb5: true,
+ 0xb6: true,
+ 0xb7: true,
+ 0xb8: true,
+ 0xb9: true,
+ 0xba: true,
+ 0xbb: true,
+ 0xbc: true,
+ 0xbd: true,
+ 0xbe: true,
+ 0xbf: true,
+ 0xc0: true,
+ 0xc1: true,
+ 0xc2: true,
+ 0xc3: true,
+ 0xc4: true,
+ 0xc5: true,
+ 0xc6: true,
+ 0xc7: true,
+ 0xc8: true,
+ 0xc9: true,
+ 0xca: true,
+ 0xcb: true,
+ 0xcc: true,
+ 0xcd: true,
+ 0xce: true,
+ 0xcf: true,
+ 0xd0: true,
+ 0xd1: true,
+ 0xd2: true,
+ 0xd3: true,
+ 0xd4: true,
+ 0xd5: true,
+ 0xd6: true,
+ 0xd7: true,
+ 0xd8: true,
+ 0xd9: true,
+ 0xda: true,
+ 0xdb: true,
+ 0xdc: true,
+ 0xdd: true,
+ 0xde: true,
+ 0xdf: true,
+ 0xe0: true,
+ 0xe1: true,
+ 0xe2: true,
+ 0xe3: true,
+ 0xe4: true,
+ 0xe5: true,
+ 0xe6: true,
+ 0xe7: true,
+ 0xe8: true,
+ 0xe9: true,
+ 0xea: true,
+ 0xeb: true,
+ 0xec: true,
+ 0xed: true,
+ 0xee: true,
+ 0xef: true,
+ 0xf0: true,
+ 0xf1: true,
+ 0xf2: true,
+ 0xf3: true,
+ 0xf4: true,
+ 0xf5: true,
+ 0xf6: true,
+ 0xf7: true,
+ 0xf8: true,
+ 0xf9: true,
+ 0xfa: true,
+ 0xfb: true,
+ 0xfc: true,
+ 0xfd: true,
+ 0xfe: true,
+ 0xff: true,
+}
+
+var needEscapeHTML = [256]bool{
+ '"': true,
+ '&': true,
+ '<': true,
+ '>': true,
+ '\\': true,
+ 0x00: true,
+ 0x01: true,
+ 0x02: true,
+ 0x03: true,
+ 0x04: true,
+ 0x05: true,
+ 0x06: true,
+ 0x07: true,
+ 0x08: true,
+ 0x09: true,
+ 0x0a: true,
+ 0x0b: true,
+ 0x0c: true,
+ 0x0d: true,
+ 0x0e: true,
+ 0x0f: true,
+ 0x10: true,
+ 0x11: true,
+ 0x12: true,
+ 0x13: true,
+ 0x14: true,
+ 0x15: true,
+ 0x16: true,
+ 0x17: true,
+ 0x18: true,
+ 0x19: true,
+ 0x1a: true,
+ 0x1b: true,
+ 0x1c: true,
+ 0x1d: true,
+ 0x1e: true,
+ 0x1f: true,
+ /* 0x20 - 0xff */
+}
+
+var needEscape = [256]bool{
+ '"': true,
+ '\\': true,
+ 0x00: true,
+ 0x01: true,
+ 0x02: true,
+ 0x03: true,
+ 0x04: true,
+ 0x05: true,
+ 0x06: true,
+ 0x07: true,
+ 0x08: true,
+ 0x09: true,
+ 0x0a: true,
+ 0x0b: true,
+ 0x0c: true,
+ 0x0d: true,
+ 0x0e: true,
+ 0x0f: true,
+ 0x10: true,
+ 0x11: true,
+ 0x12: true,
+ 0x13: true,
+ 0x14: true,
+ 0x15: true,
+ 0x16: true,
+ 0x17: true,
+ 0x18: true,
+ 0x19: true,
+ 0x1a: true,
+ 0x1b: true,
+ 0x1c: true,
+ 0x1d: true,
+ 0x1e: true,
+ 0x1f: true,
+ /* 0x20 - 0xff */
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go
new file mode 100644
index 00000000..82b6dd47
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go
@@ -0,0 +1,41 @@
+package vm
+
+import (
+ "fmt"
+ "io"
+
+ "github.com/goccy/go-json/internal/encoder"
+)
+
+func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
+ defer func() {
+ var code *encoder.Opcode
+ if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
+ code = codeSet.EscapeKeyCode
+ } else {
+ code = codeSet.NoescapeKeyCode
+ }
+ if wc := ctx.Option.DebugDOTOut; wc != nil {
+ _, _ = io.WriteString(wc, code.DumpDOT())
+ wc.Close()
+ ctx.Option.DebugDOTOut = nil
+ }
+
+ if err := recover(); err != nil {
+ w := ctx.Option.DebugOut
+ fmt.Fprintln(w, "=============[DEBUG]===============")
+ fmt.Fprintln(w, "* [TYPE]")
+ fmt.Fprintln(w, codeSet.Type)
+ fmt.Fprintf(w, "\n")
+ fmt.Fprintln(w, "* [ALL OPCODE]")
+ fmt.Fprintln(w, code.Dump())
+ fmt.Fprintf(w, "\n")
+ fmt.Fprintln(w, "* [CONTEXT]")
+ fmt.Fprintf(w, "%+v\n", ctx)
+ fmt.Fprintln(w, "===================================")
+ panic(err)
+ }
+ }()
+
+ return Run(ctx, b, codeSet)
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go b/vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go
new file mode 100644
index 00000000..65252b4a
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go
@@ -0,0 +1,9 @@
+package vm
+
+import (
+ // HACK: compile order
+ // `vm`, `vm_indent`, `vm_color`, `vm_color_indent` packages uses a lot of memory to compile,
+ // so forcibly make dependencies and avoid compiling in concurrent.
+ // dependency order: vm => vm_indent => vm_color => vm_color_indent
+ _ "github.com/goccy/go-json/internal/encoder/vm_indent"
+)
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm/util.go b/vendor/github.com/goccy/go-json/internal/encoder/vm/util.go
new file mode 100644
index 00000000..86291d7b
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/vm/util.go
@@ -0,0 +1,207 @@
+package vm
+
+import (
+ "encoding/json"
+ "fmt"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/encoder"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+const uintptrSize = 4 << (^uintptr(0) >> 63)
+
+var (
+ appendInt = encoder.AppendInt
+ appendUint = encoder.AppendUint
+ appendFloat32 = encoder.AppendFloat32
+ appendFloat64 = encoder.AppendFloat64
+ appendString = encoder.AppendString
+ appendByteSlice = encoder.AppendByteSlice
+ appendNumber = encoder.AppendNumber
+ errUnsupportedValue = encoder.ErrUnsupportedValue
+ errUnsupportedFloat = encoder.ErrUnsupportedFloat
+ mapiterinit = encoder.MapIterInit
+ mapiterkey = encoder.MapIterKey
+ mapitervalue = encoder.MapIterValue
+ mapiternext = encoder.MapIterNext
+ maplen = encoder.MapLen
+)
+
+type emptyInterface struct {
+ typ *runtime.Type
+ ptr unsafe.Pointer
+}
+
+type nonEmptyInterface struct {
+ itab *struct {
+ ityp *runtime.Type // static interface type
+ typ *runtime.Type // dynamic concrete type
+ // unused fields...
+ }
+ ptr unsafe.Pointer
+}
+
+func errUnimplementedOp(op encoder.OpType) error {
+ return fmt.Errorf("encoder: opcode %s has not been implemented", op)
+}
+
+func load(base uintptr, idx uint32) uintptr {
+ addr := base + uintptr(idx)
+ return **(**uintptr)(unsafe.Pointer(&addr))
+}
+
+func store(base uintptr, idx uint32, p uintptr) {
+ addr := base + uintptr(idx)
+ **(**uintptr)(unsafe.Pointer(&addr)) = p
+}
+
+func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr {
+ addr := base + uintptr(idx)
+ p := **(**uintptr)(unsafe.Pointer(&addr))
+ for i := uint8(0); i < ptrNum; i++ {
+ if p == 0 {
+ return 0
+ }
+ p = ptrToPtr(p)
+ }
+ return p
+}
+
+func ptrToUint64(p uintptr, bitSize uint8) uint64 {
+ switch bitSize {
+ case 8:
+ return (uint64)(**(**uint8)(unsafe.Pointer(&p)))
+ case 16:
+ return (uint64)(**(**uint16)(unsafe.Pointer(&p)))
+ case 32:
+ return (uint64)(**(**uint32)(unsafe.Pointer(&p)))
+ case 64:
+ return **(**uint64)(unsafe.Pointer(&p))
+ }
+ return 0
+}
+func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) }
+func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) }
+func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) }
+func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) }
+func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) }
+func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) }
+func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) }
+func ptrToPtr(p uintptr) uintptr {
+ return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
+}
+func ptrToNPtr(p uintptr, ptrNum uint8) uintptr {
+ for i := uint8(0); i < ptrNum; i++ {
+ if p == 0 {
+ return 0
+ }
+ p = ptrToPtr(p)
+ }
+ return p
+}
+
+func ptrToUnsafePtr(p uintptr) unsafe.Pointer {
+ return *(*unsafe.Pointer)(unsafe.Pointer(&p))
+}
+func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} {
+ return *(*interface{})(unsafe.Pointer(&emptyInterface{
+ typ: code.Type,
+ ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
+ }))
+}
+
+func appendBool(_ *encoder.RuntimeContext, b []byte, v bool) []byte {
+ if v {
+ return append(b, "true"...)
+ }
+ return append(b, "false"...)
+}
+
+func appendNull(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, "null"...)
+}
+
+func appendComma(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, ',')
+}
+
+func appendNullComma(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, "null,"...)
+}
+
+func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
+ last := len(b) - 1
+ b[last] = ':'
+ return b
+}
+
+func appendMapKeyValue(_ *encoder.RuntimeContext, _ *encoder.Opcode, b, key, value []byte) []byte {
+ b = append(b, key...)
+ b[len(b)-1] = ':'
+ return append(b, value...)
+}
+
+func appendMapEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
+ b[len(b)-1] = '}'
+ b = append(b, ',')
+ return b
+}
+
+func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) {
+ return encoder.AppendMarshalJSON(ctx, code, b, v)
+}
+
+func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) {
+ return encoder.AppendMarshalText(ctx, code, b, v)
+}
+
+func appendArrayHead(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
+ return append(b, '[')
+}
+
+func appendArrayEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
+ last := len(b) - 1
+ b[last] = ']'
+ return append(b, ',')
+}
+
+func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, '[', ']', ',')
+}
+
+func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, '{', '}', ',')
+}
+
+func appendObjectEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
+ last := len(b) - 1
+ b[last] = '}'
+ return append(b, ',')
+}
+
+func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, '{')
+}
+
+func appendStructKey(_ *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ return append(b, code.Key...)
+}
+
+func appendStructEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
+ return append(b, '}', ',')
+}
+
+func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ last := len(b) - 1
+ if b[last] == ',' {
+ b[last] = '}'
+ return appendComma(ctx, b)
+ }
+ return appendStructEnd(ctx, code, b)
+}
+
+func restoreIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, _ uintptr) {}
+func storeIndent(_ uintptr, _ *encoder.Opcode, _ uintptr) {}
+func appendMapKeyIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b }
+func appendArrayElemIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b }
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go
new file mode 100644
index 00000000..645d20f9
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go
@@ -0,0 +1,4859 @@
+// Code generated by internal/cmd/generator. DO NOT EDIT!
+package vm
+
+import (
+ "math"
+ "reflect"
+ "sort"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/encoder"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
+ recursiveLevel := 0
+ ptrOffset := uintptr(0)
+ ctxptr := ctx.Ptr()
+ var code *encoder.Opcode
+ if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
+ code = codeSet.EscapeKeyCode
+ } else {
+ code = codeSet.NoescapeKeyCode
+ }
+
+ for {
+ switch code.Op {
+ default:
+ return nil, errUnimplementedOp(code.Op)
+ case encoder.OpPtr:
+ p := load(ctxptr, code.Idx)
+ code = code.Next
+ store(ctxptr, code.Idx, ptrToPtr(p))
+ case encoder.OpIntPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpInt:
+ b = appendInt(ctx, b, load(ctxptr, code.Idx), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpUintPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpUint:
+ b = appendUint(ctx, b, load(ctxptr, code.Idx), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpIntString:
+ b = append(b, '"')
+ b = appendInt(ctx, b, load(ctxptr, code.Idx), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpUintString:
+ b = append(b, '"')
+ b = appendUint(ctx, b, load(ctxptr, code.Idx), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpFloat32Ptr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ b = appendComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpFloat32:
+ b = appendFloat32(ctx, b, ptrToFloat32(load(ctxptr, code.Idx)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpFloat64Ptr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpFloat64:
+ v := ptrToFloat64(load(ctxptr, code.Idx))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStringPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpString:
+ b = appendString(ctx, b, ptrToString(load(ctxptr, code.Idx)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpBoolPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpBool:
+ b = appendBool(ctx, b, ptrToBool(load(ctxptr, code.Idx)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpBytesPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpBytes:
+ b = appendByteSlice(ctx, b, ptrToBytes(load(ctxptr, code.Idx)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpNumberPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpNumber:
+ bb, err := appendNumber(ctx, b, ptrToNumber(load(ctxptr, code.Idx)))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpInterfacePtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpInterface:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ if recursiveLevel > encoder.StartDetectingCyclesAfter {
+ for _, seen := range ctx.SeenPtr {
+ if p == seen {
+ return nil, errUnsupportedValue(code, p)
+ }
+ }
+ }
+ ctx.SeenPtr = append(ctx.SeenPtr, p)
+ var (
+ typ *runtime.Type
+ ifacePtr unsafe.Pointer
+ )
+ up := ptrToUnsafePtr(p)
+ if code.Flags&encoder.NonEmptyInterfaceFlags != 0 {
+ iface := (*nonEmptyInterface)(up)
+ ifacePtr = iface.ptr
+ if iface.itab != nil {
+ typ = iface.itab.typ
+ }
+ } else {
+ iface := (*emptyInterface)(up)
+ ifacePtr = iface.ptr
+ typ = iface.typ
+ }
+ if ifacePtr == nil {
+ isDirectedNil := typ != nil && typ.Kind() == reflect.Struct && !runtime.IfaceIndir(typ)
+ if !isDirectedNil {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ }
+ ctx.KeepRefs = append(ctx.KeepRefs, up)
+ ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ)))
+ if err != nil {
+ return nil, err
+ }
+
+ totalLength := uintptr(code.Length) + 3
+ nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3
+
+ var c *encoder.Opcode
+ if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
+ c = ifaceCodeSet.InterfaceEscapeKeyCode
+ } else {
+ c = ifaceCodeSet.InterfaceNoescapeKeyCode
+ }
+ curlen := uintptr(len(ctx.Ptrs))
+ offsetNum := ptrOffset / uintptrSize
+ oldOffset := ptrOffset
+ ptrOffset += totalLength * uintptrSize
+ oldBaseIndent := ctx.BaseIndent
+ ctx.BaseIndent += code.Indent
+
+ newLen := offsetNum + totalLength + nextTotalLength
+ if curlen < newLen {
+ ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
+ }
+ ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr
+
+ end := ifaceCodeSet.EndCode
+ store(ctxptr, c.Idx, uintptr(ifacePtr))
+ store(ctxptr, end.Idx, oldOffset)
+ store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
+ storeIndent(ctxptr, end, uintptr(oldBaseIndent))
+ code = c
+ recursiveLevel++
+ case encoder.OpInterfaceEnd:
+ recursiveLevel--
+
+ // restore ctxptr
+ offset := load(ctxptr, code.Idx)
+ restoreIndent(ctx, code, ctxptr)
+ ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1]
+
+ codePtr := load(ctxptr, code.ElemIdx)
+ code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr))
+ ctxptr = ctx.Ptr() + offset
+ ptrOffset = offset
+ case encoder.OpMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToPtr(p))
+ fallthrough
+ case encoder.OpMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToPtr(p))
+ fallthrough
+ case encoder.OpMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = append(b, `""`...)
+ b = appendComma(ctx, b)
+ code = code.Next
+ break
+ }
+ if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpSlicePtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpSlice:
+ p := load(ctxptr, code.Idx)
+ slice := ptrToSlice(p)
+ if p == 0 || slice.Data == nil {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.ElemIdx, 0)
+ store(ctxptr, code.Length, uintptr(slice.Len))
+ store(ctxptr, code.Idx, uintptr(slice.Data))
+ if slice.Len > 0 {
+ b = appendArrayHead(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, uintptr(slice.Data))
+ } else {
+ b = appendEmptyArray(ctx, b)
+ code = code.End.Next
+ }
+ case encoder.OpSliceElem:
+ idx := load(ctxptr, code.ElemIdx)
+ length := load(ctxptr, code.Length)
+ idx++
+ if idx < length {
+ b = appendArrayElemIndent(ctx, code, b)
+ store(ctxptr, code.ElemIdx, idx)
+ data := load(ctxptr, code.Idx)
+ size := uintptr(code.Size)
+ code = code.Next
+ store(ctxptr, code.Idx, data+idx*size)
+ } else {
+ b = appendArrayEnd(ctx, code, b)
+ code = code.End.Next
+ }
+ case encoder.OpArrayPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpArray:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ if code.Length > 0 {
+ b = appendArrayHead(ctx, code, b)
+ store(ctxptr, code.ElemIdx, 0)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ } else {
+ b = appendEmptyArray(ctx, b)
+ code = code.End.Next
+ }
+ case encoder.OpArrayElem:
+ idx := load(ctxptr, code.ElemIdx)
+ idx++
+ if idx < uintptr(code.Length) {
+ b = appendArrayElemIndent(ctx, code, b)
+ store(ctxptr, code.ElemIdx, idx)
+ p := load(ctxptr, code.Idx)
+ size := uintptr(code.Size)
+ code = code.Next
+ store(ctxptr, code.Idx, p+idx*size)
+ } else {
+ b = appendArrayEnd(ctx, code, b)
+ code = code.End.Next
+ }
+ case encoder.OpMapPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ uptr := ptrToUnsafePtr(p)
+ mlen := maplen(uptr)
+ if mlen <= 0 {
+ b = appendEmptyObject(ctx, b)
+ code = code.End.Next
+ break
+ }
+ b = appendStructHead(ctx, b)
+ unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0
+ mapCtx := encoder.NewMapContext(mlen, unorderedMap)
+ mapiterinit(code.Type, uptr, &mapCtx.Iter)
+ store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx)))
+ ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx))
+ if unorderedMap {
+ b = appendMapKeyIndent(ctx, code.Next, b)
+ } else {
+ mapCtx.Start = len(b)
+ mapCtx.First = len(b)
+ }
+ key := mapiterkey(&mapCtx.Iter)
+ store(ctxptr, code.Next.Idx, uintptr(key))
+ code = code.Next
+ case encoder.OpMapKey:
+ mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx)))
+ idx := mapCtx.Idx
+ idx++
+ if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
+ if idx < mapCtx.Len {
+ b = appendMapKeyIndent(ctx, code, b)
+ mapCtx.Idx = int(idx)
+ key := mapiterkey(&mapCtx.Iter)
+ store(ctxptr, code.Next.Idx, uintptr(key))
+ code = code.Next
+ } else {
+ b = appendObjectEnd(ctx, code, b)
+ encoder.ReleaseMapContext(mapCtx)
+ code = code.End.Next
+ }
+ } else {
+ mapCtx.Slice.Items[mapCtx.Idx].Value = b[mapCtx.Start:len(b)]
+ if idx < mapCtx.Len {
+ mapCtx.Idx = int(idx)
+ mapCtx.Start = len(b)
+ key := mapiterkey(&mapCtx.Iter)
+ store(ctxptr, code.Next.Idx, uintptr(key))
+ code = code.Next
+ } else {
+ code = code.End
+ }
+ }
+ case encoder.OpMapValue:
+ mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx)))
+ if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
+ b = appendColon(ctx, b)
+ } else {
+ mapCtx.Slice.Items[mapCtx.Idx].Key = b[mapCtx.Start:len(b)]
+ mapCtx.Start = len(b)
+ }
+ value := mapitervalue(&mapCtx.Iter)
+ store(ctxptr, code.Next.Idx, uintptr(value))
+ mapiternext(&mapCtx.Iter)
+ code = code.Next
+ case encoder.OpMapEnd:
+ // this operation only used by sorted map.
+ mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx)))
+ sort.Sort(mapCtx.Slice)
+ buf := mapCtx.Buf
+ for _, item := range mapCtx.Slice.Items {
+ buf = appendMapKeyValue(ctx, code, buf, item.Key, item.Value)
+ }
+ buf = appendMapEnd(ctx, code, buf)
+ b = b[:mapCtx.First]
+ b = append(b, buf...)
+ mapCtx.Buf = buf
+ encoder.ReleaseMapContext(mapCtx)
+ code = code.Next
+ case encoder.OpRecursivePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpRecursive:
+ ptr := load(ctxptr, code.Idx)
+ if ptr != 0 {
+ if recursiveLevel > encoder.StartDetectingCyclesAfter {
+ for _, seen := range ctx.SeenPtr {
+ if ptr == seen {
+ return nil, errUnsupportedValue(code, ptr)
+ }
+ }
+ }
+ }
+ ctx.SeenPtr = append(ctx.SeenPtr, ptr)
+ c := code.Jmp.Code
+ curlen := uintptr(len(ctx.Ptrs))
+ offsetNum := ptrOffset / uintptrSize
+ oldOffset := ptrOffset
+ ptrOffset += code.Jmp.CurLen * uintptrSize
+ oldBaseIndent := ctx.BaseIndent
+ indentDiffFromTop := c.Indent - 1
+ ctx.BaseIndent += code.Indent - indentDiffFromTop
+
+ newLen := offsetNum + code.Jmp.CurLen + code.Jmp.NextLen
+ if curlen < newLen {
+ ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
+ }
+ ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr
+
+ store(ctxptr, c.Idx, ptr)
+ store(ctxptr, c.End.Next.Idx, oldOffset)
+ store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
+ storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent))
+ code = c
+ recursiveLevel++
+ case encoder.OpRecursiveEnd:
+ recursiveLevel--
+
+ // restore ctxptr
+ restoreIndent(ctx, code, ctxptr)
+ offset := load(ctxptr, code.Idx)
+ ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1]
+
+ codePtr := load(ctxptr, code.ElemIdx)
+ code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr))
+ ctxptr = ctx.Ptr() + offset
+ ptrOffset = offset
+ case encoder.OpStructPtrHead:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHead:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if len(code.Key) > 0 {
+ if (code.Flags&encoder.IsTaggedKeyFlags) != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 {
+ b = appendStructKey(ctx, code, b)
+ }
+ }
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructPtrHeadOmitEmpty:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmpty:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ if p == 0 || (ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0) {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadInt:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadInt:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyInt:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyInt:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadIntString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadIntString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyIntString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyIntString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ u64 := ptrToUint64(p, code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadIntPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadIntPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendInt(ctx, b, p, code)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyIntPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyIntPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p, code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadIntPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadIntPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyIntPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyIntPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadUint:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadUint:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyUint:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyUint:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadUintString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadUintString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyUintString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyUintString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadUintPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadUintPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendUint(ctx, b, p, code)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyUintPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyUintPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p, code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadUintPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadUintPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyUintPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyUintPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadFloat32:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadFloat32:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat32:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat32:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadFloat32String:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadFloat32String:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat32String:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat32String:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadFloat64:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadFloat64:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat64:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat64:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v == 0 {
+ code = code.NextField
+ } else {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadFloat64String:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadFloat64String:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat64String:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat64String:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v == 0 {
+ code = code.NextField
+ } else {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNull(ctx, b)
+ b = appendComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToString(p + uintptr(code.Offset))
+ if v == "" {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadStringString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadStringString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p+uintptr(code.Offset)))))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyStringString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyStringString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToString(p + uintptr(code.Offset))
+ if v == "" {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, v)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadStringPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadStringPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, ptrToString(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyStringPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyStringPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadStringPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadStringPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyStringPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyStringPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadBool:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadBool:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBool:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBool:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructPtrHeadBoolString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadBoolString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBoolString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBoolString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructPtrHeadBoolPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadBoolPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendBool(ctx, b, ptrToBool(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBoolPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBoolPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadBytes:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadBytes:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBytes:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBytes:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToBytes(p + uintptr(code.Offset))
+ if len(v) == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadBytesPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadBytesPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBytesPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBytesPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadNumber:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadNumber:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyNumber:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyNumber:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v == "" {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadNumberString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadNumberString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyNumberString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyNumberString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v == "" {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadNumberPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadNumberPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyNumberPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyNumberPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadArray, encoder.OpStructPtrHeadSlice:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadArray, encoder.OpStructHeadSlice:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructPtrHeadOmitEmptyArray:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyArray:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructPtrHeadOmitEmptySlice:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptySlice:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ slice := ptrToSlice(p)
+ if slice.Len == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadArrayPtr, encoder.OpStructPtrHeadSlicePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadArrayPtr, encoder.OpStructHeadSlicePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.NextField
+ } else {
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadOmitEmptyArrayPtr, encoder.OpStructPtrHeadOmitEmptySlicePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyArrayPtr, encoder.OpStructHeadOmitEmptySlicePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ p = ptrToPtr(p + uintptr(code.Offset))
+ }
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructPtrHeadOmitEmptyMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ p = ptrToPtr(p + uintptr(code.Offset))
+ }
+ if maplen(ptrToUnsafePtr(p)) == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadMapPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadMapPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.NextField
+ break
+ }
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.NextField
+ } else {
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p, code.PtrNum)
+ }
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadOmitEmptyMapPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMapPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if p == 0 {
+ code = code.NextField
+ break
+ }
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p == 0 {
+ code = code.NextField
+ } else {
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p, code.PtrNum)
+ }
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON {
+ p = ptrToPtr(p)
+ }
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON {
+ p = ptrToPtr(p)
+ }
+ }
+ iface := ptrToInterface(code, p)
+ if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalJSON(ctx, code, b, iface)
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if p == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText {
+ p = ptrToPtr(p)
+ }
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText {
+ p = ptrToPtr(p)
+ }
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if p == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructField:
+ if code.Flags&encoder.IsTaggedKeyFlags != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 {
+ b = appendStructKey(ctx, code, b)
+ }
+ p := load(ctxptr, code.Idx) + uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmpty:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructFieldInt:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyInt:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldIntString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyIntString:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldIntPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendInt(ctx, b, p, code)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyIntPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p, code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldIntPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyIntPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldUint:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyUint:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldUintString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyUintString:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldUintPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendUint(ctx, b, p, code)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyUintPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p, code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldUintPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyUintPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat32:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat32:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat32String:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat32String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat64:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat64:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v != 0 {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat64String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat64String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v != 0 {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToString(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldStringString:
+ p := load(ctxptr, code.Idx)
+ s := ptrToString(p + uintptr(code.Offset))
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, s)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyStringString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToString(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, v)))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldStringPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, ptrToString(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyStringPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldStringPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyStringPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBool:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBool:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBoolString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBoolString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBoolPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendBool(ctx, b, ptrToBool(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBoolPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBytes:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBytes:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBytes(p + uintptr(code.Offset))
+ if len(v) > 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBytesPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBytesPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldNumber:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyNumber:
+ p := load(ctxptr, code.Idx)
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructFieldNumberString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyNumberString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldNumberPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyNumberPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructFieldNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ code = code.NextField
+ break
+ }
+ iface := ptrToInterface(code, p)
+ if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) {
+ code = code.NextField
+ break
+ }
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalJSON(ctx, code, b, iface)
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpStructFieldMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructFieldMarshalText:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyMarshalText:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ code = code.NextField
+ break
+ }
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpStructFieldMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructFieldArray:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyArray:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldArrayPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyArrayPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructFieldSlice:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptySlice:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ slice := ptrToSlice(p)
+ if slice.Len == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructFieldSlicePtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptySlicePtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructFieldMap:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToPtr(p + uintptr(code.Offset))
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyMap:
+ p := load(ctxptr, code.Idx)
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p == 0 || maplen(ptrToUnsafePtr(p)) == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructFieldMapPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p != 0 {
+ p = ptrToNPtr(p, code.PtrNum)
+ }
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyMapPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p != 0 {
+ p = ptrToNPtr(p, code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructFieldStruct:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyStruct:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructEnd:
+ b = appendStructEndSkipLast(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndInt:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyInt:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndIntString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyIntString:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndIntPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendInt(ctx, b, p, code)
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyIntPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p, code)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndIntPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyIntPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndUint:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyUint:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndUintString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyUintString:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndUintPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendUint(ctx, b, p, code)
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyUintPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p, code)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndUintPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyUintPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat32:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat32:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat32String:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat32String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat32Ptr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat32PtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat64:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat64:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v != 0 {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat64String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat64String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v != 0 {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat64Ptr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ break
+ }
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat64PtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToString(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndStringString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ s := ptrToString(p + uintptr(code.Offset))
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, s)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyStringString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToString(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, v)))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndStringPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, ptrToString(p))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyStringPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndStringPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyStringPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBool:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBool:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBoolString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBoolString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBoolPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendBool(ctx, b, ptrToBool(p))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBoolPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBoolPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBytes:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBytes:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBytes(p + uintptr(code.Offset))
+ if len(v) > 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBytesPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBytesPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndNumber:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = appendStructEnd(ctx, code, bb)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyNumber:
+ p := load(ctxptr, code.Idx)
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = appendStructEnd(ctx, code, bb)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndNumberString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyNumberString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndNumberPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyNumberPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendStructEnd(ctx, code, bb)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndNumberPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpEnd:
+ goto END
+ }
+ }
+END:
+ return b, nil
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go
new file mode 100644
index 00000000..925f61ed
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go
@@ -0,0 +1,35 @@
+package vm_color
+
+import (
+ "fmt"
+
+ "github.com/goccy/go-json/internal/encoder"
+)
+
+func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
+ var code *encoder.Opcode
+ if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
+ code = codeSet.EscapeKeyCode
+ } else {
+ code = codeSet.NoescapeKeyCode
+ }
+
+ defer func() {
+ if err := recover(); err != nil {
+ w := ctx.Option.DebugOut
+ fmt.Fprintln(w, "=============[DEBUG]===============")
+ fmt.Fprintln(w, "* [TYPE]")
+ fmt.Fprintln(w, codeSet.Type)
+ fmt.Fprintf(w, "\n")
+ fmt.Fprintln(w, "* [ALL OPCODE]")
+ fmt.Fprintln(w, code.Dump())
+ fmt.Fprintf(w, "\n")
+ fmt.Fprintln(w, "* [CONTEXT]")
+ fmt.Fprintf(w, "%+v\n", ctx)
+ fmt.Fprintln(w, "===================================")
+ panic(err)
+ }
+ }()
+
+ return Run(ctx, b, codeSet)
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go
new file mode 100644
index 00000000..12ec56c5
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go
@@ -0,0 +1,9 @@
+package vm_color
+
+import (
+ // HACK: compile order
+ // `vm`, `vm_indent`, `vm_color`, `vm_color_indent` packages uses a lot of memory to compile,
+ // so forcibly make dependencies and avoid compiling in concurrent.
+ // dependency order: vm => vm_indent => vm_color => vm_color_indent
+ _ "github.com/goccy/go-json/internal/encoder/vm_color_indent"
+)
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go
new file mode 100644
index 00000000..33f29aee
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go
@@ -0,0 +1,274 @@
+package vm_color
+
+import (
+ "encoding/json"
+ "fmt"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/encoder"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+const uintptrSize = 4 << (^uintptr(0) >> 63)
+
+var (
+ errUnsupportedValue = encoder.ErrUnsupportedValue
+ errUnsupportedFloat = encoder.ErrUnsupportedFloat
+ mapiterinit = encoder.MapIterInit
+ mapiterkey = encoder.MapIterKey
+ mapitervalue = encoder.MapIterValue
+ mapiternext = encoder.MapIterNext
+ maplen = encoder.MapLen
+)
+
+type emptyInterface struct {
+ typ *runtime.Type
+ ptr unsafe.Pointer
+}
+
+type nonEmptyInterface struct {
+ itab *struct {
+ ityp *runtime.Type // static interface type
+ typ *runtime.Type // dynamic concrete type
+ // unused fields...
+ }
+ ptr unsafe.Pointer
+}
+
+func errUnimplementedOp(op encoder.OpType) error {
+ return fmt.Errorf("encoder: opcode %s has not been implemented", op)
+}
+
+func load(base uintptr, idx uint32) uintptr {
+ addr := base + uintptr(idx)
+ return **(**uintptr)(unsafe.Pointer(&addr))
+}
+
+func store(base uintptr, idx uint32, p uintptr) {
+ addr := base + uintptr(idx)
+ **(**uintptr)(unsafe.Pointer(&addr)) = p
+}
+
+func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr {
+ addr := base + uintptr(idx)
+ p := **(**uintptr)(unsafe.Pointer(&addr))
+ for i := uint8(0); i < ptrNum; i++ {
+ if p == 0 {
+ return 0
+ }
+ p = ptrToPtr(p)
+ }
+ return p
+}
+
+func ptrToUint64(p uintptr, bitSize uint8) uint64 {
+ switch bitSize {
+ case 8:
+ return (uint64)(**(**uint8)(unsafe.Pointer(&p)))
+ case 16:
+ return (uint64)(**(**uint16)(unsafe.Pointer(&p)))
+ case 32:
+ return (uint64)(**(**uint32)(unsafe.Pointer(&p)))
+ case 64:
+ return **(**uint64)(unsafe.Pointer(&p))
+ }
+ return 0
+}
+func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) }
+func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) }
+func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) }
+func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) }
+func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) }
+func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) }
+func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) }
+func ptrToPtr(p uintptr) uintptr {
+ return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
+}
+func ptrToNPtr(p uintptr, ptrNum uint8) uintptr {
+ for i := uint8(0); i < ptrNum; i++ {
+ if p == 0 {
+ return 0
+ }
+ p = ptrToPtr(p)
+ }
+ return p
+}
+
+func ptrToUnsafePtr(p uintptr) unsafe.Pointer {
+ return *(*unsafe.Pointer)(unsafe.Pointer(&p))
+}
+func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} {
+ return *(*interface{})(unsafe.Pointer(&emptyInterface{
+ typ: code.Type,
+ ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
+ }))
+}
+
+func appendInt(ctx *encoder.RuntimeContext, b []byte, p uintptr, code *encoder.Opcode) []byte {
+ format := ctx.Option.ColorScheme.Int
+ b = append(b, format.Header...)
+ b = encoder.AppendInt(ctx, b, p, code)
+ return append(b, format.Footer...)
+}
+
+func appendUint(ctx *encoder.RuntimeContext, b []byte, p uintptr, code *encoder.Opcode) []byte {
+ format := ctx.Option.ColorScheme.Uint
+ b = append(b, format.Header...)
+ b = encoder.AppendUint(ctx, b, p, code)
+ return append(b, format.Footer...)
+}
+
+func appendFloat32(ctx *encoder.RuntimeContext, b []byte, v float32) []byte {
+ format := ctx.Option.ColorScheme.Float
+ b = append(b, format.Header...)
+ b = encoder.AppendFloat32(ctx, b, v)
+ return append(b, format.Footer...)
+}
+
+func appendFloat64(ctx *encoder.RuntimeContext, b []byte, v float64) []byte {
+ format := ctx.Option.ColorScheme.Float
+ b = append(b, format.Header...)
+ b = encoder.AppendFloat64(ctx, b, v)
+ return append(b, format.Footer...)
+}
+
+func appendString(ctx *encoder.RuntimeContext, b []byte, v string) []byte {
+ format := ctx.Option.ColorScheme.String
+ b = append(b, format.Header...)
+ b = encoder.AppendString(ctx, b, v)
+ return append(b, format.Footer...)
+}
+
+func appendByteSlice(ctx *encoder.RuntimeContext, b []byte, src []byte) []byte {
+ format := ctx.Option.ColorScheme.Binary
+ b = append(b, format.Header...)
+ b = encoder.AppendByteSlice(ctx, b, src)
+ return append(b, format.Footer...)
+}
+
+func appendNumber(ctx *encoder.RuntimeContext, b []byte, n json.Number) ([]byte, error) {
+ format := ctx.Option.ColorScheme.Int
+ b = append(b, format.Header...)
+ bb, err := encoder.AppendNumber(ctx, b, n)
+ if err != nil {
+ return nil, err
+ }
+ return append(bb, format.Footer...), nil
+}
+
+func appendBool(ctx *encoder.RuntimeContext, b []byte, v bool) []byte {
+ format := ctx.Option.ColorScheme.Bool
+ b = append(b, format.Header...)
+ if v {
+ b = append(b, "true"...)
+ } else {
+ b = append(b, "false"...)
+ }
+ return append(b, format.Footer...)
+}
+
+func appendNull(ctx *encoder.RuntimeContext, b []byte) []byte {
+ format := ctx.Option.ColorScheme.Null
+ b = append(b, format.Header...)
+ b = append(b, "null"...)
+ return append(b, format.Footer...)
+}
+
+func appendComma(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, ',')
+}
+
+func appendNullComma(ctx *encoder.RuntimeContext, b []byte) []byte {
+ format := ctx.Option.ColorScheme.Null
+ b = append(b, format.Header...)
+ b = append(b, "null"...)
+ return append(append(b, format.Footer...), ',')
+}
+
+func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
+ last := len(b) - 1
+ b[last] = ':'
+ return b
+}
+
+func appendMapKeyValue(_ *encoder.RuntimeContext, _ *encoder.Opcode, b, key, value []byte) []byte {
+ b = append(b, key[:len(key)-1]...)
+ b = append(b, ':')
+ return append(b, value...)
+}
+
+func appendMapEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
+ last := len(b) - 1
+ b[last] = '}'
+ b = append(b, ',')
+ return b
+}
+
+func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) {
+ return encoder.AppendMarshalJSON(ctx, code, b, v)
+}
+
+func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) {
+ format := ctx.Option.ColorScheme.String
+ b = append(b, format.Header...)
+ bb, err := encoder.AppendMarshalText(ctx, code, b, v)
+ if err != nil {
+ return nil, err
+ }
+ return append(bb, format.Footer...), nil
+}
+
+func appendArrayHead(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
+ return append(b, '[')
+}
+
+func appendArrayEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
+ last := len(b) - 1
+ b[last] = ']'
+ return append(b, ',')
+}
+
+func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, '[', ']', ',')
+}
+
+func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, '{', '}', ',')
+}
+
+func appendObjectEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
+ last := len(b) - 1
+ b[last] = '}'
+ return append(b, ',')
+}
+
+func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, '{')
+}
+
+func appendStructKey(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ format := ctx.Option.ColorScheme.ObjectKey
+ b = append(b, format.Header...)
+ b = append(b, code.Key[:len(code.Key)-1]...)
+ b = append(b, format.Footer...)
+
+ return append(b, ':')
+}
+
+func appendStructEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte {
+ return append(b, '}', ',')
+}
+
+func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ last := len(b) - 1
+ if b[last] == ',' {
+ b[last] = '}'
+ return appendComma(ctx, b)
+ }
+ return appendStructEnd(ctx, code, b)
+}
+
+func restoreIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, _ uintptr) {}
+func storeIndent(_ uintptr, _ *encoder.Opcode, _ uintptr) {}
+func appendMapKeyIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b }
+func appendArrayElemIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b }
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go
new file mode 100644
index 00000000..a63e83e5
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go
@@ -0,0 +1,4859 @@
+// Code generated by internal/cmd/generator. DO NOT EDIT!
+package vm_color
+
+import (
+ "math"
+ "reflect"
+ "sort"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/encoder"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
+ recursiveLevel := 0
+ ptrOffset := uintptr(0)
+ ctxptr := ctx.Ptr()
+ var code *encoder.Opcode
+ if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
+ code = codeSet.EscapeKeyCode
+ } else {
+ code = codeSet.NoescapeKeyCode
+ }
+
+ for {
+ switch code.Op {
+ default:
+ return nil, errUnimplementedOp(code.Op)
+ case encoder.OpPtr:
+ p := load(ctxptr, code.Idx)
+ code = code.Next
+ store(ctxptr, code.Idx, ptrToPtr(p))
+ case encoder.OpIntPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpInt:
+ b = appendInt(ctx, b, load(ctxptr, code.Idx), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpUintPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpUint:
+ b = appendUint(ctx, b, load(ctxptr, code.Idx), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpIntString:
+ b = append(b, '"')
+ b = appendInt(ctx, b, load(ctxptr, code.Idx), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpUintString:
+ b = append(b, '"')
+ b = appendUint(ctx, b, load(ctxptr, code.Idx), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpFloat32Ptr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ b = appendComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpFloat32:
+ b = appendFloat32(ctx, b, ptrToFloat32(load(ctxptr, code.Idx)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpFloat64Ptr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpFloat64:
+ v := ptrToFloat64(load(ctxptr, code.Idx))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStringPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpString:
+ b = appendString(ctx, b, ptrToString(load(ctxptr, code.Idx)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpBoolPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpBool:
+ b = appendBool(ctx, b, ptrToBool(load(ctxptr, code.Idx)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpBytesPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpBytes:
+ b = appendByteSlice(ctx, b, ptrToBytes(load(ctxptr, code.Idx)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpNumberPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpNumber:
+ bb, err := appendNumber(ctx, b, ptrToNumber(load(ctxptr, code.Idx)))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpInterfacePtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpInterface:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ if recursiveLevel > encoder.StartDetectingCyclesAfter {
+ for _, seen := range ctx.SeenPtr {
+ if p == seen {
+ return nil, errUnsupportedValue(code, p)
+ }
+ }
+ }
+ ctx.SeenPtr = append(ctx.SeenPtr, p)
+ var (
+ typ *runtime.Type
+ ifacePtr unsafe.Pointer
+ )
+ up := ptrToUnsafePtr(p)
+ if code.Flags&encoder.NonEmptyInterfaceFlags != 0 {
+ iface := (*nonEmptyInterface)(up)
+ ifacePtr = iface.ptr
+ if iface.itab != nil {
+ typ = iface.itab.typ
+ }
+ } else {
+ iface := (*emptyInterface)(up)
+ ifacePtr = iface.ptr
+ typ = iface.typ
+ }
+ if ifacePtr == nil {
+ isDirectedNil := typ != nil && typ.Kind() == reflect.Struct && !runtime.IfaceIndir(typ)
+ if !isDirectedNil {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ }
+ ctx.KeepRefs = append(ctx.KeepRefs, up)
+ ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ)))
+ if err != nil {
+ return nil, err
+ }
+
+ totalLength := uintptr(code.Length) + 3
+ nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3
+
+ var c *encoder.Opcode
+ if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
+ c = ifaceCodeSet.InterfaceEscapeKeyCode
+ } else {
+ c = ifaceCodeSet.InterfaceNoescapeKeyCode
+ }
+ curlen := uintptr(len(ctx.Ptrs))
+ offsetNum := ptrOffset / uintptrSize
+ oldOffset := ptrOffset
+ ptrOffset += totalLength * uintptrSize
+ oldBaseIndent := ctx.BaseIndent
+ ctx.BaseIndent += code.Indent
+
+ newLen := offsetNum + totalLength + nextTotalLength
+ if curlen < newLen {
+ ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
+ }
+ ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr
+
+ end := ifaceCodeSet.EndCode
+ store(ctxptr, c.Idx, uintptr(ifacePtr))
+ store(ctxptr, end.Idx, oldOffset)
+ store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
+ storeIndent(ctxptr, end, uintptr(oldBaseIndent))
+ code = c
+ recursiveLevel++
+ case encoder.OpInterfaceEnd:
+ recursiveLevel--
+
+ // restore ctxptr
+ offset := load(ctxptr, code.Idx)
+ restoreIndent(ctx, code, ctxptr)
+ ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1]
+
+ codePtr := load(ctxptr, code.ElemIdx)
+ code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr))
+ ctxptr = ctx.Ptr() + offset
+ ptrOffset = offset
+ case encoder.OpMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToPtr(p))
+ fallthrough
+ case encoder.OpMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToPtr(p))
+ fallthrough
+ case encoder.OpMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = append(b, `""`...)
+ b = appendComma(ctx, b)
+ code = code.Next
+ break
+ }
+ if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpSlicePtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpSlice:
+ p := load(ctxptr, code.Idx)
+ slice := ptrToSlice(p)
+ if p == 0 || slice.Data == nil {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.ElemIdx, 0)
+ store(ctxptr, code.Length, uintptr(slice.Len))
+ store(ctxptr, code.Idx, uintptr(slice.Data))
+ if slice.Len > 0 {
+ b = appendArrayHead(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, uintptr(slice.Data))
+ } else {
+ b = appendEmptyArray(ctx, b)
+ code = code.End.Next
+ }
+ case encoder.OpSliceElem:
+ idx := load(ctxptr, code.ElemIdx)
+ length := load(ctxptr, code.Length)
+ idx++
+ if idx < length {
+ b = appendArrayElemIndent(ctx, code, b)
+ store(ctxptr, code.ElemIdx, idx)
+ data := load(ctxptr, code.Idx)
+ size := uintptr(code.Size)
+ code = code.Next
+ store(ctxptr, code.Idx, data+idx*size)
+ } else {
+ b = appendArrayEnd(ctx, code, b)
+ code = code.End.Next
+ }
+ case encoder.OpArrayPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpArray:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ if code.Length > 0 {
+ b = appendArrayHead(ctx, code, b)
+ store(ctxptr, code.ElemIdx, 0)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ } else {
+ b = appendEmptyArray(ctx, b)
+ code = code.End.Next
+ }
+ case encoder.OpArrayElem:
+ idx := load(ctxptr, code.ElemIdx)
+ idx++
+ if idx < uintptr(code.Length) {
+ b = appendArrayElemIndent(ctx, code, b)
+ store(ctxptr, code.ElemIdx, idx)
+ p := load(ctxptr, code.Idx)
+ size := uintptr(code.Size)
+ code = code.Next
+ store(ctxptr, code.Idx, p+idx*size)
+ } else {
+ b = appendArrayEnd(ctx, code, b)
+ code = code.End.Next
+ }
+ case encoder.OpMapPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ uptr := ptrToUnsafePtr(p)
+ mlen := maplen(uptr)
+ if mlen <= 0 {
+ b = appendEmptyObject(ctx, b)
+ code = code.End.Next
+ break
+ }
+ b = appendStructHead(ctx, b)
+ unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0
+ mapCtx := encoder.NewMapContext(mlen, unorderedMap)
+ mapiterinit(code.Type, uptr, &mapCtx.Iter)
+ store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx)))
+ ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx))
+ if unorderedMap {
+ b = appendMapKeyIndent(ctx, code.Next, b)
+ } else {
+ mapCtx.Start = len(b)
+ mapCtx.First = len(b)
+ }
+ key := mapiterkey(&mapCtx.Iter)
+ store(ctxptr, code.Next.Idx, uintptr(key))
+ code = code.Next
+ case encoder.OpMapKey:
+ mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx)))
+ idx := mapCtx.Idx
+ idx++
+ if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
+ if idx < mapCtx.Len {
+ b = appendMapKeyIndent(ctx, code, b)
+ mapCtx.Idx = int(idx)
+ key := mapiterkey(&mapCtx.Iter)
+ store(ctxptr, code.Next.Idx, uintptr(key))
+ code = code.Next
+ } else {
+ b = appendObjectEnd(ctx, code, b)
+ encoder.ReleaseMapContext(mapCtx)
+ code = code.End.Next
+ }
+ } else {
+ mapCtx.Slice.Items[mapCtx.Idx].Value = b[mapCtx.Start:len(b)]
+ if idx < mapCtx.Len {
+ mapCtx.Idx = int(idx)
+ mapCtx.Start = len(b)
+ key := mapiterkey(&mapCtx.Iter)
+ store(ctxptr, code.Next.Idx, uintptr(key))
+ code = code.Next
+ } else {
+ code = code.End
+ }
+ }
+ case encoder.OpMapValue:
+ mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx)))
+ if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
+ b = appendColon(ctx, b)
+ } else {
+ mapCtx.Slice.Items[mapCtx.Idx].Key = b[mapCtx.Start:len(b)]
+ mapCtx.Start = len(b)
+ }
+ value := mapitervalue(&mapCtx.Iter)
+ store(ctxptr, code.Next.Idx, uintptr(value))
+ mapiternext(&mapCtx.Iter)
+ code = code.Next
+ case encoder.OpMapEnd:
+ // this operation only used by sorted map.
+ mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx)))
+ sort.Sort(mapCtx.Slice)
+ buf := mapCtx.Buf
+ for _, item := range mapCtx.Slice.Items {
+ buf = appendMapKeyValue(ctx, code, buf, item.Key, item.Value)
+ }
+ buf = appendMapEnd(ctx, code, buf)
+ b = b[:mapCtx.First]
+ b = append(b, buf...)
+ mapCtx.Buf = buf
+ encoder.ReleaseMapContext(mapCtx)
+ code = code.Next
+ case encoder.OpRecursivePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpRecursive:
+ ptr := load(ctxptr, code.Idx)
+ if ptr != 0 {
+ if recursiveLevel > encoder.StartDetectingCyclesAfter {
+ for _, seen := range ctx.SeenPtr {
+ if ptr == seen {
+ return nil, errUnsupportedValue(code, ptr)
+ }
+ }
+ }
+ }
+ ctx.SeenPtr = append(ctx.SeenPtr, ptr)
+ c := code.Jmp.Code
+ curlen := uintptr(len(ctx.Ptrs))
+ offsetNum := ptrOffset / uintptrSize
+ oldOffset := ptrOffset
+ ptrOffset += code.Jmp.CurLen * uintptrSize
+ oldBaseIndent := ctx.BaseIndent
+ indentDiffFromTop := c.Indent - 1
+ ctx.BaseIndent += code.Indent - indentDiffFromTop
+
+ newLen := offsetNum + code.Jmp.CurLen + code.Jmp.NextLen
+ if curlen < newLen {
+ ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
+ }
+ ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr
+
+ store(ctxptr, c.Idx, ptr)
+ store(ctxptr, c.End.Next.Idx, oldOffset)
+ store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
+ storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent))
+ code = c
+ recursiveLevel++
+ case encoder.OpRecursiveEnd:
+ recursiveLevel--
+
+ // restore ctxptr
+ restoreIndent(ctx, code, ctxptr)
+ offset := load(ctxptr, code.Idx)
+ ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1]
+
+ codePtr := load(ctxptr, code.ElemIdx)
+ code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr))
+ ctxptr = ctx.Ptr() + offset
+ ptrOffset = offset
+ case encoder.OpStructPtrHead:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHead:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if len(code.Key) > 0 {
+ if (code.Flags&encoder.IsTaggedKeyFlags) != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 {
+ b = appendStructKey(ctx, code, b)
+ }
+ }
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructPtrHeadOmitEmpty:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmpty:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ if p == 0 || (ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0) {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadInt:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadInt:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyInt:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyInt:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadIntString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadIntString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyIntString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyIntString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ u64 := ptrToUint64(p, code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadIntPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadIntPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendInt(ctx, b, p, code)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyIntPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyIntPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p, code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadIntPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadIntPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyIntPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyIntPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadUint:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadUint:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyUint:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyUint:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadUintString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadUintString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyUintString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyUintString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadUintPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadUintPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendUint(ctx, b, p, code)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyUintPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyUintPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p, code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadUintPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadUintPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyUintPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyUintPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadFloat32:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadFloat32:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat32:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat32:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadFloat32String:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadFloat32String:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat32String:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat32String:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadFloat64:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadFloat64:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat64:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat64:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v == 0 {
+ code = code.NextField
+ } else {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadFloat64String:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadFloat64String:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat64String:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat64String:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v == 0 {
+ code = code.NextField
+ } else {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNull(ctx, b)
+ b = appendComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToString(p + uintptr(code.Offset))
+ if v == "" {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadStringString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadStringString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p+uintptr(code.Offset)))))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyStringString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyStringString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToString(p + uintptr(code.Offset))
+ if v == "" {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, v)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadStringPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadStringPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, ptrToString(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyStringPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyStringPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadStringPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadStringPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyStringPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyStringPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadBool:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadBool:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBool:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBool:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructPtrHeadBoolString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadBoolString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBoolString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBoolString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructPtrHeadBoolPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadBoolPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendBool(ctx, b, ptrToBool(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBoolPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBoolPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadBytes:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadBytes:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBytes:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBytes:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToBytes(p + uintptr(code.Offset))
+ if len(v) == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadBytesPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadBytesPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBytesPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBytesPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadNumber:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadNumber:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyNumber:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyNumber:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v == "" {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadNumberString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadNumberString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyNumberString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyNumberString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v == "" {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadNumberPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadNumberPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyNumberPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyNumberPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadArray, encoder.OpStructPtrHeadSlice:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadArray, encoder.OpStructHeadSlice:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructPtrHeadOmitEmptyArray:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyArray:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructPtrHeadOmitEmptySlice:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptySlice:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ slice := ptrToSlice(p)
+ if slice.Len == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadArrayPtr, encoder.OpStructPtrHeadSlicePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadArrayPtr, encoder.OpStructHeadSlicePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.NextField
+ } else {
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadOmitEmptyArrayPtr, encoder.OpStructPtrHeadOmitEmptySlicePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyArrayPtr, encoder.OpStructHeadOmitEmptySlicePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ p = ptrToPtr(p + uintptr(code.Offset))
+ }
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructPtrHeadOmitEmptyMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ p = ptrToPtr(p + uintptr(code.Offset))
+ }
+ if maplen(ptrToUnsafePtr(p)) == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadMapPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadMapPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.NextField
+ break
+ }
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.NextField
+ } else {
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p, code.PtrNum)
+ }
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadOmitEmptyMapPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMapPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if p == 0 {
+ code = code.NextField
+ break
+ }
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p == 0 {
+ code = code.NextField
+ } else {
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p, code.PtrNum)
+ }
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON {
+ p = ptrToPtr(p)
+ }
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON {
+ p = ptrToPtr(p)
+ }
+ }
+ iface := ptrToInterface(code, p)
+ if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalJSON(ctx, code, b, iface)
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if p == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText {
+ p = ptrToPtr(p)
+ }
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText {
+ p = ptrToPtr(p)
+ }
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if p == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructField:
+ if code.Flags&encoder.IsTaggedKeyFlags != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 {
+ b = appendStructKey(ctx, code, b)
+ }
+ p := load(ctxptr, code.Idx) + uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmpty:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructFieldInt:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyInt:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldIntString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyIntString:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldIntPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendInt(ctx, b, p, code)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyIntPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p, code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldIntPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyIntPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldUint:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyUint:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldUintString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyUintString:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldUintPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendUint(ctx, b, p, code)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyUintPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p, code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldUintPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyUintPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat32:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat32:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat32String:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat32String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat64:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat64:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v != 0 {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat64String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat64String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v != 0 {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToString(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldStringString:
+ p := load(ctxptr, code.Idx)
+ s := ptrToString(p + uintptr(code.Offset))
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, s)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyStringString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToString(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, v)))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldStringPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, ptrToString(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyStringPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldStringPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyStringPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBool:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBool:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBoolString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBoolString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBoolPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendBool(ctx, b, ptrToBool(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBoolPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBytes:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBytes:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBytes(p + uintptr(code.Offset))
+ if len(v) > 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBytesPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBytesPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldNumber:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyNumber:
+ p := load(ctxptr, code.Idx)
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructFieldNumberString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyNumberString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldNumberPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyNumberPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructFieldNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ code = code.NextField
+ break
+ }
+ iface := ptrToInterface(code, p)
+ if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) {
+ code = code.NextField
+ break
+ }
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalJSON(ctx, code, b, iface)
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpStructFieldMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructFieldMarshalText:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyMarshalText:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ code = code.NextField
+ break
+ }
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpStructFieldMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructFieldArray:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyArray:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldArrayPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyArrayPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructFieldSlice:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptySlice:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ slice := ptrToSlice(p)
+ if slice.Len == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructFieldSlicePtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptySlicePtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructFieldMap:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToPtr(p + uintptr(code.Offset))
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyMap:
+ p := load(ctxptr, code.Idx)
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p == 0 || maplen(ptrToUnsafePtr(p)) == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructFieldMapPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p != 0 {
+ p = ptrToNPtr(p, code.PtrNum)
+ }
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyMapPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p != 0 {
+ p = ptrToNPtr(p, code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructFieldStruct:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyStruct:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructEnd:
+ b = appendStructEndSkipLast(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndInt:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyInt:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndIntString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyIntString:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndIntPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendInt(ctx, b, p, code)
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyIntPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p, code)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndIntPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyIntPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndUint:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyUint:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndUintString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyUintString:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndUintPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendUint(ctx, b, p, code)
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyUintPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p, code)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndUintPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyUintPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat32:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat32:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat32String:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat32String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat32Ptr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat32PtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat64:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat64:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v != 0 {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat64String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat64String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v != 0 {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat64Ptr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ break
+ }
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat64PtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToString(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndStringString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ s := ptrToString(p + uintptr(code.Offset))
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, s)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyStringString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToString(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, v)))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndStringPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, ptrToString(p))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyStringPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndStringPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyStringPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBool:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBool:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBoolString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBoolString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBoolPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendBool(ctx, b, ptrToBool(p))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBoolPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBoolPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBytes:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBytes:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBytes(p + uintptr(code.Offset))
+ if len(v) > 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBytesPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBytesPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndNumber:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = appendStructEnd(ctx, code, bb)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyNumber:
+ p := load(ctxptr, code.Idx)
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = appendStructEnd(ctx, code, bb)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndNumberString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyNumberString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndNumberPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyNumberPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendStructEnd(ctx, code, bb)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndNumberPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpEnd:
+ goto END
+ }
+ }
+END:
+ return b, nil
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go
new file mode 100644
index 00000000..dd4cd489
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go
@@ -0,0 +1,35 @@
+package vm_color_indent
+
+import (
+ "fmt"
+
+ "github.com/goccy/go-json/internal/encoder"
+)
+
+func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
+ var code *encoder.Opcode
+ if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
+ code = codeSet.EscapeKeyCode
+ } else {
+ code = codeSet.NoescapeKeyCode
+ }
+
+ defer func() {
+ if err := recover(); err != nil {
+ w := ctx.Option.DebugOut
+ fmt.Fprintln(w, "=============[DEBUG]===============")
+ fmt.Fprintln(w, "* [TYPE]")
+ fmt.Fprintln(w, codeSet.Type)
+ fmt.Fprintf(w, "\n")
+ fmt.Fprintln(w, "* [ALL OPCODE]")
+ fmt.Fprintln(w, code.Dump())
+ fmt.Fprintf(w, "\n")
+ fmt.Fprintln(w, "* [CONTEXT]")
+ fmt.Fprintf(w, "%+v\n", ctx)
+ fmt.Fprintln(w, "===================================")
+ panic(err)
+ }
+ }()
+
+ return Run(ctx, b, codeSet)
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go
new file mode 100644
index 00000000..2395abec
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go
@@ -0,0 +1,297 @@
+package vm_color_indent
+
+import (
+ "encoding/json"
+ "fmt"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/encoder"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+const uintptrSize = 4 << (^uintptr(0) >> 63)
+
+var (
+ appendIndent = encoder.AppendIndent
+ appendStructEnd = encoder.AppendStructEndIndent
+ errUnsupportedValue = encoder.ErrUnsupportedValue
+ errUnsupportedFloat = encoder.ErrUnsupportedFloat
+ mapiterinit = encoder.MapIterInit
+ mapiterkey = encoder.MapIterKey
+ mapitervalue = encoder.MapIterValue
+ mapiternext = encoder.MapIterNext
+ maplen = encoder.MapLen
+)
+
+type emptyInterface struct {
+ typ *runtime.Type
+ ptr unsafe.Pointer
+}
+
+type nonEmptyInterface struct {
+ itab *struct {
+ ityp *runtime.Type // static interface type
+ typ *runtime.Type // dynamic concrete type
+ // unused fields...
+ }
+ ptr unsafe.Pointer
+}
+
+func errUnimplementedOp(op encoder.OpType) error {
+ return fmt.Errorf("encoder (indent): opcode %s has not been implemented", op)
+}
+
+func load(base uintptr, idx uint32) uintptr {
+ addr := base + uintptr(idx)
+ return **(**uintptr)(unsafe.Pointer(&addr))
+}
+
+func store(base uintptr, idx uint32, p uintptr) {
+ addr := base + uintptr(idx)
+ **(**uintptr)(unsafe.Pointer(&addr)) = p
+}
+
+func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr {
+ addr := base + uintptr(idx)
+ p := **(**uintptr)(unsafe.Pointer(&addr))
+ for i := uint8(0); i < ptrNum; i++ {
+ if p == 0 {
+ return 0
+ }
+ p = ptrToPtr(p)
+ }
+ return p
+}
+
+func ptrToUint64(p uintptr, bitSize uint8) uint64 {
+ switch bitSize {
+ case 8:
+ return (uint64)(**(**uint8)(unsafe.Pointer(&p)))
+ case 16:
+ return (uint64)(**(**uint16)(unsafe.Pointer(&p)))
+ case 32:
+ return (uint64)(**(**uint32)(unsafe.Pointer(&p)))
+ case 64:
+ return **(**uint64)(unsafe.Pointer(&p))
+ }
+ return 0
+}
+
+func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) }
+func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) }
+func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) }
+func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) }
+func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) }
+func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) }
+func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) }
+func ptrToPtr(p uintptr) uintptr {
+ return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
+}
+func ptrToNPtr(p uintptr, ptrNum uint8) uintptr {
+ for i := uint8(0); i < ptrNum; i++ {
+ if p == 0 {
+ return 0
+ }
+ p = ptrToPtr(p)
+ }
+ return p
+}
+
+func ptrToUnsafePtr(p uintptr) unsafe.Pointer {
+ return *(*unsafe.Pointer)(unsafe.Pointer(&p))
+}
+func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} {
+ return *(*interface{})(unsafe.Pointer(&emptyInterface{
+ typ: code.Type,
+ ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
+ }))
+}
+
+func appendInt(ctx *encoder.RuntimeContext, b []byte, p uintptr, code *encoder.Opcode) []byte {
+ format := ctx.Option.ColorScheme.Int
+ b = append(b, format.Header...)
+ b = encoder.AppendInt(ctx, b, p, code)
+ return append(b, format.Footer...)
+}
+
+func appendUint(ctx *encoder.RuntimeContext, b []byte, p uintptr, code *encoder.Opcode) []byte {
+ format := ctx.Option.ColorScheme.Uint
+ b = append(b, format.Header...)
+ b = encoder.AppendUint(ctx, b, p, code)
+ return append(b, format.Footer...)
+}
+
+func appendFloat32(ctx *encoder.RuntimeContext, b []byte, v float32) []byte {
+ format := ctx.Option.ColorScheme.Float
+ b = append(b, format.Header...)
+ b = encoder.AppendFloat32(ctx, b, v)
+ return append(b, format.Footer...)
+}
+
+func appendFloat64(ctx *encoder.RuntimeContext, b []byte, v float64) []byte {
+ format := ctx.Option.ColorScheme.Float
+ b = append(b, format.Header...)
+ b = encoder.AppendFloat64(ctx, b, v)
+ return append(b, format.Footer...)
+}
+
+func appendString(ctx *encoder.RuntimeContext, b []byte, v string) []byte {
+ format := ctx.Option.ColorScheme.String
+ b = append(b, format.Header...)
+ b = encoder.AppendString(ctx, b, v)
+ return append(b, format.Footer...)
+}
+
+func appendByteSlice(ctx *encoder.RuntimeContext, b []byte, src []byte) []byte {
+ format := ctx.Option.ColorScheme.Binary
+ b = append(b, format.Header...)
+ b = encoder.AppendByteSlice(ctx, b, src)
+ return append(b, format.Footer...)
+}
+
+func appendNumber(ctx *encoder.RuntimeContext, b []byte, n json.Number) ([]byte, error) {
+ format := ctx.Option.ColorScheme.Int
+ b = append(b, format.Header...)
+ bb, err := encoder.AppendNumber(ctx, b, n)
+ if err != nil {
+ return nil, err
+ }
+ return append(bb, format.Footer...), nil
+}
+
+func appendBool(ctx *encoder.RuntimeContext, b []byte, v bool) []byte {
+ format := ctx.Option.ColorScheme.Bool
+ b = append(b, format.Header...)
+ if v {
+ b = append(b, "true"...)
+ } else {
+ b = append(b, "false"...)
+ }
+ return append(b, format.Footer...)
+}
+
+func appendNull(ctx *encoder.RuntimeContext, b []byte) []byte {
+ format := ctx.Option.ColorScheme.Null
+ b = append(b, format.Header...)
+ b = append(b, "null"...)
+ return append(b, format.Footer...)
+}
+
+func appendComma(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, ',', '\n')
+}
+
+func appendNullComma(ctx *encoder.RuntimeContext, b []byte) []byte {
+ format := ctx.Option.ColorScheme.Null
+ b = append(b, format.Header...)
+ b = append(b, "null"...)
+ return append(append(b, format.Footer...), ',', '\n')
+}
+
+func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b[:len(b)-2], ':', ' ')
+}
+
+func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte {
+ b = appendIndent(ctx, b, code.Indent+1)
+ b = append(b, key...)
+ b[len(b)-2] = ':'
+ b[len(b)-1] = ' '
+ return append(b, value...)
+}
+
+func appendMapEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ b = b[:len(b)-2]
+ b = append(b, '\n')
+ b = appendIndent(ctx, b, code.Indent)
+ return append(b, '}', ',', '\n')
+}
+
+func appendArrayHead(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ b = append(b, '[', '\n')
+ return appendIndent(ctx, b, code.Indent+1)
+}
+
+func appendArrayEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ b = b[:len(b)-2]
+ b = append(b, '\n')
+ b = appendIndent(ctx, b, code.Indent)
+ return append(b, ']', ',', '\n')
+}
+
+func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, '[', ']', ',', '\n')
+}
+
+func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, '{', '}', ',', '\n')
+}
+
+func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ last := len(b) - 1
+ // replace comma to newline
+ b[last-1] = '\n'
+ b = appendIndent(ctx, b[:last], code.Indent)
+ return append(b, '}', ',', '\n')
+}
+
+func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) {
+ return encoder.AppendMarshalJSONIndent(ctx, code, b, v)
+}
+
+func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) {
+ format := ctx.Option.ColorScheme.String
+ b = append(b, format.Header...)
+ bb, err := encoder.AppendMarshalTextIndent(ctx, code, b, v)
+ if err != nil {
+ return nil, err
+ }
+ return append(bb, format.Footer...), nil
+}
+
+func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, '{', '\n')
+}
+
+func appendStructKey(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ b = appendIndent(ctx, b, code.Indent)
+
+ format := ctx.Option.ColorScheme.ObjectKey
+ b = append(b, format.Header...)
+ b = append(b, code.Key[:len(code.Key)-1]...)
+ b = append(b, format.Footer...)
+
+ return append(b, ':', ' ')
+}
+
+func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ last := len(b) - 1
+ if b[last-1] == '{' {
+ b[last] = '}'
+ } else {
+ if b[last] == '\n' {
+ // to remove ',' and '\n' characters
+ b = b[:len(b)-2]
+ }
+ b = append(b, '\n')
+ b = appendIndent(ctx, b, code.Indent-1)
+ b = append(b, '}')
+ }
+ return appendComma(ctx, b)
+}
+
+func restoreIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, ctxptr uintptr) {
+ ctx.BaseIndent = uint32(load(ctxptr, code.Length))
+}
+
+func storeIndent(ctxptr uintptr, code *encoder.Opcode, indent uintptr) {
+ store(ctxptr, code.Length, indent)
+}
+
+func appendArrayElemIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ return appendIndent(ctx, b, code.Indent+1)
+}
+
+func appendMapKeyIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ return appendIndent(ctx, b, code.Indent)
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go
new file mode 100644
index 00000000..3b4e22e5
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go
@@ -0,0 +1,4859 @@
+// Code generated by internal/cmd/generator. DO NOT EDIT!
+package vm_color_indent
+
+import (
+ "math"
+ "reflect"
+ "sort"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/encoder"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
+ recursiveLevel := 0
+ ptrOffset := uintptr(0)
+ ctxptr := ctx.Ptr()
+ var code *encoder.Opcode
+ if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
+ code = codeSet.EscapeKeyCode
+ } else {
+ code = codeSet.NoescapeKeyCode
+ }
+
+ for {
+ switch code.Op {
+ default:
+ return nil, errUnimplementedOp(code.Op)
+ case encoder.OpPtr:
+ p := load(ctxptr, code.Idx)
+ code = code.Next
+ store(ctxptr, code.Idx, ptrToPtr(p))
+ case encoder.OpIntPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpInt:
+ b = appendInt(ctx, b, load(ctxptr, code.Idx), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpUintPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpUint:
+ b = appendUint(ctx, b, load(ctxptr, code.Idx), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpIntString:
+ b = append(b, '"')
+ b = appendInt(ctx, b, load(ctxptr, code.Idx), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpUintString:
+ b = append(b, '"')
+ b = appendUint(ctx, b, load(ctxptr, code.Idx), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpFloat32Ptr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ b = appendComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpFloat32:
+ b = appendFloat32(ctx, b, ptrToFloat32(load(ctxptr, code.Idx)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpFloat64Ptr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpFloat64:
+ v := ptrToFloat64(load(ctxptr, code.Idx))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStringPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpString:
+ b = appendString(ctx, b, ptrToString(load(ctxptr, code.Idx)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpBoolPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpBool:
+ b = appendBool(ctx, b, ptrToBool(load(ctxptr, code.Idx)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpBytesPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpBytes:
+ b = appendByteSlice(ctx, b, ptrToBytes(load(ctxptr, code.Idx)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpNumberPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpNumber:
+ bb, err := appendNumber(ctx, b, ptrToNumber(load(ctxptr, code.Idx)))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpInterfacePtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpInterface:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ if recursiveLevel > encoder.StartDetectingCyclesAfter {
+ for _, seen := range ctx.SeenPtr {
+ if p == seen {
+ return nil, errUnsupportedValue(code, p)
+ }
+ }
+ }
+ ctx.SeenPtr = append(ctx.SeenPtr, p)
+ var (
+ typ *runtime.Type
+ ifacePtr unsafe.Pointer
+ )
+ up := ptrToUnsafePtr(p)
+ if code.Flags&encoder.NonEmptyInterfaceFlags != 0 {
+ iface := (*nonEmptyInterface)(up)
+ ifacePtr = iface.ptr
+ if iface.itab != nil {
+ typ = iface.itab.typ
+ }
+ } else {
+ iface := (*emptyInterface)(up)
+ ifacePtr = iface.ptr
+ typ = iface.typ
+ }
+ if ifacePtr == nil {
+ isDirectedNil := typ != nil && typ.Kind() == reflect.Struct && !runtime.IfaceIndir(typ)
+ if !isDirectedNil {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ }
+ ctx.KeepRefs = append(ctx.KeepRefs, up)
+ ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ)))
+ if err != nil {
+ return nil, err
+ }
+
+ totalLength := uintptr(code.Length) + 3
+ nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3
+
+ var c *encoder.Opcode
+ if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
+ c = ifaceCodeSet.InterfaceEscapeKeyCode
+ } else {
+ c = ifaceCodeSet.InterfaceNoescapeKeyCode
+ }
+ curlen := uintptr(len(ctx.Ptrs))
+ offsetNum := ptrOffset / uintptrSize
+ oldOffset := ptrOffset
+ ptrOffset += totalLength * uintptrSize
+ oldBaseIndent := ctx.BaseIndent
+ ctx.BaseIndent += code.Indent
+
+ newLen := offsetNum + totalLength + nextTotalLength
+ if curlen < newLen {
+ ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
+ }
+ ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr
+
+ end := ifaceCodeSet.EndCode
+ store(ctxptr, c.Idx, uintptr(ifacePtr))
+ store(ctxptr, end.Idx, oldOffset)
+ store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
+ storeIndent(ctxptr, end, uintptr(oldBaseIndent))
+ code = c
+ recursiveLevel++
+ case encoder.OpInterfaceEnd:
+ recursiveLevel--
+
+ // restore ctxptr
+ offset := load(ctxptr, code.Idx)
+ restoreIndent(ctx, code, ctxptr)
+ ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1]
+
+ codePtr := load(ctxptr, code.ElemIdx)
+ code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr))
+ ctxptr = ctx.Ptr() + offset
+ ptrOffset = offset
+ case encoder.OpMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToPtr(p))
+ fallthrough
+ case encoder.OpMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToPtr(p))
+ fallthrough
+ case encoder.OpMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = append(b, `""`...)
+ b = appendComma(ctx, b)
+ code = code.Next
+ break
+ }
+ if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpSlicePtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpSlice:
+ p := load(ctxptr, code.Idx)
+ slice := ptrToSlice(p)
+ if p == 0 || slice.Data == nil {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.ElemIdx, 0)
+ store(ctxptr, code.Length, uintptr(slice.Len))
+ store(ctxptr, code.Idx, uintptr(slice.Data))
+ if slice.Len > 0 {
+ b = appendArrayHead(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, uintptr(slice.Data))
+ } else {
+ b = appendEmptyArray(ctx, b)
+ code = code.End.Next
+ }
+ case encoder.OpSliceElem:
+ idx := load(ctxptr, code.ElemIdx)
+ length := load(ctxptr, code.Length)
+ idx++
+ if idx < length {
+ b = appendArrayElemIndent(ctx, code, b)
+ store(ctxptr, code.ElemIdx, idx)
+ data := load(ctxptr, code.Idx)
+ size := uintptr(code.Size)
+ code = code.Next
+ store(ctxptr, code.Idx, data+idx*size)
+ } else {
+ b = appendArrayEnd(ctx, code, b)
+ code = code.End.Next
+ }
+ case encoder.OpArrayPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpArray:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ if code.Length > 0 {
+ b = appendArrayHead(ctx, code, b)
+ store(ctxptr, code.ElemIdx, 0)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ } else {
+ b = appendEmptyArray(ctx, b)
+ code = code.End.Next
+ }
+ case encoder.OpArrayElem:
+ idx := load(ctxptr, code.ElemIdx)
+ idx++
+ if idx < uintptr(code.Length) {
+ b = appendArrayElemIndent(ctx, code, b)
+ store(ctxptr, code.ElemIdx, idx)
+ p := load(ctxptr, code.Idx)
+ size := uintptr(code.Size)
+ code = code.Next
+ store(ctxptr, code.Idx, p+idx*size)
+ } else {
+ b = appendArrayEnd(ctx, code, b)
+ code = code.End.Next
+ }
+ case encoder.OpMapPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ uptr := ptrToUnsafePtr(p)
+ mlen := maplen(uptr)
+ if mlen <= 0 {
+ b = appendEmptyObject(ctx, b)
+ code = code.End.Next
+ break
+ }
+ b = appendStructHead(ctx, b)
+ unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0
+ mapCtx := encoder.NewMapContext(mlen, unorderedMap)
+ mapiterinit(code.Type, uptr, &mapCtx.Iter)
+ store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx)))
+ ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx))
+ if unorderedMap {
+ b = appendMapKeyIndent(ctx, code.Next, b)
+ } else {
+ mapCtx.Start = len(b)
+ mapCtx.First = len(b)
+ }
+ key := mapiterkey(&mapCtx.Iter)
+ store(ctxptr, code.Next.Idx, uintptr(key))
+ code = code.Next
+ case encoder.OpMapKey:
+ mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx)))
+ idx := mapCtx.Idx
+ idx++
+ if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
+ if idx < mapCtx.Len {
+ b = appendMapKeyIndent(ctx, code, b)
+ mapCtx.Idx = int(idx)
+ key := mapiterkey(&mapCtx.Iter)
+ store(ctxptr, code.Next.Idx, uintptr(key))
+ code = code.Next
+ } else {
+ b = appendObjectEnd(ctx, code, b)
+ encoder.ReleaseMapContext(mapCtx)
+ code = code.End.Next
+ }
+ } else {
+ mapCtx.Slice.Items[mapCtx.Idx].Value = b[mapCtx.Start:len(b)]
+ if idx < mapCtx.Len {
+ mapCtx.Idx = int(idx)
+ mapCtx.Start = len(b)
+ key := mapiterkey(&mapCtx.Iter)
+ store(ctxptr, code.Next.Idx, uintptr(key))
+ code = code.Next
+ } else {
+ code = code.End
+ }
+ }
+ case encoder.OpMapValue:
+ mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx)))
+ if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
+ b = appendColon(ctx, b)
+ } else {
+ mapCtx.Slice.Items[mapCtx.Idx].Key = b[mapCtx.Start:len(b)]
+ mapCtx.Start = len(b)
+ }
+ value := mapitervalue(&mapCtx.Iter)
+ store(ctxptr, code.Next.Idx, uintptr(value))
+ mapiternext(&mapCtx.Iter)
+ code = code.Next
+ case encoder.OpMapEnd:
+ // this operation only used by sorted map.
+ mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx)))
+ sort.Sort(mapCtx.Slice)
+ buf := mapCtx.Buf
+ for _, item := range mapCtx.Slice.Items {
+ buf = appendMapKeyValue(ctx, code, buf, item.Key, item.Value)
+ }
+ buf = appendMapEnd(ctx, code, buf)
+ b = b[:mapCtx.First]
+ b = append(b, buf...)
+ mapCtx.Buf = buf
+ encoder.ReleaseMapContext(mapCtx)
+ code = code.Next
+ case encoder.OpRecursivePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpRecursive:
+ ptr := load(ctxptr, code.Idx)
+ if ptr != 0 {
+ if recursiveLevel > encoder.StartDetectingCyclesAfter {
+ for _, seen := range ctx.SeenPtr {
+ if ptr == seen {
+ return nil, errUnsupportedValue(code, ptr)
+ }
+ }
+ }
+ }
+ ctx.SeenPtr = append(ctx.SeenPtr, ptr)
+ c := code.Jmp.Code
+ curlen := uintptr(len(ctx.Ptrs))
+ offsetNum := ptrOffset / uintptrSize
+ oldOffset := ptrOffset
+ ptrOffset += code.Jmp.CurLen * uintptrSize
+ oldBaseIndent := ctx.BaseIndent
+ indentDiffFromTop := c.Indent - 1
+ ctx.BaseIndent += code.Indent - indentDiffFromTop
+
+ newLen := offsetNum + code.Jmp.CurLen + code.Jmp.NextLen
+ if curlen < newLen {
+ ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
+ }
+ ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr
+
+ store(ctxptr, c.Idx, ptr)
+ store(ctxptr, c.End.Next.Idx, oldOffset)
+ store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
+ storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent))
+ code = c
+ recursiveLevel++
+ case encoder.OpRecursiveEnd:
+ recursiveLevel--
+
+ // restore ctxptr
+ restoreIndent(ctx, code, ctxptr)
+ offset := load(ctxptr, code.Idx)
+ ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1]
+
+ codePtr := load(ctxptr, code.ElemIdx)
+ code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr))
+ ctxptr = ctx.Ptr() + offset
+ ptrOffset = offset
+ case encoder.OpStructPtrHead:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHead:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if len(code.Key) > 0 {
+ if (code.Flags&encoder.IsTaggedKeyFlags) != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 {
+ b = appendStructKey(ctx, code, b)
+ }
+ }
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructPtrHeadOmitEmpty:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmpty:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ if p == 0 || (ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0) {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadInt:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadInt:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyInt:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyInt:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadIntString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadIntString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyIntString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyIntString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ u64 := ptrToUint64(p, code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadIntPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadIntPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendInt(ctx, b, p, code)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyIntPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyIntPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p, code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadIntPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadIntPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyIntPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyIntPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadUint:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadUint:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyUint:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyUint:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadUintString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadUintString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyUintString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyUintString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadUintPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadUintPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendUint(ctx, b, p, code)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyUintPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyUintPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p, code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadUintPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadUintPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyUintPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyUintPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadFloat32:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadFloat32:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat32:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat32:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadFloat32String:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadFloat32String:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat32String:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat32String:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadFloat64:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadFloat64:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat64:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat64:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v == 0 {
+ code = code.NextField
+ } else {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadFloat64String:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadFloat64String:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat64String:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat64String:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v == 0 {
+ code = code.NextField
+ } else {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNull(ctx, b)
+ b = appendComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToString(p + uintptr(code.Offset))
+ if v == "" {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadStringString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadStringString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p+uintptr(code.Offset)))))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyStringString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyStringString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToString(p + uintptr(code.Offset))
+ if v == "" {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, v)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadStringPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadStringPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, ptrToString(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyStringPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyStringPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadStringPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadStringPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyStringPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyStringPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadBool:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadBool:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBool:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBool:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructPtrHeadBoolString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadBoolString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBoolString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBoolString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructPtrHeadBoolPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadBoolPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendBool(ctx, b, ptrToBool(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBoolPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBoolPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadBytes:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadBytes:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBytes:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBytes:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToBytes(p + uintptr(code.Offset))
+ if len(v) == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadBytesPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadBytesPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBytesPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBytesPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadNumber:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadNumber:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyNumber:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyNumber:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v == "" {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadNumberString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadNumberString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyNumberString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyNumberString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v == "" {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadNumberPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadNumberPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyNumberPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyNumberPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadArray, encoder.OpStructPtrHeadSlice:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadArray, encoder.OpStructHeadSlice:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructPtrHeadOmitEmptyArray:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyArray:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructPtrHeadOmitEmptySlice:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptySlice:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ slice := ptrToSlice(p)
+ if slice.Len == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadArrayPtr, encoder.OpStructPtrHeadSlicePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadArrayPtr, encoder.OpStructHeadSlicePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.NextField
+ } else {
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadOmitEmptyArrayPtr, encoder.OpStructPtrHeadOmitEmptySlicePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyArrayPtr, encoder.OpStructHeadOmitEmptySlicePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ p = ptrToPtr(p + uintptr(code.Offset))
+ }
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructPtrHeadOmitEmptyMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ p = ptrToPtr(p + uintptr(code.Offset))
+ }
+ if maplen(ptrToUnsafePtr(p)) == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadMapPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadMapPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.NextField
+ break
+ }
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.NextField
+ } else {
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p, code.PtrNum)
+ }
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadOmitEmptyMapPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMapPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if p == 0 {
+ code = code.NextField
+ break
+ }
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p == 0 {
+ code = code.NextField
+ } else {
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p, code.PtrNum)
+ }
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON {
+ p = ptrToPtr(p)
+ }
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON {
+ p = ptrToPtr(p)
+ }
+ }
+ iface := ptrToInterface(code, p)
+ if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalJSON(ctx, code, b, iface)
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if p == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText {
+ p = ptrToPtr(p)
+ }
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText {
+ p = ptrToPtr(p)
+ }
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if p == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructField:
+ if code.Flags&encoder.IsTaggedKeyFlags != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 {
+ b = appendStructKey(ctx, code, b)
+ }
+ p := load(ctxptr, code.Idx) + uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmpty:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructFieldInt:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyInt:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldIntString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyIntString:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldIntPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendInt(ctx, b, p, code)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyIntPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p, code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldIntPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyIntPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldUint:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyUint:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldUintString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyUintString:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldUintPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendUint(ctx, b, p, code)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyUintPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p, code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldUintPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyUintPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat32:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat32:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat32String:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat32String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat64:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat64:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v != 0 {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat64String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat64String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v != 0 {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToString(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldStringString:
+ p := load(ctxptr, code.Idx)
+ s := ptrToString(p + uintptr(code.Offset))
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, s)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyStringString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToString(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, v)))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldStringPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, ptrToString(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyStringPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldStringPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyStringPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBool:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBool:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBoolString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBoolString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBoolPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendBool(ctx, b, ptrToBool(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBoolPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBytes:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBytes:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBytes(p + uintptr(code.Offset))
+ if len(v) > 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBytesPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBytesPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldNumber:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyNumber:
+ p := load(ctxptr, code.Idx)
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructFieldNumberString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyNumberString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldNumberPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyNumberPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructFieldNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ code = code.NextField
+ break
+ }
+ iface := ptrToInterface(code, p)
+ if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) {
+ code = code.NextField
+ break
+ }
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalJSON(ctx, code, b, iface)
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpStructFieldMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructFieldMarshalText:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyMarshalText:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ code = code.NextField
+ break
+ }
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpStructFieldMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructFieldArray:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyArray:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldArrayPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyArrayPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructFieldSlice:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptySlice:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ slice := ptrToSlice(p)
+ if slice.Len == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructFieldSlicePtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptySlicePtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructFieldMap:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToPtr(p + uintptr(code.Offset))
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyMap:
+ p := load(ctxptr, code.Idx)
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p == 0 || maplen(ptrToUnsafePtr(p)) == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructFieldMapPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p != 0 {
+ p = ptrToNPtr(p, code.PtrNum)
+ }
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyMapPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p != 0 {
+ p = ptrToNPtr(p, code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructFieldStruct:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyStruct:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructEnd:
+ b = appendStructEndSkipLast(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndInt:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyInt:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndIntString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyIntString:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndIntPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendInt(ctx, b, p, code)
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyIntPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p, code)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndIntPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyIntPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndUint:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyUint:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndUintString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyUintString:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndUintPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendUint(ctx, b, p, code)
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyUintPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p, code)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndUintPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyUintPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat32:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat32:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat32String:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat32String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat32Ptr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat32PtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat64:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat64:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v != 0 {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat64String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat64String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v != 0 {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat64Ptr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ break
+ }
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat64PtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToString(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndStringString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ s := ptrToString(p + uintptr(code.Offset))
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, s)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyStringString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToString(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, v)))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndStringPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, ptrToString(p))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyStringPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndStringPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyStringPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBool:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBool:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBoolString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBoolString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBoolPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendBool(ctx, b, ptrToBool(p))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBoolPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBoolPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBytes:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBytes:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBytes(p + uintptr(code.Offset))
+ if len(v) > 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBytesPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBytesPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndNumber:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = appendStructEnd(ctx, code, bb)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyNumber:
+ p := load(ctxptr, code.Idx)
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = appendStructEnd(ctx, code, bb)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndNumberString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyNumberString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndNumberPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyNumberPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendStructEnd(ctx, code, bb)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndNumberPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpEnd:
+ goto END
+ }
+ }
+END:
+ return b, nil
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go
new file mode 100644
index 00000000..99395388
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go
@@ -0,0 +1,35 @@
+package vm_indent
+
+import (
+ "fmt"
+
+ "github.com/goccy/go-json/internal/encoder"
+)
+
+func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
+ var code *encoder.Opcode
+ if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
+ code = codeSet.EscapeKeyCode
+ } else {
+ code = codeSet.NoescapeKeyCode
+ }
+
+ defer func() {
+ if err := recover(); err != nil {
+ w := ctx.Option.DebugOut
+ fmt.Fprintln(w, "=============[DEBUG]===============")
+ fmt.Fprintln(w, "* [TYPE]")
+ fmt.Fprintln(w, codeSet.Type)
+ fmt.Fprintf(w, "\n")
+ fmt.Fprintln(w, "* [ALL OPCODE]")
+ fmt.Fprintln(w, code.Dump())
+ fmt.Fprintf(w, "\n")
+ fmt.Fprintln(w, "* [CONTEXT]")
+ fmt.Fprintf(w, "%+v\n", ctx)
+ fmt.Fprintln(w, "===================================")
+ panic(err)
+ }
+ }()
+
+ return Run(ctx, b, codeSet)
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go
new file mode 100644
index 00000000..9e245bfe
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go
@@ -0,0 +1,9 @@
+package vm_indent
+
+import (
+ // HACK: compile order
+ // `vm`, `vm_indent`, `vm_color`, `vm_color_indent` packages uses a lot of memory to compile,
+ // so forcibly make dependencies and avoid compiling in concurrent.
+ // dependency order: vm => vm_indent => vm_color => vm_color_indent
+ _ "github.com/goccy/go-json/internal/encoder/vm_color"
+)
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go
new file mode 100644
index 00000000..6cb745e3
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go
@@ -0,0 +1,230 @@
+package vm_indent
+
+import (
+ "encoding/json"
+ "fmt"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/encoder"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+const uintptrSize = 4 << (^uintptr(0) >> 63)
+
+var (
+ appendInt = encoder.AppendInt
+ appendUint = encoder.AppendUint
+ appendFloat32 = encoder.AppendFloat32
+ appendFloat64 = encoder.AppendFloat64
+ appendString = encoder.AppendString
+ appendByteSlice = encoder.AppendByteSlice
+ appendNumber = encoder.AppendNumber
+ appendStructEnd = encoder.AppendStructEndIndent
+ appendIndent = encoder.AppendIndent
+ errUnsupportedValue = encoder.ErrUnsupportedValue
+ errUnsupportedFloat = encoder.ErrUnsupportedFloat
+ mapiterinit = encoder.MapIterInit
+ mapiterkey = encoder.MapIterKey
+ mapitervalue = encoder.MapIterValue
+ mapiternext = encoder.MapIterNext
+ maplen = encoder.MapLen
+)
+
+type emptyInterface struct {
+ typ *runtime.Type
+ ptr unsafe.Pointer
+}
+
+type nonEmptyInterface struct {
+ itab *struct {
+ ityp *runtime.Type // static interface type
+ typ *runtime.Type // dynamic concrete type
+ // unused fields...
+ }
+ ptr unsafe.Pointer
+}
+
+func errUnimplementedOp(op encoder.OpType) error {
+ return fmt.Errorf("encoder (indent): opcode %s has not been implemented", op)
+}
+
+func load(base uintptr, idx uint32) uintptr {
+ addr := base + uintptr(idx)
+ return **(**uintptr)(unsafe.Pointer(&addr))
+}
+
+func store(base uintptr, idx uint32, p uintptr) {
+ addr := base + uintptr(idx)
+ **(**uintptr)(unsafe.Pointer(&addr)) = p
+}
+
+func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr {
+ addr := base + uintptr(idx)
+ p := **(**uintptr)(unsafe.Pointer(&addr))
+ for i := uint8(0); i < ptrNum; i++ {
+ if p == 0 {
+ return 0
+ }
+ p = ptrToPtr(p)
+ }
+ return p
+}
+
+func ptrToUint64(p uintptr, bitSize uint8) uint64 {
+ switch bitSize {
+ case 8:
+ return (uint64)(**(**uint8)(unsafe.Pointer(&p)))
+ case 16:
+ return (uint64)(**(**uint16)(unsafe.Pointer(&p)))
+ case 32:
+ return (uint64)(**(**uint32)(unsafe.Pointer(&p)))
+ case 64:
+ return **(**uint64)(unsafe.Pointer(&p))
+ }
+ return 0
+}
+func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) }
+func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) }
+func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) }
+func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) }
+func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) }
+func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) }
+func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) }
+func ptrToPtr(p uintptr) uintptr {
+ return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p)))
+}
+func ptrToNPtr(p uintptr, ptrNum uint8) uintptr {
+ for i := uint8(0); i < ptrNum; i++ {
+ if p == 0 {
+ return 0
+ }
+ p = ptrToPtr(p)
+ }
+ return p
+}
+
+func ptrToUnsafePtr(p uintptr) unsafe.Pointer {
+ return *(*unsafe.Pointer)(unsafe.Pointer(&p))
+}
+func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} {
+ return *(*interface{})(unsafe.Pointer(&emptyInterface{
+ typ: code.Type,
+ ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)),
+ }))
+}
+
+func appendBool(_ *encoder.RuntimeContext, b []byte, v bool) []byte {
+ if v {
+ return append(b, "true"...)
+ }
+ return append(b, "false"...)
+}
+
+func appendNull(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, "null"...)
+}
+
+func appendComma(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, ',', '\n')
+}
+
+func appendNullComma(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, "null,\n"...)
+}
+
+func appendColon(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b[:len(b)-2], ':', ' ')
+}
+
+func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte {
+ b = appendIndent(ctx, b, code.Indent+1)
+ b = append(b, key...)
+ b[len(b)-2] = ':'
+ b[len(b)-1] = ' '
+ return append(b, value...)
+}
+
+func appendMapEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ b = b[:len(b)-2]
+ b = append(b, '\n')
+ b = appendIndent(ctx, b, code.Indent)
+ return append(b, '}', ',', '\n')
+}
+
+func appendArrayHead(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ b = append(b, '[', '\n')
+ return appendIndent(ctx, b, code.Indent+1)
+}
+
+func appendArrayEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ b = b[:len(b)-2]
+ b = append(b, '\n')
+ b = appendIndent(ctx, b, code.Indent)
+ return append(b, ']', ',', '\n')
+}
+
+func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, '[', ']', ',', '\n')
+}
+
+func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, '{', '}', ',', '\n')
+}
+
+func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ last := len(b) - 1
+ // replace comma to newline
+ b[last-1] = '\n'
+ b = appendIndent(ctx, b[:last], code.Indent)
+ return append(b, '}', ',', '\n')
+}
+
+func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) {
+ return encoder.AppendMarshalJSONIndent(ctx, code, b, v)
+}
+
+func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) {
+ return encoder.AppendMarshalTextIndent(ctx, code, b, v)
+}
+
+func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte {
+ return append(b, '{', '\n')
+}
+
+func appendStructKey(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ b = appendIndent(ctx, b, code.Indent)
+ b = append(b, code.Key...)
+ return append(b, ' ')
+}
+
+func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ last := len(b) - 1
+ if b[last-1] == '{' {
+ b[last] = '}'
+ } else {
+ if b[last] == '\n' {
+ // to remove ',' and '\n' characters
+ b = b[:len(b)-2]
+ }
+ b = append(b, '\n')
+ b = appendIndent(ctx, b, code.Indent-1)
+ b = append(b, '}')
+ }
+ return appendComma(ctx, b)
+}
+
+func restoreIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, ctxptr uintptr) {
+ ctx.BaseIndent = uint32(load(ctxptr, code.Length))
+}
+
+func storeIndent(ctxptr uintptr, code *encoder.Opcode, indent uintptr) {
+ store(ctxptr, code.Length, indent)
+}
+
+func appendArrayElemIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ return appendIndent(ctx, b, code.Indent+1)
+}
+
+func appendMapKeyIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte {
+ return appendIndent(ctx, b, code.Indent)
+}
diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go
new file mode 100644
index 00000000..836c5c8a
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go
@@ -0,0 +1,4859 @@
+// Code generated by internal/cmd/generator. DO NOT EDIT!
+package vm_indent
+
+import (
+ "math"
+ "reflect"
+ "sort"
+ "unsafe"
+
+ "github.com/goccy/go-json/internal/encoder"
+ "github.com/goccy/go-json/internal/runtime"
+)
+
+func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) {
+ recursiveLevel := 0
+ ptrOffset := uintptr(0)
+ ctxptr := ctx.Ptr()
+ var code *encoder.Opcode
+ if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
+ code = codeSet.EscapeKeyCode
+ } else {
+ code = codeSet.NoescapeKeyCode
+ }
+
+ for {
+ switch code.Op {
+ default:
+ return nil, errUnimplementedOp(code.Op)
+ case encoder.OpPtr:
+ p := load(ctxptr, code.Idx)
+ code = code.Next
+ store(ctxptr, code.Idx, ptrToPtr(p))
+ case encoder.OpIntPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpInt:
+ b = appendInt(ctx, b, load(ctxptr, code.Idx), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpUintPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpUint:
+ b = appendUint(ctx, b, load(ctxptr, code.Idx), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpIntString:
+ b = append(b, '"')
+ b = appendInt(ctx, b, load(ctxptr, code.Idx), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpUintString:
+ b = append(b, '"')
+ b = appendUint(ctx, b, load(ctxptr, code.Idx), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpFloat32Ptr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ b = appendComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpFloat32:
+ b = appendFloat32(ctx, b, ptrToFloat32(load(ctxptr, code.Idx)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpFloat64Ptr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpFloat64:
+ v := ptrToFloat64(load(ctxptr, code.Idx))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStringPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpString:
+ b = appendString(ctx, b, ptrToString(load(ctxptr, code.Idx)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpBoolPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpBool:
+ b = appendBool(ctx, b, ptrToBool(load(ctxptr, code.Idx)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpBytesPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpBytes:
+ b = appendByteSlice(ctx, b, ptrToBytes(load(ctxptr, code.Idx)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpNumberPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpNumber:
+ bb, err := appendNumber(ctx, b, ptrToNumber(load(ctxptr, code.Idx)))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpInterfacePtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpInterface:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ if recursiveLevel > encoder.StartDetectingCyclesAfter {
+ for _, seen := range ctx.SeenPtr {
+ if p == seen {
+ return nil, errUnsupportedValue(code, p)
+ }
+ }
+ }
+ ctx.SeenPtr = append(ctx.SeenPtr, p)
+ var (
+ typ *runtime.Type
+ ifacePtr unsafe.Pointer
+ )
+ up := ptrToUnsafePtr(p)
+ if code.Flags&encoder.NonEmptyInterfaceFlags != 0 {
+ iface := (*nonEmptyInterface)(up)
+ ifacePtr = iface.ptr
+ if iface.itab != nil {
+ typ = iface.itab.typ
+ }
+ } else {
+ iface := (*emptyInterface)(up)
+ ifacePtr = iface.ptr
+ typ = iface.typ
+ }
+ if ifacePtr == nil {
+ isDirectedNil := typ != nil && typ.Kind() == reflect.Struct && !runtime.IfaceIndir(typ)
+ if !isDirectedNil {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ }
+ ctx.KeepRefs = append(ctx.KeepRefs, up)
+ ifaceCodeSet, err := encoder.CompileToGetCodeSet(ctx, uintptr(unsafe.Pointer(typ)))
+ if err != nil {
+ return nil, err
+ }
+
+ totalLength := uintptr(code.Length) + 3
+ nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3
+
+ var c *encoder.Opcode
+ if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 {
+ c = ifaceCodeSet.InterfaceEscapeKeyCode
+ } else {
+ c = ifaceCodeSet.InterfaceNoescapeKeyCode
+ }
+ curlen := uintptr(len(ctx.Ptrs))
+ offsetNum := ptrOffset / uintptrSize
+ oldOffset := ptrOffset
+ ptrOffset += totalLength * uintptrSize
+ oldBaseIndent := ctx.BaseIndent
+ ctx.BaseIndent += code.Indent
+
+ newLen := offsetNum + totalLength + nextTotalLength
+ if curlen < newLen {
+ ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
+ }
+ ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr
+
+ end := ifaceCodeSet.EndCode
+ store(ctxptr, c.Idx, uintptr(ifacePtr))
+ store(ctxptr, end.Idx, oldOffset)
+ store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
+ storeIndent(ctxptr, end, uintptr(oldBaseIndent))
+ code = c
+ recursiveLevel++
+ case encoder.OpInterfaceEnd:
+ recursiveLevel--
+
+ // restore ctxptr
+ offset := load(ctxptr, code.Idx)
+ restoreIndent(ctx, code, ctxptr)
+ ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1]
+
+ codePtr := load(ctxptr, code.ElemIdx)
+ code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr))
+ ctxptr = ctx.Ptr() + offset
+ ptrOffset = offset
+ case encoder.OpMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToPtr(p))
+ fallthrough
+ case encoder.OpMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToPtr(p))
+ fallthrough
+ case encoder.OpMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = append(b, `""`...)
+ b = appendComma(ctx, b)
+ code = code.Next
+ break
+ }
+ if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpSlicePtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpSlice:
+ p := load(ctxptr, code.Idx)
+ slice := ptrToSlice(p)
+ if p == 0 || slice.Data == nil {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.ElemIdx, 0)
+ store(ctxptr, code.Length, uintptr(slice.Len))
+ store(ctxptr, code.Idx, uintptr(slice.Data))
+ if slice.Len > 0 {
+ b = appendArrayHead(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, uintptr(slice.Data))
+ } else {
+ b = appendEmptyArray(ctx, b)
+ code = code.End.Next
+ }
+ case encoder.OpSliceElem:
+ idx := load(ctxptr, code.ElemIdx)
+ length := load(ctxptr, code.Length)
+ idx++
+ if idx < length {
+ b = appendArrayElemIndent(ctx, code, b)
+ store(ctxptr, code.ElemIdx, idx)
+ data := load(ctxptr, code.Idx)
+ size := uintptr(code.Size)
+ code = code.Next
+ store(ctxptr, code.Idx, data+idx*size)
+ } else {
+ b = appendArrayEnd(ctx, code, b)
+ code = code.End.Next
+ }
+ case encoder.OpArrayPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpArray:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ if code.Length > 0 {
+ b = appendArrayHead(ctx, code, b)
+ store(ctxptr, code.ElemIdx, 0)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ } else {
+ b = appendEmptyArray(ctx, b)
+ code = code.End.Next
+ }
+ case encoder.OpArrayElem:
+ idx := load(ctxptr, code.ElemIdx)
+ idx++
+ if idx < uintptr(code.Length) {
+ b = appendArrayElemIndent(ctx, code, b)
+ store(ctxptr, code.ElemIdx, idx)
+ p := load(ctxptr, code.Idx)
+ size := uintptr(code.Size)
+ code = code.Next
+ store(ctxptr, code.Idx, p+idx*size)
+ } else {
+ b = appendArrayEnd(ctx, code, b)
+ code = code.End.Next
+ }
+ case encoder.OpMapPtr:
+ p := loadNPtr(ctxptr, code.Idx, code.PtrNum)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, p)
+ fallthrough
+ case encoder.OpMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.End.Next
+ break
+ }
+ uptr := ptrToUnsafePtr(p)
+ mlen := maplen(uptr)
+ if mlen <= 0 {
+ b = appendEmptyObject(ctx, b)
+ code = code.End.Next
+ break
+ }
+ b = appendStructHead(ctx, b)
+ unorderedMap := (ctx.Option.Flag & encoder.UnorderedMapOption) != 0
+ mapCtx := encoder.NewMapContext(mlen, unorderedMap)
+ mapiterinit(code.Type, uptr, &mapCtx.Iter)
+ store(ctxptr, code.Idx, uintptr(unsafe.Pointer(mapCtx)))
+ ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx))
+ if unorderedMap {
+ b = appendMapKeyIndent(ctx, code.Next, b)
+ } else {
+ mapCtx.Start = len(b)
+ mapCtx.First = len(b)
+ }
+ key := mapiterkey(&mapCtx.Iter)
+ store(ctxptr, code.Next.Idx, uintptr(key))
+ code = code.Next
+ case encoder.OpMapKey:
+ mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx)))
+ idx := mapCtx.Idx
+ idx++
+ if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
+ if idx < mapCtx.Len {
+ b = appendMapKeyIndent(ctx, code, b)
+ mapCtx.Idx = int(idx)
+ key := mapiterkey(&mapCtx.Iter)
+ store(ctxptr, code.Next.Idx, uintptr(key))
+ code = code.Next
+ } else {
+ b = appendObjectEnd(ctx, code, b)
+ encoder.ReleaseMapContext(mapCtx)
+ code = code.End.Next
+ }
+ } else {
+ mapCtx.Slice.Items[mapCtx.Idx].Value = b[mapCtx.Start:len(b)]
+ if idx < mapCtx.Len {
+ mapCtx.Idx = int(idx)
+ mapCtx.Start = len(b)
+ key := mapiterkey(&mapCtx.Iter)
+ store(ctxptr, code.Next.Idx, uintptr(key))
+ code = code.Next
+ } else {
+ code = code.End
+ }
+ }
+ case encoder.OpMapValue:
+ mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx)))
+ if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 {
+ b = appendColon(ctx, b)
+ } else {
+ mapCtx.Slice.Items[mapCtx.Idx].Key = b[mapCtx.Start:len(b)]
+ mapCtx.Start = len(b)
+ }
+ value := mapitervalue(&mapCtx.Iter)
+ store(ctxptr, code.Next.Idx, uintptr(value))
+ mapiternext(&mapCtx.Iter)
+ code = code.Next
+ case encoder.OpMapEnd:
+ // this operation only used by sorted map.
+ mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(load(ctxptr, code.Idx)))
+ sort.Sort(mapCtx.Slice)
+ buf := mapCtx.Buf
+ for _, item := range mapCtx.Slice.Items {
+ buf = appendMapKeyValue(ctx, code, buf, item.Key, item.Value)
+ }
+ buf = appendMapEnd(ctx, code, buf)
+ b = b[:mapCtx.First]
+ b = append(b, buf...)
+ mapCtx.Buf = buf
+ encoder.ReleaseMapContext(mapCtx)
+ code = code.Next
+ case encoder.OpRecursivePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ code = code.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpRecursive:
+ ptr := load(ctxptr, code.Idx)
+ if ptr != 0 {
+ if recursiveLevel > encoder.StartDetectingCyclesAfter {
+ for _, seen := range ctx.SeenPtr {
+ if ptr == seen {
+ return nil, errUnsupportedValue(code, ptr)
+ }
+ }
+ }
+ }
+ ctx.SeenPtr = append(ctx.SeenPtr, ptr)
+ c := code.Jmp.Code
+ curlen := uintptr(len(ctx.Ptrs))
+ offsetNum := ptrOffset / uintptrSize
+ oldOffset := ptrOffset
+ ptrOffset += code.Jmp.CurLen * uintptrSize
+ oldBaseIndent := ctx.BaseIndent
+ indentDiffFromTop := c.Indent - 1
+ ctx.BaseIndent += code.Indent - indentDiffFromTop
+
+ newLen := offsetNum + code.Jmp.CurLen + code.Jmp.NextLen
+ if curlen < newLen {
+ ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...)
+ }
+ ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr
+
+ store(ctxptr, c.Idx, ptr)
+ store(ctxptr, c.End.Next.Idx, oldOffset)
+ store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next)))
+ storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent))
+ code = c
+ recursiveLevel++
+ case encoder.OpRecursiveEnd:
+ recursiveLevel--
+
+ // restore ctxptr
+ restoreIndent(ctx, code, ctxptr)
+ offset := load(ctxptr, code.Idx)
+ ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1]
+
+ codePtr := load(ctxptr, code.ElemIdx)
+ code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr))
+ ctxptr = ctx.Ptr() + offset
+ ptrOffset = offset
+ case encoder.OpStructPtrHead:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHead:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if len(code.Key) > 0 {
+ if (code.Flags&encoder.IsTaggedKeyFlags) != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 {
+ b = appendStructKey(ctx, code, b)
+ }
+ }
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructPtrHeadOmitEmpty:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmpty:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ if p == 0 || (ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0) {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadInt:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadInt:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyInt:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyInt:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadIntString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadIntString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyIntString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyIntString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ u64 := ptrToUint64(p, code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadIntPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadIntPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendInt(ctx, b, p, code)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyIntPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyIntPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p, code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadIntPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadIntPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyIntPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyIntPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadUint:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadUint:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyUint:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyUint:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadUintString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadUintString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyUintString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyUintString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadUintPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadUintPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendUint(ctx, b, p, code)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyUintPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyUintPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p, code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadUintPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadUintPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyUintPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyUintPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadFloat32:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadFloat32:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat32:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat32:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadFloat32String:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadFloat32String:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat32String:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat32String:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadFloat64:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadFloat64:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat64:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat64:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v == 0 {
+ code = code.NextField
+ } else {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadFloat64String:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadFloat64String:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat64String:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat64String:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v == 0 {
+ code = code.NextField
+ } else {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNull(ctx, b)
+ b = appendComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToString(p + uintptr(code.Offset))
+ if v == "" {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadStringString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadStringString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p+uintptr(code.Offset)))))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyStringString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyStringString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToString(p + uintptr(code.Offset))
+ if v == "" {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, v)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadStringPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadStringPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, ptrToString(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyStringPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyStringPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadStringPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadStringPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyStringPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyStringPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadBool:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadBool:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBool:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBool:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructPtrHeadBoolString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadBoolString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBoolString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBoolString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructPtrHeadBoolPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadBoolPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendBool(ctx, b, ptrToBool(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBoolPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBoolPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadBytes:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadBytes:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBytes:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBytes:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToBytes(p + uintptr(code.Offset))
+ if len(v) == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadBytesPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadBytesPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyBytesPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyBytesPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadNumber:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadNumber:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyNumber:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyNumber:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v == "" {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadNumberString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadNumberString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyNumberString:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyNumberString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v == "" {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadNumberPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadNumberPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyNumberPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyNumberPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructPtrHeadArray, encoder.OpStructPtrHeadSlice:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadArray, encoder.OpStructHeadSlice:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructPtrHeadOmitEmptyArray:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyArray:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructPtrHeadOmitEmptySlice:
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptySlice:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ slice := ptrToSlice(p)
+ if slice.Len == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadArrayPtr, encoder.OpStructPtrHeadSlicePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadArrayPtr, encoder.OpStructHeadSlicePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.NextField
+ } else {
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadOmitEmptyArrayPtr, encoder.OpStructPtrHeadOmitEmptySlicePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyArrayPtr, encoder.OpStructHeadOmitEmptySlicePtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ p = ptrToPtr(p + uintptr(code.Offset))
+ }
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructPtrHeadOmitEmptyMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMap:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ p = ptrToPtr(p + uintptr(code.Offset))
+ }
+ if maplen(ptrToUnsafePtr(p)) == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadMapPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadMapPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.NextField
+ break
+ }
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.NextField
+ } else {
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p, code.PtrNum)
+ }
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadOmitEmptyMapPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMapPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if p == 0 {
+ code = code.NextField
+ break
+ }
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p == 0 {
+ code = code.NextField
+ } else {
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p, code.PtrNum)
+ }
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructPtrHeadMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON {
+ p = ptrToPtr(p)
+ }
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON {
+ p = ptrToPtr(p)
+ }
+ }
+ iface := ptrToInterface(code, p)
+ if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalJSON(ctx, code, b, iface)
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if p == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText {
+ p = ptrToPtr(p)
+ }
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ }
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMarshalText:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText {
+ p = ptrToPtr(p)
+ }
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructPtrHeadMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ b = appendStructKey(ctx, code, b)
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructPtrHeadOmitEmptyMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum))
+ fallthrough
+ case encoder.OpStructHeadOmitEmptyMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 {
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendNullComma(ctx, b)
+ }
+ code = code.End.Next
+ break
+ }
+ if (code.Flags & encoder.IndirectFlags) != 0 {
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ }
+ if code.Flags&encoder.AnonymousHeadFlags == 0 {
+ b = appendStructHead(ctx, b)
+ }
+ if p == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ b = appendComma(ctx, b)
+ code = code.Next
+ }
+ case encoder.OpStructField:
+ if code.Flags&encoder.IsTaggedKeyFlags != 0 || code.Flags&encoder.AnonymousKeyFlags == 0 {
+ b = appendStructKey(ctx, code, b)
+ }
+ p := load(ctxptr, code.Idx) + uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmpty:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructFieldInt:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyInt:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldIntString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyIntString:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldIntPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendInt(ctx, b, p, code)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyIntPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p, code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldIntPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyIntPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldUint:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyUint:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldUintString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyUintString:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldUintPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendUint(ctx, b, p, code)
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyUintPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p, code)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldUintPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyUintPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat32:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat32:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat32String:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat32String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat64:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat64:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v != 0 {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat64String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat64String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v != 0 {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNullComma(ctx, b)
+ code = code.Next
+ break
+ }
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToString(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldStringString:
+ p := load(ctxptr, code.Idx)
+ s := ptrToString(p + uintptr(code.Offset))
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, s)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyStringString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToString(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, v)))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldStringPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, ptrToString(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyStringPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldStringPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyStringPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBool:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBool:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBoolString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBoolString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, v)
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBoolPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendBool(ctx, b, ptrToBool(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBoolPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBytes:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset)))
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBytes:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBytes(p + uintptr(code.Offset))
+ if len(v) > 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, v)
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldBytesPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyBytesPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldNumber:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyNumber:
+ p := load(ctxptr, code.Idx)
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructFieldNumberString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyNumberString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldNumberPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyNumberPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructFieldNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ b = appendStructKey(ctx, code, b)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendComma(ctx, b)
+ }
+ code = code.Next
+ case encoder.OpStructFieldMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyMarshalJSON:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ code = code.NextField
+ break
+ }
+ iface := ptrToInterface(code, p)
+ if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) {
+ code = code.NextField
+ break
+ }
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalJSON(ctx, code, b, iface)
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpStructFieldMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyMarshalJSONPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructFieldMarshalText:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyMarshalText:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ if (code.Flags & encoder.IsNilableTypeFlags) != 0 {
+ p = ptrToPtr(p)
+ }
+ if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 {
+ code = code.NextField
+ break
+ }
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ code = code.Next
+ case encoder.OpStructFieldMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendComma(ctx, b)
+ code = code.Next
+ case encoder.OpStructFieldOmitEmptyMarshalTextPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendComma(ctx, bb)
+ }
+ code = code.Next
+ case encoder.OpStructFieldArray:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyArray:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldArrayPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyArrayPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructFieldSlice:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptySlice:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ slice := ptrToSlice(p)
+ if slice.Len == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructFieldSlicePtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptySlicePtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructFieldMap:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToPtr(p + uintptr(code.Offset))
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyMap:
+ p := load(ctxptr, code.Idx)
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p == 0 || maplen(ptrToUnsafePtr(p)) == 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructFieldMapPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p != 0 {
+ p = ptrToNPtr(p, code.PtrNum)
+ }
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyMapPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToPtr(p + uintptr(code.Offset))
+ if p != 0 {
+ p = ptrToNPtr(p, code.PtrNum)
+ }
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ } else {
+ code = code.NextField
+ }
+ case encoder.OpStructFieldStruct:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ case encoder.OpStructFieldOmitEmptyStruct:
+ p := load(ctxptr, code.Idx)
+ p += uintptr(code.Offset)
+ if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 {
+ code = code.NextField
+ } else {
+ b = appendStructKey(ctx, code, b)
+ code = code.Next
+ store(ctxptr, code.Idx, p)
+ }
+ case encoder.OpStructEnd:
+ b = appendStructEndSkipLast(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndInt:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyInt:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndIntString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyIntString:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndIntPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendInt(ctx, b, p, code)
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyIntPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendInt(ctx, b, p, code)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndIntPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyIntPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendInt(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndUint:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyUint:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndUintString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyUintString:
+ p := load(ctxptr, code.Idx)
+ u64 := ptrToUint64(p+uintptr(code.Offset), code.NumBitSize)
+ v := u64 & ((1 << code.NumBitSize) - 1)
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p+uintptr(code.Offset), code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndUintPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendUint(ctx, b, p, code)
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyUintPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendUint(ctx, b, p, code)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndUintPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyUintPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendUint(ctx, b, p, code)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat32:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat32:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat32String:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat32String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat32(p + uintptr(code.Offset))
+ if v != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat32Ptr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat32Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat32PtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat32PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat32(ctx, b, ptrToFloat32(p))
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat64:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat64:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v != 0 {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = appendFloat64(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat64String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat64String:
+ p := load(ctxptr, code.Idx)
+ v := ptrToFloat64(p + uintptr(code.Offset))
+ if v != 0 {
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat64Ptr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ break
+ }
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat64Ptr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndFloat64PtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyFloat64PtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ v := ptrToFloat64(p)
+ if math.IsInf(v, 0) || math.IsNaN(v) {
+ return nil, errUnsupportedFloat(v)
+ }
+ b = append(b, '"')
+ b = appendFloat64(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToString(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndStringString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ s := ptrToString(p + uintptr(code.Offset))
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, s)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyStringString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToString(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, v)))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndStringPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, ptrToString(p))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyStringPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, ptrToString(p))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndStringPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyStringPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p))))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBool:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBool:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBoolString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset)))
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBoolString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBool(p + uintptr(code.Offset))
+ if v {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, v)
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBoolPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendBool(ctx, b, ptrToBool(p))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBoolPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBoolPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBoolPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ b = appendBool(ctx, b, ptrToBool(p))
+ b = append(b, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBytes:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset)))
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBytes:
+ p := load(ctxptr, code.Idx)
+ v := ptrToBytes(p + uintptr(code.Offset))
+ if len(v) > 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, v)
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndBytesPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyBytesPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = appendByteSlice(ctx, b, ptrToBytes(p))
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndNumber:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = appendStructEnd(ctx, code, bb)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyNumber:
+ p := load(ctxptr, code.Idx)
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = appendStructEnd(ctx, code, bb)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndNumberString:
+ p := load(ctxptr, code.Idx)
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset)))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyNumberString:
+ p := load(ctxptr, code.Idx)
+ v := ptrToNumber(p + uintptr(code.Offset))
+ if v != "" {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, v)
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndNumberPtr:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = bb
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyNumberPtr:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = appendStructEnd(ctx, code, bb)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpStructEndNumberPtrString:
+ b = appendStructKey(ctx, code, b)
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p == 0 {
+ b = appendNull(ctx, b)
+ } else {
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ }
+ b = appendStructEnd(ctx, code, b)
+ code = code.Next
+ case encoder.OpStructEndOmitEmptyNumberPtrString:
+ p := load(ctxptr, code.Idx)
+ p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum)
+ if p != 0 {
+ b = appendStructKey(ctx, code, b)
+ b = append(b, '"')
+ bb, err := appendNumber(ctx, b, ptrToNumber(p))
+ if err != nil {
+ return nil, err
+ }
+ b = append(bb, '"')
+ b = appendStructEnd(ctx, code, b)
+ } else {
+ b = appendStructEndSkipLast(ctx, code, b)
+ }
+ code = code.Next
+ case encoder.OpEnd:
+ goto END
+ }
+ }
+END:
+ return b, nil
+}
diff --git a/vendor/github.com/goccy/go-json/internal/errors/error.go b/vendor/github.com/goccy/go-json/internal/errors/error.go
new file mode 100644
index 00000000..9207d0ff
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/errors/error.go
@@ -0,0 +1,183 @@
+package errors
+
+import (
+ "fmt"
+ "reflect"
+ "strconv"
+)
+
+type InvalidUTF8Error struct {
+ S string // the whole string value that caused the error
+}
+
+func (e *InvalidUTF8Error) Error() string {
+ return fmt.Sprintf("json: invalid UTF-8 in string: %s", strconv.Quote(e.S))
+}
+
+type InvalidUnmarshalError struct {
+ Type reflect.Type
+}
+
+func (e *InvalidUnmarshalError) Error() string {
+ if e.Type == nil {
+ return "json: Unmarshal(nil)"
+ }
+
+ if e.Type.Kind() != reflect.Ptr {
+ return fmt.Sprintf("json: Unmarshal(non-pointer %s)", e.Type)
+ }
+ return fmt.Sprintf("json: Unmarshal(nil %s)", e.Type)
+}
+
+// A MarshalerError represents an error from calling a MarshalJSON or MarshalText method.
+type MarshalerError struct {
+ Type reflect.Type
+ Err error
+ sourceFunc string
+}
+
+func (e *MarshalerError) Error() string {
+ srcFunc := e.sourceFunc
+ if srcFunc == "" {
+ srcFunc = "MarshalJSON"
+ }
+ return fmt.Sprintf("json: error calling %s for type %s: %s", srcFunc, e.Type, e.Err.Error())
+}
+
+// Unwrap returns the underlying error.
+func (e *MarshalerError) Unwrap() error { return e.Err }
+
+// A SyntaxError is a description of a JSON syntax error.
+type SyntaxError struct {
+ msg string // description of error
+ Offset int64 // error occurred after reading Offset bytes
+}
+
+func (e *SyntaxError) Error() string { return e.msg }
+
+// An UnmarshalFieldError describes a JSON object key that
+// led to an unexported (and therefore unwritable) struct field.
+//
+// Deprecated: No longer used; kept for compatibility.
+type UnmarshalFieldError struct {
+ Key string
+ Type reflect.Type
+ Field reflect.StructField
+}
+
+func (e *UnmarshalFieldError) Error() string {
+ return fmt.Sprintf("json: cannot unmarshal object key %s into unexported field %s of type %s",
+ strconv.Quote(e.Key), e.Field.Name, e.Type.String(),
+ )
+}
+
+// An UnmarshalTypeError describes a JSON value that was
+// not appropriate for a value of a specific Go type.
+type UnmarshalTypeError struct {
+ Value string // description of JSON value - "bool", "array", "number -5"
+ Type reflect.Type // type of Go value it could not be assigned to
+ Offset int64 // error occurred after reading Offset bytes
+ Struct string // name of the struct type containing the field
+ Field string // the full path from root node to the field
+}
+
+func (e *UnmarshalTypeError) Error() string {
+ if e.Struct != "" || e.Field != "" {
+ return fmt.Sprintf("json: cannot unmarshal %s into Go struct field %s.%s of type %s",
+ e.Value, e.Struct, e.Field, e.Type,
+ )
+ }
+ return fmt.Sprintf("json: cannot unmarshal %s into Go value of type %s", e.Value, e.Type)
+}
+
+// An UnsupportedTypeError is returned by Marshal when attempting
+// to encode an unsupported value type.
+type UnsupportedTypeError struct {
+ Type reflect.Type
+}
+
+func (e *UnsupportedTypeError) Error() string {
+ return fmt.Sprintf("json: unsupported type: %s", e.Type)
+}
+
+type UnsupportedValueError struct {
+ Value reflect.Value
+ Str string
+}
+
+func (e *UnsupportedValueError) Error() string {
+ return fmt.Sprintf("json: unsupported value: %s", e.Str)
+}
+
+func ErrSyntax(msg string, offset int64) *SyntaxError {
+ return &SyntaxError{msg: msg, Offset: offset}
+}
+
+func ErrMarshaler(typ reflect.Type, err error, msg string) *MarshalerError {
+ return &MarshalerError{
+ Type: typ,
+ Err: err,
+ sourceFunc: msg,
+ }
+}
+
+func ErrExceededMaxDepth(c byte, cursor int64) *SyntaxError {
+ return &SyntaxError{
+ msg: fmt.Sprintf(`invalid character "%c" exceeded max depth`, c),
+ Offset: cursor,
+ }
+}
+
+func ErrNotAtBeginningOfValue(cursor int64) *SyntaxError {
+ return &SyntaxError{msg: "not at beginning of value", Offset: cursor}
+}
+
+func ErrUnexpectedEndOfJSON(msg string, cursor int64) *SyntaxError {
+ return &SyntaxError{
+ msg: fmt.Sprintf("json: %s unexpected end of JSON input", msg),
+ Offset: cursor,
+ }
+}
+
+func ErrExpected(msg string, cursor int64) *SyntaxError {
+ return &SyntaxError{msg: fmt.Sprintf("expected %s", msg), Offset: cursor}
+}
+
+func ErrInvalidCharacter(c byte, context string, cursor int64) *SyntaxError {
+ if c == 0 {
+ return &SyntaxError{
+ msg: fmt.Sprintf("json: invalid character as %s", context),
+ Offset: cursor,
+ }
+ }
+ return &SyntaxError{
+ msg: fmt.Sprintf("json: invalid character %c as %s", c, context),
+ Offset: cursor,
+ }
+}
+
+func ErrInvalidBeginningOfValue(c byte, cursor int64) *SyntaxError {
+ return &SyntaxError{
+ msg: fmt.Sprintf("invalid character '%c' looking for beginning of value", c),
+ Offset: cursor,
+ }
+}
+
+type PathError struct {
+ msg string
+}
+
+func (e *PathError) Error() string {
+ return fmt.Sprintf("json: invalid path format: %s", e.msg)
+}
+
+func ErrInvalidPath(msg string, args ...interface{}) *PathError {
+ if len(args) != 0 {
+ return &PathError{msg: fmt.Sprintf(msg, args...)}
+ }
+ return &PathError{msg: msg}
+}
+
+func ErrEmptyPath() *PathError {
+ return &PathError{msg: "path is empty"}
+}
diff --git a/vendor/github.com/goccy/go-json/internal/runtime/rtype.go b/vendor/github.com/goccy/go-json/internal/runtime/rtype.go
new file mode 100644
index 00000000..37cfe35a
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/runtime/rtype.go
@@ -0,0 +1,262 @@
+package runtime
+
+import (
+ "reflect"
+ "unsafe"
+)
+
+// Type representing reflect.rtype for noescape trick
+type Type struct{}
+
+//go:linkname rtype_Align reflect.(*rtype).Align
+//go:noescape
+func rtype_Align(*Type) int
+
+func (t *Type) Align() int {
+ return rtype_Align(t)
+}
+
+//go:linkname rtype_FieldAlign reflect.(*rtype).FieldAlign
+//go:noescape
+func rtype_FieldAlign(*Type) int
+
+func (t *Type) FieldAlign() int {
+ return rtype_FieldAlign(t)
+}
+
+//go:linkname rtype_Method reflect.(*rtype).Method
+//go:noescape
+func rtype_Method(*Type, int) reflect.Method
+
+func (t *Type) Method(a0 int) reflect.Method {
+ return rtype_Method(t, a0)
+}
+
+//go:linkname rtype_MethodByName reflect.(*rtype).MethodByName
+//go:noescape
+func rtype_MethodByName(*Type, string) (reflect.Method, bool)
+
+func (t *Type) MethodByName(a0 string) (reflect.Method, bool) {
+ return rtype_MethodByName(t, a0)
+}
+
+//go:linkname rtype_NumMethod reflect.(*rtype).NumMethod
+//go:noescape
+func rtype_NumMethod(*Type) int
+
+func (t *Type) NumMethod() int {
+ return rtype_NumMethod(t)
+}
+
+//go:linkname rtype_Name reflect.(*rtype).Name
+//go:noescape
+func rtype_Name(*Type) string
+
+func (t *Type) Name() string {
+ return rtype_Name(t)
+}
+
+//go:linkname rtype_PkgPath reflect.(*rtype).PkgPath
+//go:noescape
+func rtype_PkgPath(*Type) string
+
+func (t *Type) PkgPath() string {
+ return rtype_PkgPath(t)
+}
+
+//go:linkname rtype_Size reflect.(*rtype).Size
+//go:noescape
+func rtype_Size(*Type) uintptr
+
+func (t *Type) Size() uintptr {
+ return rtype_Size(t)
+}
+
+//go:linkname rtype_String reflect.(*rtype).String
+//go:noescape
+func rtype_String(*Type) string
+
+func (t *Type) String() string {
+ return rtype_String(t)
+}
+
+//go:linkname rtype_Kind reflect.(*rtype).Kind
+//go:noescape
+func rtype_Kind(*Type) reflect.Kind
+
+func (t *Type) Kind() reflect.Kind {
+ return rtype_Kind(t)
+}
+
+//go:linkname rtype_Implements reflect.(*rtype).Implements
+//go:noescape
+func rtype_Implements(*Type, reflect.Type) bool
+
+func (t *Type) Implements(u reflect.Type) bool {
+ return rtype_Implements(t, u)
+}
+
+//go:linkname rtype_AssignableTo reflect.(*rtype).AssignableTo
+//go:noescape
+func rtype_AssignableTo(*Type, reflect.Type) bool
+
+func (t *Type) AssignableTo(u reflect.Type) bool {
+ return rtype_AssignableTo(t, u)
+}
+
+//go:linkname rtype_ConvertibleTo reflect.(*rtype).ConvertibleTo
+//go:noescape
+func rtype_ConvertibleTo(*Type, reflect.Type) bool
+
+func (t *Type) ConvertibleTo(u reflect.Type) bool {
+ return rtype_ConvertibleTo(t, u)
+}
+
+//go:linkname rtype_Comparable reflect.(*rtype).Comparable
+//go:noescape
+func rtype_Comparable(*Type) bool
+
+func (t *Type) Comparable() bool {
+ return rtype_Comparable(t)
+}
+
+//go:linkname rtype_Bits reflect.(*rtype).Bits
+//go:noescape
+func rtype_Bits(*Type) int
+
+func (t *Type) Bits() int {
+ return rtype_Bits(t)
+}
+
+//go:linkname rtype_ChanDir reflect.(*rtype).ChanDir
+//go:noescape
+func rtype_ChanDir(*Type) reflect.ChanDir
+
+func (t *Type) ChanDir() reflect.ChanDir {
+ return rtype_ChanDir(t)
+}
+
+//go:linkname rtype_IsVariadic reflect.(*rtype).IsVariadic
+//go:noescape
+func rtype_IsVariadic(*Type) bool
+
+func (t *Type) IsVariadic() bool {
+ return rtype_IsVariadic(t)
+}
+
+//go:linkname rtype_Elem reflect.(*rtype).Elem
+//go:noescape
+func rtype_Elem(*Type) reflect.Type
+
+func (t *Type) Elem() *Type {
+ return Type2RType(rtype_Elem(t))
+}
+
+//go:linkname rtype_Field reflect.(*rtype).Field
+//go:noescape
+func rtype_Field(*Type, int) reflect.StructField
+
+func (t *Type) Field(i int) reflect.StructField {
+ return rtype_Field(t, i)
+}
+
+//go:linkname rtype_FieldByIndex reflect.(*rtype).FieldByIndex
+//go:noescape
+func rtype_FieldByIndex(*Type, []int) reflect.StructField
+
+func (t *Type) FieldByIndex(index []int) reflect.StructField {
+ return rtype_FieldByIndex(t, index)
+}
+
+//go:linkname rtype_FieldByName reflect.(*rtype).FieldByName
+//go:noescape
+func rtype_FieldByName(*Type, string) (reflect.StructField, bool)
+
+func (t *Type) FieldByName(name string) (reflect.StructField, bool) {
+ return rtype_FieldByName(t, name)
+}
+
+//go:linkname rtype_FieldByNameFunc reflect.(*rtype).FieldByNameFunc
+//go:noescape
+func rtype_FieldByNameFunc(*Type, func(string) bool) (reflect.StructField, bool)
+
+func (t *Type) FieldByNameFunc(match func(string) bool) (reflect.StructField, bool) {
+ return rtype_FieldByNameFunc(t, match)
+}
+
+//go:linkname rtype_In reflect.(*rtype).In
+//go:noescape
+func rtype_In(*Type, int) reflect.Type
+
+func (t *Type) In(i int) reflect.Type {
+ return rtype_In(t, i)
+}
+
+//go:linkname rtype_Key reflect.(*rtype).Key
+//go:noescape
+func rtype_Key(*Type) reflect.Type
+
+func (t *Type) Key() *Type {
+ return Type2RType(rtype_Key(t))
+}
+
+//go:linkname rtype_Len reflect.(*rtype).Len
+//go:noescape
+func rtype_Len(*Type) int
+
+func (t *Type) Len() int {
+ return rtype_Len(t)
+}
+
+//go:linkname rtype_NumField reflect.(*rtype).NumField
+//go:noescape
+func rtype_NumField(*Type) int
+
+func (t *Type) NumField() int {
+ return rtype_NumField(t)
+}
+
+//go:linkname rtype_NumIn reflect.(*rtype).NumIn
+//go:noescape
+func rtype_NumIn(*Type) int
+
+func (t *Type) NumIn() int {
+ return rtype_NumIn(t)
+}
+
+//go:linkname rtype_NumOut reflect.(*rtype).NumOut
+//go:noescape
+func rtype_NumOut(*Type) int
+
+func (t *Type) NumOut() int {
+ return rtype_NumOut(t)
+}
+
+//go:linkname rtype_Out reflect.(*rtype).Out
+//go:noescape
+func rtype_Out(*Type, int) reflect.Type
+
+//go:linkname PtrTo reflect.(*rtype).ptrTo
+//go:noescape
+func PtrTo(*Type) *Type
+
+func (t *Type) Out(i int) reflect.Type {
+ return rtype_Out(t, i)
+}
+
+//go:linkname IfaceIndir reflect.ifaceIndir
+//go:noescape
+func IfaceIndir(*Type) bool
+
+//go:linkname RType2Type reflect.toType
+//go:noescape
+func RType2Type(t *Type) reflect.Type
+
+type emptyInterface struct {
+ _ *Type
+ ptr unsafe.Pointer
+}
+
+func Type2RType(t reflect.Type) *Type {
+ return (*Type)(((*emptyInterface)(unsafe.Pointer(&t))).ptr)
+}
diff --git a/vendor/github.com/goccy/go-json/internal/runtime/struct_field.go b/vendor/github.com/goccy/go-json/internal/runtime/struct_field.go
new file mode 100644
index 00000000..baab0c59
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/runtime/struct_field.go
@@ -0,0 +1,91 @@
+package runtime
+
+import (
+ "reflect"
+ "strings"
+ "unicode"
+)
+
+func getTag(field reflect.StructField) string {
+ return field.Tag.Get("json")
+}
+
+func IsIgnoredStructField(field reflect.StructField) bool {
+ if field.PkgPath != "" {
+ if field.Anonymous {
+ t := field.Type
+ if t.Kind() == reflect.Ptr {
+ t = t.Elem()
+ }
+ if t.Kind() != reflect.Struct {
+ return true
+ }
+ } else {
+ // private field
+ return true
+ }
+ }
+ tag := getTag(field)
+ return tag == "-"
+}
+
+type StructTag struct {
+ Key string
+ IsTaggedKey bool
+ IsOmitEmpty bool
+ IsString bool
+ Field reflect.StructField
+}
+
+type StructTags []*StructTag
+
+func (t StructTags) ExistsKey(key string) bool {
+ for _, tt := range t {
+ if tt.Key == key {
+ return true
+ }
+ }
+ return false
+}
+
+func isValidTag(s string) bool {
+ if s == "" {
+ return false
+ }
+ for _, c := range s {
+ switch {
+ case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
+ // Backslash and quote chars are reserved, but
+ // otherwise any punctuation chars are allowed
+ // in a tag name.
+ case !unicode.IsLetter(c) && !unicode.IsDigit(c):
+ return false
+ }
+ }
+ return true
+}
+
+func StructTagFromField(field reflect.StructField) *StructTag {
+ keyName := field.Name
+ tag := getTag(field)
+ st := &StructTag{Field: field}
+ opts := strings.Split(tag, ",")
+ if len(opts) > 0 {
+ if opts[0] != "" && isValidTag(opts[0]) {
+ keyName = opts[0]
+ st.IsTaggedKey = true
+ }
+ }
+ st.Key = keyName
+ if len(opts) > 1 {
+ for _, opt := range opts[1:] {
+ switch opt {
+ case "omitempty":
+ st.IsOmitEmpty = true
+ case "string":
+ st.IsString = true
+ }
+ }
+ }
+ return st
+}
diff --git a/vendor/github.com/goccy/go-json/internal/runtime/type.go b/vendor/github.com/goccy/go-json/internal/runtime/type.go
new file mode 100644
index 00000000..0167cd2c
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/internal/runtime/type.go
@@ -0,0 +1,100 @@
+package runtime
+
+import (
+ "reflect"
+ "unsafe"
+)
+
+type SliceHeader struct {
+ Data unsafe.Pointer
+ Len int
+ Cap int
+}
+
+const (
+ maxAcceptableTypeAddrRange = 1024 * 1024 * 2 // 2 Mib
+)
+
+type TypeAddr struct {
+ BaseTypeAddr uintptr
+ MaxTypeAddr uintptr
+ AddrRange uintptr
+ AddrShift uintptr
+}
+
+var (
+ typeAddr *TypeAddr
+ alreadyAnalyzed bool
+)
+
+//go:linkname typelinks reflect.typelinks
+func typelinks() ([]unsafe.Pointer, [][]int32)
+
+//go:linkname rtypeOff reflect.rtypeOff
+func rtypeOff(unsafe.Pointer, int32) unsafe.Pointer
+
+func AnalyzeTypeAddr() *TypeAddr {
+ defer func() {
+ alreadyAnalyzed = true
+ }()
+ if alreadyAnalyzed {
+ return typeAddr
+ }
+ sections, offsets := typelinks()
+ if len(sections) != 1 {
+ return nil
+ }
+ if len(offsets) != 1 {
+ return nil
+ }
+ section := sections[0]
+ offset := offsets[0]
+ var (
+ min uintptr = uintptr(^uint(0))
+ max uintptr = 0
+ isAligned64 = true
+ isAligned32 = true
+ )
+ for i := 0; i < len(offset); i++ {
+ typ := (*Type)(rtypeOff(section, offset[i]))
+ addr := uintptr(unsafe.Pointer(typ))
+ if min > addr {
+ min = addr
+ }
+ if max < addr {
+ max = addr
+ }
+ if typ.Kind() == reflect.Ptr {
+ addr = uintptr(unsafe.Pointer(typ.Elem()))
+ if min > addr {
+ min = addr
+ }
+ if max < addr {
+ max = addr
+ }
+ }
+ isAligned64 = isAligned64 && (addr-min)&63 == 0
+ isAligned32 = isAligned32 && (addr-min)&31 == 0
+ }
+ addrRange := max - min
+ if addrRange == 0 {
+ return nil
+ }
+ var addrShift uintptr
+ if isAligned64 {
+ addrShift = 6
+ } else if isAligned32 {
+ addrShift = 5
+ }
+ cacheSize := addrRange >> addrShift
+ if cacheSize > maxAcceptableTypeAddrRange {
+ return nil
+ }
+ typeAddr = &TypeAddr{
+ BaseTypeAddr: min,
+ MaxTypeAddr: max,
+ AddrRange: addrRange,
+ AddrShift: addrShift,
+ }
+ return typeAddr
+}
diff --git a/vendor/github.com/goccy/go-json/json.go b/vendor/github.com/goccy/go-json/json.go
new file mode 100644
index 00000000..fb18065a
--- /dev/null
+++ b/vendor/github.com/goccy/go-json/json.go
@@ -0,0 +1,368 @@
+package json
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+
+ "github.com/goccy/go-json/internal/encoder"
+)
+
+// Marshaler is the interface implemented by types that
+// can marshal themselves into valid JSON.
+type Marshaler interface {
+ MarshalJSON() ([]byte, error)
+}
+
+// MarshalerContext is the interface implemented by types that
+// can marshal themselves into valid JSON with context.Context.
+type MarshalerContext interface {
+ MarshalJSON(context.Context) ([]byte, error)
+}
+
+// Unmarshaler is the interface implemented by types
+// that can unmarshal a JSON description of themselves.
+// The input can be assumed to be a valid encoding of
+// a JSON value. UnmarshalJSON must copy the JSON data
+// if it wishes to retain the data after returning.
+//
+// By convention, to approximate the behavior of Unmarshal itself,
+// Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op.
+type Unmarshaler interface {
+ UnmarshalJSON([]byte) error
+}
+
+// UnmarshalerContext is the interface implemented by types
+// that can unmarshal with context.Context a JSON description of themselves.
+type UnmarshalerContext interface {
+ UnmarshalJSON(context.Context, []byte) error
+}
+
+// Marshal returns the JSON encoding of v.
+//
+// Marshal traverses the value v recursively.
+// If an encountered value implements the Marshaler interface
+// and is not a nil pointer, Marshal calls its MarshalJSON method
+// to produce JSON. If no MarshalJSON method is present but the
+// value implements encoding.TextMarshaler instead, Marshal calls
+// its MarshalText method and encodes the result as a JSON string.
+// The nil pointer exception is not strictly necessary
+// but mimics a similar, necessary exception in the behavior of
+// UnmarshalJSON.
+//
+// Otherwise, Marshal uses the following type-dependent default encodings:
+//
+// Boolean values encode as JSON booleans.
+//
+// Floating point, integer, and Number values encode as JSON numbers.
+//
+// String values encode as JSON strings coerced to valid UTF-8,
+// replacing invalid bytes with the Unicode replacement rune.
+// The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e"
+// to keep some browsers from misinterpreting JSON output as HTML.
+// Ampersand "&" is also escaped to "\u0026" for the same reason.
+// This escaping can be disabled using an Encoder that had SetEscapeHTML(false)
+// called on it.
+//
+// Array and slice values encode as JSON arrays, except that
+// []byte encodes as a base64-encoded string, and a nil slice
+// encodes as the null JSON value.
+//
+// Struct values encode as JSON objects.
+// Each exported struct field becomes a member of the object, using the
+// field name as the object key, unless the field is omitted for one of the
+// reasons given below.
+//
+// The encoding of each struct field can be customized by the format string
+// stored under the "json" key in the struct field's tag.
+// The format string gives the name of the field, possibly followed by a
+// comma-separated list of options. The name may be empty in order to
+// specify options without overriding the default field name.
+//
+// The "omitempty" option specifies that the field should be omitted
+// from the encoding if the field has an empty value, defined as
+// false, 0, a nil pointer, a nil interface value, and any empty array,
+// slice, map, or string.
+//
+// As a special case, if the field tag is "-", the field is always omitted.
+// Note that a field with name "-" can still be generated using the tag "-,".
+//
+// Examples of struct field tags and their meanings:
+//
+// // Field appears in JSON as key "myName".
+// Field int `json:"myName"`
+//
+// // Field appears in JSON as key "myName" and
+// // the field is omitted from the object if its value is empty,
+// // as defined above.
+// Field int `json:"myName,omitempty"`
+//
+// // Field appears in JSON as key "Field" (the default), but
+// // the field is skipped if empty.
+// // Note the leading comma.
+// Field int `json:",omitempty"`
+//
+// // Field is ignored by this package.
+// Field int `json:"-"`
+//
+// // Field appears in JSON as key "-".
+// Field int `json:"-,"`
+//
+// The "string" option signals that a field is stored as JSON inside a
+// JSON-encoded string. It applies only to fields of string, floating point,
+// integer, or boolean types. This extra level of encoding is sometimes used
+// when communicating with JavaScript programs:
+//
+// Int64String int64 `json:",string"`
+//
+// The key name will be used if it's a non-empty string consisting of
+// only Unicode letters, digits, and ASCII punctuation except quotation
+// marks, backslash, and comma.
+//
+// Anonymous struct fields are usually marshaled as if their inner exported fields
+// were fields in the outer struct, subject to the usual Go visibility rules amended
+// as described in the next paragraph.
+// An anonymous struct field with a name given in its JSON tag is treated as
+// having that name, rather than being anonymous.
+// An anonymous struct field of interface type is treated the same as having
+// that type as its name, rather than being anonymous.
+//
+// The Go visibility rules for struct fields are amended for JSON when
+// deciding which field to marshal or unmarshal. If there are
+// multiple fields at the same level, and that level is the least
+// nested (and would therefore be the nesting level selected by the
+// usual Go rules), the following extra rules apply:
+//
+// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered,
+// even if there are multiple untagged fields that would otherwise conflict.
+//
+// 2) If there is exactly one field (tagged or not according to the first rule), that is selected.
+//
+// 3) Otherwise there are multiple fields, and all are ignored; no error occurs.
+//
+// Handling of anonymous struct fields is new in Go 1.1.
+// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of
+// an anonymous struct field in both current and earlier versions, give the field
+// a JSON tag of "-".
+//
+// Map values encode as JSON objects. The map's key type must either be a
+// string, an integer type, or implement encoding.TextMarshaler. The map keys
+// are sorted and used as JSON object keys by applying the following rules,
+// subject to the UTF-8 coercion described for string values above:
+// - string keys are used directly
+// - encoding.TextMarshalers are marshaled
+// - integer keys are converted to strings
+//
+// Pointer values encode as the value pointed to.
+// A nil pointer encodes as the null JSON value.
+//
+// Interface values encode as the value contained in the interface.
+// A nil interface value encodes as the null JSON value.
+//
+// Channel, complex, and function values cannot be encoded in JSON.
+// Attempting to encode such a value causes Marshal to return
+// an UnsupportedTypeError.
+//
+// JSON cannot represent cyclic data structures and Marshal does not
+// handle them. Passing cyclic structures to Marshal will result in
+// an infinite recursion.
+func Marshal(v interface{}) ([]byte, error) {
+ return MarshalWithOption(v)
+}
+
+// MarshalNoEscape returns the JSON encoding of v and doesn't escape v.
+func MarshalNoEscape(v interface{}) ([]byte, error) {
+ return marshalNoEscape(v)
+}
+
+// MarshalContext returns the JSON encoding of v with context.Context and EncodeOption.
+func MarshalContext(ctx context.Context, v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) {
+ return marshalContext(ctx, v, optFuncs...)
+}
+
+// MarshalWithOption returns the JSON encoding of v with EncodeOption.
+func MarshalWithOption(v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) {
+ return marshal(v, optFuncs...)
+}
+
+// MarshalIndent is like Marshal but applies Indent to format the output.
+// Each JSON element in the output will begin on a new line beginning with prefix
+// followed by one or more copies of indent according to the indentation nesting.
+func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
+ return MarshalIndentWithOption(v, prefix, indent)
+}
+
+// MarshalIndentWithOption is like Marshal but applies Indent to format the output with EncodeOption.
+func MarshalIndentWithOption(v interface{}, prefix, indent string, optFuncs ...EncodeOptionFunc) ([]byte, error) {
+ return marshalIndent(v, prefix, indent, optFuncs...)
+}
+
+// Unmarshal parses the JSON-encoded data and stores the result
+// in the value pointed to by v. If v is nil or not a pointer,
+// Unmarshal returns an InvalidUnmarshalError.
+//
+// Unmarshal uses the inverse of the encodings that
+// Marshal uses, allocating maps, slices, and pointers as necessary,
+// with the following additional rules:
+//
+// To unmarshal JSON into a pointer, Unmarshal first handles the case of
+// the JSON being the JSON literal null. In that case, Unmarshal sets
+// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into
+// the value pointed at by the pointer. If the pointer is nil, Unmarshal
+// allocates a new value for it to point to.
+//
+// To unmarshal JSON into a value implementing the Unmarshaler interface,
+// Unmarshal calls that value's UnmarshalJSON method, including
+// when the input is a JSON null.
+// Otherwise, if the value implements encoding.TextUnmarshaler
+// and the input is a JSON quoted string, Unmarshal calls that value's
+// UnmarshalText method with the unquoted form of the string.
+//
+// To unmarshal JSON into a struct, Unmarshal matches incoming object
+// keys to the keys used by Marshal (either the struct field name or its tag),
+// preferring an exact match but also accepting a case-insensitive match. By
+// default, object keys which don't have a corresponding struct field are
+// ignored (see Decoder.DisallowUnknownFields for an alternative).
+//
+// To unmarshal JSON into an interface value,
+// Unmarshal stores one of these in the interface value:
+//
+// bool, for JSON booleans
+// float64, for JSON numbers
+// string, for JSON strings
+// []interface{}, for JSON arrays
+// map[string]interface{}, for JSON objects
+// nil for JSON null
+//
+// To unmarshal a JSON array into a slice, Unmarshal resets the slice length
+// to zero and then appends each element to the slice.
+// As a special case, to unmarshal an empty JSON array into a slice,
+// Unmarshal replaces the slice with a new empty slice.
+//
+// To unmarshal a JSON array into a Go array, Unmarshal decodes
+// JSON array elements into corresponding Go array elements.
+// If the Go array is smaller than the JSON array,
+// the additional JSON array elements are discarded.
+// If the JSON array is smaller than the Go array,
+// the additional Go array elements are set to zero values.
+//
+// To unmarshal a JSON object into a map, Unmarshal first establishes a map to
+// use. If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal
+// reuses the existing map, keeping existing entries. Unmarshal then stores
+// key-value pairs from the JSON object into the map. The map's key type must
+// either be any string type, an integer, implement json.Unmarshaler, or
+// implement encoding.TextUnmarshaler.
+//
+// If a JSON value is not appropriate for a given target type,
+// or if a JSON number overflows the target type, Unmarshal
+// skips that field and completes the unmarshaling as best it can.
+// If no more serious errors are encountered, Unmarshal returns
+// an UnmarshalTypeError describing the earliest such error. In any
+// case, it's not guaranteed that all the remaining fields following
+// the problematic one will be unmarshaled into the target object.
+//
+// The JSON null value unmarshals into an interface, map, pointer, or slice
+// by setting that Go value to nil. Because null is often used in JSON to mean
+// “not present,” unmarshaling a JSON null into any other Go type has no effect
+// on the value and produces no error.
+//
+// When unmarshaling quoted strings, invalid UTF-8 or
+// invalid UTF-16 surrogate pairs are not treated as an error.
+// Instead, they are replaced by the Unicode replacement
+// character U+FFFD.
+func Unmarshal(data []byte, v interface{}) error {
+ return unmarshal(data, v)
+}
+
+// UnmarshalContext parses the JSON-encoded data and stores the result
+// in the value pointed to by v. If you implement the UnmarshalerContext interface,
+// call it with ctx as an argument.
+func UnmarshalContext(ctx context.Context, data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
+ return unmarshalContext(ctx, data, v)
+}
+
+func UnmarshalWithOption(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
+ return unmarshal(data, v, optFuncs...)
+}
+
+func UnmarshalNoEscape(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error {
+ return unmarshalNoEscape(data, v, optFuncs...)
+}
+
+// A Token holds a value of one of these types:
+//
+// Delim, for the four JSON delimiters [ ] { }
+// bool, for JSON booleans
+// float64, for JSON numbers
+// Number, for JSON numbers
+// string, for JSON string literals
+// nil, for JSON null
+type Token = json.Token
+
+// A Number represents a JSON number literal.
+type Number = json.Number
+
+// RawMessage is a raw encoded JSON value.
+// It implements Marshaler and Unmarshaler and can
+// be used to delay JSON decoding or precompute a JSON encoding.
+type RawMessage = json.RawMessage
+
+// A Delim is a JSON array or object delimiter, one of [ ] { or }.
+type Delim = json.Delim
+
+// Compact appends to dst the JSON-encoded src with
+// insignificant space characters elided.
+func Compact(dst *bytes.Buffer, src []byte) error {
+ return encoder.Compact(dst, src, false)
+}
+
+// Indent appends to dst an indented form of the JSON-encoded src.
+// Each element in a JSON object or array begins on a new,
+// indented line beginning with prefix followed by one or more
+// copies of indent according to the indentation nesting.
+// The data appended to dst does not begin with the prefix nor
+// any indentation, to make it easier to embed inside other formatted JSON data.
+// Although leading space characters (space, tab, carriage return, newline)
+// at the beginning of src are dropped, trailing space characters
+// at the end of src are preserved and copied to dst.
+// For example, if src has no trailing spaces, neither will dst;
+// if src ends in a trailing newline, so will dst.
+func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
+ return encoder.Indent(dst, src, prefix, indent)
+}
+
+// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
+// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029
+// so that the JSON will be safe to embed inside HTML