mirror of https://github.com/status-im/consul.git
Net-2712/resource hcl parsing (#18250)
* Initial protohcl implementation Co-authored-by: Matt Keeler <mkeeler@users.noreply.github.com> Co-authored-by: Daniel Upton <daniel@floppy.co> * resourcehcl: implement resource decoding on top of protohcl Co-authored-by: Daniel Upton <daniel@floppy.co> * fix: resolve ci failures * test: add additional unmarshalling tests * refactor: update function test to clean protohcl package imports --------- Co-authored-by: Matt Keeler <mkeeler@users.noreply.github.com> Co-authored-by: Daniel Upton <daniel@floppy.co>
This commit is contained in:
parent
4a0afb5d13
commit
559c61e6b6
6
go.mod
6
go.mod
|
@ -61,6 +61,7 @@ require (
|
||||||
github.com/hashicorp/go-version v1.2.1
|
github.com/hashicorp/go-version v1.2.1
|
||||||
github.com/hashicorp/golang-lru v0.5.4
|
github.com/hashicorp/golang-lru v0.5.4
|
||||||
github.com/hashicorp/hcl v1.0.0
|
github.com/hashicorp/hcl v1.0.0
|
||||||
|
github.com/hashicorp/hcl/v2 v2.6.0
|
||||||
github.com/hashicorp/hcp-scada-provider v0.2.3
|
github.com/hashicorp/hcp-scada-provider v0.2.3
|
||||||
github.com/hashicorp/hcp-sdk-go v0.55.0
|
github.com/hashicorp/hcp-sdk-go v0.55.0
|
||||||
github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038
|
github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038
|
||||||
|
@ -96,6 +97,7 @@ require (
|
||||||
github.com/ryanuber/columnize v2.1.2+incompatible
|
github.com/ryanuber/columnize v2.1.2+incompatible
|
||||||
github.com/shirou/gopsutil/v3 v3.22.8
|
github.com/shirou/gopsutil/v3 v3.22.8
|
||||||
github.com/stretchr/testify v1.8.3
|
github.com/stretchr/testify v1.8.3
|
||||||
|
github.com/zclconf/go-cty v1.2.0
|
||||||
go.etcd.io/bbolt v1.3.7
|
go.etcd.io/bbolt v1.3.7
|
||||||
go.opentelemetry.io/otel v1.16.0
|
go.opentelemetry.io/otel v1.16.0
|
||||||
go.opentelemetry.io/otel/metric v1.16.0
|
go.opentelemetry.io/otel/metric v1.16.0
|
||||||
|
@ -138,6 +140,9 @@ require (
|
||||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||||
github.com/DataDog/datadog-go v4.8.2+incompatible // indirect
|
github.com/DataDog/datadog-go v4.8.2+incompatible // indirect
|
||||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||||
|
github.com/agext/levenshtein v1.2.1 // indirect
|
||||||
|
github.com/apparentlymart/go-textseg v1.0.0 // indirect
|
||||||
|
github.com/apparentlymart/go-textseg/v12 v12.0.0 // indirect
|
||||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
|
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
|
||||||
github.com/benbjohnson/immutable v0.4.0 // indirect
|
github.com/benbjohnson/immutable v0.4.0 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
@ -207,6 +212,7 @@ require (
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
|
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
|
||||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
|
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
|
|
23
go.sum
23
go.sum
|
@ -111,6 +111,8 @@ github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdko
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14=
|
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14=
|
||||||
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw=
|
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw=
|
||||||
|
github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
|
||||||
|
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
|
@ -118,6 +120,11 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.62.156 h1:K4N91T1+RlSlx+t2dujeDviy4ehSGVjEltluDgmeHS4=
|
github.com/aliyun/alibaba-cloud-sdk-go v1.62.156 h1:K4N91T1+RlSlx+t2dujeDviy4ehSGVjEltluDgmeHS4=
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.62.156/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs=
|
github.com/aliyun/alibaba-cloud-sdk-go v1.62.156/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||||
|
github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
|
||||||
|
github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0=
|
||||||
|
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
|
||||||
|
github.com/apparentlymart/go-textseg/v12 v12.0.0 h1:bNEQyAGak9tojivJNkoqWErVCQbjdL7GzRt3F8NvfJ0=
|
||||||
|
github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
|
||||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA=
|
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA=
|
||||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||||
|
@ -312,6 +319,7 @@ github.com/go-ozzo/ozzo-validation v3.6.0+incompatible/go.mod h1:gsEKFIVnabGBt6m
|
||||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||||
|
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||||
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
|
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
|
||||||
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||||
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
|
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
|
||||||
|
@ -367,6 +375,7 @@ github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71
|
||||||
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
||||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
@ -552,6 +561,8 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l
|
||||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
|
github.com/hashicorp/hcl/v2 v2.6.0 h1:3krZOfGY6SziUXa6H9PJU6TyohHn7I+ARYnhbeNBz+o=
|
||||||
|
github.com/hashicorp/hcl/v2 v2.6.0/go.mod h1:bQTN5mpo+jewjJgh8jr0JUguIi7qPHUF6yIfAEN3jqY=
|
||||||
github.com/hashicorp/hcp-scada-provider v0.2.3 h1:AarYR+/Pcv+cMvPdAlb92uOBmZfEH6ny4+DT+4NY2VQ=
|
github.com/hashicorp/hcp-scada-provider v0.2.3 h1:AarYR+/Pcv+cMvPdAlb92uOBmZfEH6ny4+DT+4NY2VQ=
|
||||||
github.com/hashicorp/hcp-scada-provider v0.2.3/go.mod h1:ZFTgGwkzNv99PLQjTsulzaCplCzOTBh0IUQsPKzrQFo=
|
github.com/hashicorp/hcp-scada-provider v0.2.3/go.mod h1:ZFTgGwkzNv99PLQjTsulzaCplCzOTBh0IUQsPKzrQFo=
|
||||||
github.com/hashicorp/hcp-sdk-go v0.55.0 h1:T4sQtgQfQJOD0uucT4hS+GZI1FmoHAQMADj277W++xw=
|
github.com/hashicorp/hcp-sdk-go v0.55.0 h1:T4sQtgQfQJOD0uucT4hS+GZI1FmoHAQMADj277W++xw=
|
||||||
|
@ -653,6 +664,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4=
|
||||||
|
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
github.com/linode/linodego v0.7.1/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY=
|
github.com/linode/linodego v0.7.1/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY=
|
||||||
github.com/linode/linodego v0.10.0 h1:AMdb82HVgY8o3mjBXJcUv9B+fnJjfDMn2rNRGbX+jvM=
|
github.com/linode/linodego v0.10.0 h1:AMdb82HVgY8o3mjBXJcUv9B+fnJjfDMn2rNRGbX+jvM=
|
||||||
|
@ -710,6 +723,8 @@ github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.
|
||||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||||
github.com/mitchellh/go-testing-interface v1.14.0 h1:/x0XQ6h+3U3nAyk1yx+bHPURrKa9sVVvYbuqZ7pIAtI=
|
github.com/mitchellh/go-testing-interface v1.14.0 h1:/x0XQ6h+3U3nAyk1yx+bHPURrKa9sVVvYbuqZ7pIAtI=
|
||||||
github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
|
github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
|
||||||
|
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||||
|
github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
|
||||||
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||||
github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 h1:hOY53G+kBFhbYFpRVxHl5eS7laP6B1+Cq+Z9Dry1iMU=
|
github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 h1:hOY53G+kBFhbYFpRVxHl5eS7laP6B1+Cq+Z9Dry1iMU=
|
||||||
github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
|
github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
|
||||||
|
@ -847,6 +862,7 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUt
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM=
|
github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM=
|
||||||
github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY=
|
github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY=
|
||||||
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
github.com/shirou/gopsutil/v3 v3.22.8 h1:a4s3hXogo5mE2PfdfJIonDbstO/P+9JszdfhAHSzD9Y=
|
github.com/shirou/gopsutil/v3 v3.22.8 h1:a4s3hXogo5mE2PfdfJIonDbstO/P+9JszdfhAHSzD9Y=
|
||||||
github.com/shirou/gopsutil/v3 v3.22.8/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI=
|
github.com/shirou/gopsutil/v3 v3.22.8/go.mod h1:s648gW4IywYzUfE/KjXxUsqrqx/T2xO5VqOXxONeRfI=
|
||||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||||
|
@ -871,6 +887,7 @@ github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3
|
||||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
|
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
@ -912,6 +929,7 @@ github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVK
|
||||||
github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||||
|
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||||
github.com/vmware/govmomi v0.18.0 h1:f7QxSmP7meCtoAmiKZogvVbLInT+CZx6Px6K5rYsJZo=
|
github.com/vmware/govmomi v0.18.0 h1:f7QxSmP7meCtoAmiKZogvVbLInT+CZx6Px6K5rYsJZo=
|
||||||
github.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
|
github.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU=
|
||||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||||
|
@ -930,6 +948,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||||
|
github.com/zclconf/go-cty v1.2.0 h1:sPHsy7ADcIZQP3vILvTjrh74ZA175TFP5vqiNK1UmlI=
|
||||||
|
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
|
||||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||||
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
|
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
|
||||||
|
@ -974,6 +994,7 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf
|
||||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||||
|
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
|
@ -1035,6 +1056,7 @@ golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73r
|
||||||
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
@ -1137,6 +1159,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
package protohcl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
"google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
"google.golang.org/protobuf/reflect/protoregistry"
|
||||||
|
"google.golang.org/protobuf/types/known/anypb"
|
||||||
|
)
|
||||||
|
|
||||||
|
const wellKnownTypeAny = "google.protobuf.Any"
|
||||||
|
|
||||||
|
type AnyTypeProvider interface {
|
||||||
|
AnyType(*UnmarshalContext, MessageDecoder) (protoreflect.FullName, MessageDecoder, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type AnyTypeURLProvider struct {
|
||||||
|
TypeURLFieldName string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *AnyTypeURLProvider) AnyType(ctx *UnmarshalContext, decoder MessageDecoder) (protoreflect.FullName, MessageDecoder, error) {
|
||||||
|
typeURLFieldName := "type_url"
|
||||||
|
if p != nil {
|
||||||
|
typeURLFieldName = p.TypeURLFieldName
|
||||||
|
}
|
||||||
|
|
||||||
|
var typeURL *IterField
|
||||||
|
err := decoder.EachField(FieldIterator{
|
||||||
|
Desc: (&anypb.Any{}).ProtoReflect().Descriptor(),
|
||||||
|
Func: func(field *IterField) error {
|
||||||
|
if field.Name == typeURLFieldName {
|
||||||
|
typeURL = field
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
IgnoreUnknown: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if typeURL == nil || typeURL.Val == nil {
|
||||||
|
return "", nil, fmt.Errorf("%s field is required to decode Any", typeURLFieldName)
|
||||||
|
}
|
||||||
|
|
||||||
|
url, err := stringFromCty(*typeURL.Val)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
slashIdx := strings.LastIndex(url, "/")
|
||||||
|
typeName := url
|
||||||
|
// strip all "hostname" parts of the URL path
|
||||||
|
if slashIdx > 1 && slashIdx+1 < len(url) {
|
||||||
|
typeName = url[slashIdx+1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
return protoreflect.FullName(typeName), decoder.SkipFields(typeURLFieldName), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UnmarshalOptions) decodeAny(ctx *UnmarshalContext, decoder MessageDecoder, msg protoreflect.Message) error {
|
||||||
|
var typeProvider AnyTypeProvider = &AnyTypeURLProvider{TypeURLFieldName: "type_url"}
|
||||||
|
if u.AnyTypeProvider != nil {
|
||||||
|
typeProvider = u.AnyTypeProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
typeName protoreflect.FullName
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
typeName, decoder, err = typeProvider.AnyType(ctx, decoder)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error getting type for Any field: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// the type.googleapis.come/ should be optional
|
||||||
|
mt, err := protoregistry.GlobalTypes.FindMessageByName(typeName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error looking up type information for %s: %w", typeName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
newMsg := mt.New()
|
||||||
|
|
||||||
|
err = u.decodeMessage(&UnmarshalContext{
|
||||||
|
Parent: ctx.Parent,
|
||||||
|
Name: ctx.Name,
|
||||||
|
Message: newMsg,
|
||||||
|
}, decoder, newMsg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
enc, err := proto.Marshal(newMsg.Interface())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error marshalling Any data as protobuf value: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
anyValue := msg.Interface().(*anypb.Any)
|
||||||
|
|
||||||
|
// This will look like <proto package>.<proto Message name> and not quite like a full URL with a path
|
||||||
|
anyValue.TypeUrl = string(newMsg.Descriptor().FullName())
|
||||||
|
anyValue.Value = enc
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isAnyField(desc protoreflect.FieldDescriptor) bool {
|
||||||
|
if desc.Kind() != protoreflect.MessageKind {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return desc.Message().FullName() == wellKnownTypeAny
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
package protohcl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
"google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (u UnmarshalOptions) decodeAttribute(ctx *UnmarshalContext, newMessage newMessageFn, f protoreflect.FieldDescriptor, val cty.Value, listAllowed bool) (protoreflect.Value, error) {
|
||||||
|
if f.IsMap() {
|
||||||
|
return u.decodeAttributeToMap(ctx, newMessage, f, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.IsList() && listAllowed {
|
||||||
|
return u.decodeAttributeToList(ctx, newMessage, f, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
ok, value, err := decodeAttributeToWellKnownType(f, val)
|
||||||
|
if ok {
|
||||||
|
return value, errors.Wrapf(err, "%s: Failed to unmarshal argument %s", ctx.ErrorRange(), ctx.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
ok, value, err = u.decodeAttributeToMessage(ctx, newMessage, f, val)
|
||||||
|
if ok {
|
||||||
|
return value, err
|
||||||
|
}
|
||||||
|
|
||||||
|
value, err = decodeAttributeToPrimitive(f, val)
|
||||||
|
if err != nil {
|
||||||
|
return value, errors.Wrapf(err, "%s: Failed to unmarshal argument %s", ctx.ErrorRange(), ctx.Name)
|
||||||
|
}
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UnmarshalOptions) decodeAttributeToMessage(ctx *UnmarshalContext, newMessage newMessageFn, desc protoreflect.FieldDescriptor, val cty.Value) (bool, protoreflect.Value, error) {
|
||||||
|
if desc.Kind() != protoreflect.MessageKind {
|
||||||
|
return false, protoreflect.Value{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := newMessage().Message()
|
||||||
|
|
||||||
|
ctx = &UnmarshalContext{
|
||||||
|
Parent: ctx.Parent,
|
||||||
|
Name: ctx.Name,
|
||||||
|
Message: msg,
|
||||||
|
Range: ctx.Range,
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have limited support for HCL functions, essentially just those that
|
||||||
|
// return a protobuf message (like the resource `gvk` function) in which
|
||||||
|
// case, the message will be wrapped in a cty capsule.
|
||||||
|
if val.Type().IsCapsuleType() {
|
||||||
|
msg, ok := val.EncapsulatedValue().(proto.Message)
|
||||||
|
if ok {
|
||||||
|
return true, protoreflect.ValueOf(msg.ProtoReflect()), nil
|
||||||
|
} else {
|
||||||
|
return true, protoreflect.Value{}, fmt.Errorf("expected encapsulated value to be a message, actual type: %T", val.EncapsulatedValue())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !val.Type().IsObjectType() {
|
||||||
|
return false, protoreflect.Value{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
decoder := newObjectDecoder(val, u.FieldNamer, ctx.ErrorRange())
|
||||||
|
|
||||||
|
if err := u.decodeMessage(ctx, decoder, msg); err != nil {
|
||||||
|
return true, protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return true, protoreflect.ValueOf(msg), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UnmarshalOptions) decodeAttributeToList(ctx *UnmarshalContext, newMessage newMessageFn, desc protoreflect.FieldDescriptor, value cty.Value) (protoreflect.Value, error) {
|
||||||
|
if value.IsNull() {
|
||||||
|
return protoreflect.Value{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
valueType := value.Type()
|
||||||
|
if !valueType.IsListType() && !valueType.IsTupleType() {
|
||||||
|
return protoreflect.Value{}, fmt.Errorf("expected list/tuple type after HCL decode but the actual type was %s", valueType.FriendlyName())
|
||||||
|
}
|
||||||
|
|
||||||
|
if value.LengthInt() < 1 {
|
||||||
|
return protoreflect.Value{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
protoList := newMessage().List()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var idx int
|
||||||
|
value.ForEachElement(func(_ cty.Value, val cty.Value) bool {
|
||||||
|
var protoVal protoreflect.Value
|
||||||
|
protoVal, err = u.decodeAttribute(&UnmarshalContext{
|
||||||
|
Parent: ctx,
|
||||||
|
Name: fmt.Sprintf("%s[%d]", u.FieldNamer.NameField(desc), idx),
|
||||||
|
}, protoList.NewElement, desc, val, false)
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
idx++
|
||||||
|
protoList.Append(protoVal)
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return protoreflect.ValueOfList(protoList), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UnmarshalOptions) decodeAttributeToMap(ctx *UnmarshalContext, newMessage newMessageFn, desc protoreflect.FieldDescriptor, value cty.Value) (protoreflect.Value, error) {
|
||||||
|
if value.IsNull() {
|
||||||
|
return protoreflect.Value{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
valueType := value.Type()
|
||||||
|
if !valueType.IsMapType() && !valueType.IsObjectType() {
|
||||||
|
return protoreflect.Value{}, fmt.Errorf("expected map/object type after HCL decode but the actual type was %s", valueType.FriendlyName())
|
||||||
|
}
|
||||||
|
|
||||||
|
if value.LengthInt() < 1 {
|
||||||
|
return protoreflect.Value{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
protoMap := newMessage().Map()
|
||||||
|
protoValueDesc := desc.MapValue()
|
||||||
|
var err error
|
||||||
|
|
||||||
|
value.ForEachElement(func(key cty.Value, val cty.Value) (stop bool) {
|
||||||
|
var protoVal protoreflect.Value
|
||||||
|
protoVal, err = u.decodeAttribute(&UnmarshalContext{
|
||||||
|
Parent: ctx,
|
||||||
|
Name: fmt.Sprintf("%s[%q]", u.FieldNamer.NameField(desc), key.AsString()),
|
||||||
|
Message: nil, // TODO: what should this really be?
|
||||||
|
}, protoMap.NewValue, protoValueDesc, val, false)
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if protoVal.IsValid() {
|
||||||
|
// HCL doesn't support non-string keyed maps so we blindly use string keys
|
||||||
|
protoMap.Set(protoreflect.ValueOfString(key.AsString()).MapKey(), protoVal)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return protoreflect.ValueOfMap(protoMap), nil
|
||||||
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
package protohcl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/hashicorp/hcl/v2"
|
||||||
|
"google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (u UnmarshalOptions) decodeBlocks(ctx *UnmarshalContext, blocks hcl.Blocks, msg protoreflect.Message, f protoreflect.FieldDescriptor) (protoreflect.Value, error) {
|
||||||
|
if f.Kind() != protoreflect.MessageKind {
|
||||||
|
return protoreflect.Value{}, fmt.Errorf("only protobuf message kinds can use HCL block syntax")
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.IsMap() {
|
||||||
|
return u.decodeBlocksToMap(ctx, blocks, msg, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.IsList() {
|
||||||
|
return u.decodeBlocksToList(ctx, blocks, msg, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
return u.decodeBlocksToMessage(ctx, blocks, msg, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UnmarshalOptions) decodeBlocksToMap(ctx *UnmarshalContext, blocks hcl.Blocks, msg protoreflect.Message, f protoreflect.FieldDescriptor) (protoreflect.Value, error) {
|
||||||
|
val := msg.NewField(f)
|
||||||
|
mapVal := val.Map()
|
||||||
|
|
||||||
|
for _, block := range blocks {
|
||||||
|
if len(block.Labels) != 1 {
|
||||||
|
return protoreflect.Value{}, fmt.Errorf("protobuf map fields must have 1 HCL block label")
|
||||||
|
}
|
||||||
|
|
||||||
|
key := protoreflect.ValueOfString(block.Labels[0])
|
||||||
|
value := mapVal.NewValue()
|
||||||
|
msgVal := value.Message()
|
||||||
|
|
||||||
|
err := u.decodeMessage(
|
||||||
|
&UnmarshalContext{
|
||||||
|
Parent: ctx,
|
||||||
|
Name: fmt.Sprintf("%s[%q]", u.FieldNamer.NameField(f), block.Labels[0]),
|
||||||
|
Message: msgVal,
|
||||||
|
Range: block.DefRange,
|
||||||
|
},
|
||||||
|
u.bodyDecoder(block.Body),
|
||||||
|
msgVal,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mapVal.Set(key.MapKey(), value)
|
||||||
|
}
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UnmarshalOptions) decodeBlocksToList(ctx *UnmarshalContext, blocks hcl.Blocks, msg protoreflect.Message, f protoreflect.FieldDescriptor) (protoreflect.Value, error) {
|
||||||
|
val := msg.NewField(f)
|
||||||
|
listVal := val.List()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
for idx, block := range blocks {
|
||||||
|
if len(block.Labels) > 0 {
|
||||||
|
return protoreflect.Value{}, fmt.Errorf("repeated protobuf fields must not have HCL block labels")
|
||||||
|
}
|
||||||
|
elem := listVal.NewElement()
|
||||||
|
elemMsg := elem.Message()
|
||||||
|
|
||||||
|
err = u.decodeMessage(
|
||||||
|
&UnmarshalContext{
|
||||||
|
Parent: ctx,
|
||||||
|
Name: fmt.Sprintf("%s[%d]", u.FieldNamer.NameField(f), idx),
|
||||||
|
Message: elemMsg,
|
||||||
|
Range: block.DefRange,
|
||||||
|
},
|
||||||
|
u.bodyDecoder(block.Body),
|
||||||
|
elemMsg,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
listVal.Append(elem)
|
||||||
|
}
|
||||||
|
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UnmarshalOptions) decodeBlocksToMessage(ctx *UnmarshalContext, blocks hcl.Blocks, msg protoreflect.Message, f protoreflect.FieldDescriptor) (protoreflect.Value, error) {
|
||||||
|
if len(blocks) > 1 {
|
||||||
|
return protoreflect.Value{}, fmt.Errorf("only one HCL block may be specified for a non-repeated protobuf Message")
|
||||||
|
}
|
||||||
|
|
||||||
|
val := msg.NewField(f)
|
||||||
|
valMsg := val.Message()
|
||||||
|
|
||||||
|
err := u.decodeMessage(
|
||||||
|
&UnmarshalContext{
|
||||||
|
Parent: ctx,
|
||||||
|
Name: blocks[0].Type,
|
||||||
|
Message: valMsg,
|
||||||
|
Range: blocks[0].DefRange,
|
||||||
|
},
|
||||||
|
u.bodyDecoder(blocks[0].Body),
|
||||||
|
valMsg,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return val, nil
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
package protohcl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
"github.com/zclconf/go-cty/cty/gocty"
|
||||||
|
)
|
||||||
|
|
||||||
|
func boolFromCty(val cty.Value) (bool, error) {
|
||||||
|
if val.Type() != cty.Bool {
|
||||||
|
return false, fmt.Errorf("expected value of type %s but actual type is %s", cty.Bool.FriendlyName(), val.Type().FriendlyName())
|
||||||
|
}
|
||||||
|
|
||||||
|
if val.IsNull() {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return val.True(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func int32FromCty(val cty.Value) (int32, error) {
|
||||||
|
if val.Type() != cty.Number {
|
||||||
|
return 0, fmt.Errorf("expected value of type %s but actual type is %s", cty.Number.FriendlyName(), val.Type().FriendlyName())
|
||||||
|
}
|
||||||
|
|
||||||
|
if val.IsNull() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var goVal int32
|
||||||
|
if err := gocty.FromCtyValue(val, &goVal); err != nil {
|
||||||
|
return 0, fmt.Errorf("error converting cty value of type %s to int32: %w", val.Type().FriendlyName(), err)
|
||||||
|
}
|
||||||
|
return goVal, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func uint32FromCty(val cty.Value) (uint32, error) {
|
||||||
|
if val.Type() != cty.Number {
|
||||||
|
return 0, fmt.Errorf("expected value of type %s but actual type is %s", cty.Number.FriendlyName(), val.Type().FriendlyName())
|
||||||
|
}
|
||||||
|
|
||||||
|
if val.IsNull() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var goVal uint32
|
||||||
|
if err := gocty.FromCtyValue(val, &goVal); err != nil {
|
||||||
|
return 0, fmt.Errorf("error converting cty value of type %s to uint32: %w", val.Type().FriendlyName(), err)
|
||||||
|
}
|
||||||
|
return goVal, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func int64FromCty(val cty.Value) (int64, error) {
|
||||||
|
if val.Type() != cty.Number {
|
||||||
|
return 0, fmt.Errorf("expected value of type %s but actual type is %s", cty.Number.FriendlyName(), val.Type().FriendlyName())
|
||||||
|
}
|
||||||
|
|
||||||
|
if val.IsNull() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var goVal int64
|
||||||
|
if err := gocty.FromCtyValue(val, &goVal); err != nil {
|
||||||
|
return 0, fmt.Errorf("error converting cty value of type %s to int64: %w", val.Type().FriendlyName(), err)
|
||||||
|
}
|
||||||
|
return goVal, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func uint64FromCty(val cty.Value) (uint64, error) {
|
||||||
|
if val.Type() != cty.Number {
|
||||||
|
return 0, fmt.Errorf("expected value of type %s but actual type is %s", cty.Number.FriendlyName(), val.Type().FriendlyName())
|
||||||
|
}
|
||||||
|
|
||||||
|
if val.IsNull() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var goVal uint64
|
||||||
|
if err := gocty.FromCtyValue(val, &goVal); err != nil {
|
||||||
|
return 0, fmt.Errorf("error converting cty value of type %s to uint64: %w", val.Type().FriendlyName(), err)
|
||||||
|
}
|
||||||
|
return goVal, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func floatFromCty(val cty.Value) (float32, error) {
|
||||||
|
if val.Type() != cty.Number {
|
||||||
|
return 0, fmt.Errorf("expected value of type %s but actual type is %s", cty.Number.FriendlyName(), val.Type().FriendlyName())
|
||||||
|
}
|
||||||
|
|
||||||
|
if val.IsNull() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var goVal float32
|
||||||
|
if err := gocty.FromCtyValue(val, &goVal); err != nil {
|
||||||
|
return 0, fmt.Errorf("error converting cty value of type %s to float32: %w", val.Type().FriendlyName(), err)
|
||||||
|
}
|
||||||
|
return goVal, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func doubleFromCty(val cty.Value) (float64, error) {
|
||||||
|
if val.Type() != cty.Number {
|
||||||
|
return 0, fmt.Errorf("expected value of type %s but actual type is %s", cty.Number.FriendlyName(), val.Type().FriendlyName())
|
||||||
|
}
|
||||||
|
|
||||||
|
if val.IsNull() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var goVal float64
|
||||||
|
if err := gocty.FromCtyValue(val, &goVal); err != nil {
|
||||||
|
return 0, fmt.Errorf("error converting cty value of type %s to float64: %w", val.Type().FriendlyName(), err)
|
||||||
|
}
|
||||||
|
return goVal, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringFromCty(val cty.Value) (string, error) {
|
||||||
|
if val.Type() != cty.String {
|
||||||
|
return "", fmt.Errorf("expected value of type %s but actual type is %s", cty.String.FriendlyName(), val.Type().FriendlyName())
|
||||||
|
}
|
||||||
|
|
||||||
|
if val.IsNull() {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
return val.AsString(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func bytesFromCty(val cty.Value) ([]byte, error) {
|
||||||
|
if val.Type() != cty.String {
|
||||||
|
return nil, fmt.Errorf("expected value of type %s but actual type is %s", cty.String.FriendlyName(), val.Type().FriendlyName())
|
||||||
|
}
|
||||||
|
|
||||||
|
if val.IsNull() {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
encoded := val.AsString()
|
||||||
|
decoded, err := base64.StdEncoding.DecodeString(encoded)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error base64 decoding byte string: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return decoded, nil
|
||||||
|
}
|
|
@ -0,0 +1,284 @@
|
||||||
|
package protohcl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/hashicorp/hcl/v2"
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
"github.com/zclconf/go-cty/cty/function"
|
||||||
|
"google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MessageDecoder provides an abstract way to decode protobuf messages from HCL
|
||||||
|
// blocks or objects.
|
||||||
|
type MessageDecoder interface {
|
||||||
|
// EachField calls the given iterator for each field provided in the HCL source.
|
||||||
|
EachField(iter FieldIterator) error
|
||||||
|
|
||||||
|
// SkipFields returns a MessageDecoder that skips over the given fields. It is
|
||||||
|
// primarily used for doing two-pass decoding of protobuf `Any` fields.
|
||||||
|
SkipFields(fields ...string) MessageDecoder
|
||||||
|
}
|
||||||
|
|
||||||
|
// IterField represents a field discovered by the MessageDecoder.
|
||||||
|
type IterField struct {
|
||||||
|
// Name is the HCL name of the field.
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// Desc is the protobuf field descriptor.
|
||||||
|
Desc protoreflect.FieldDescriptor
|
||||||
|
|
||||||
|
// Val is the field value, only if it was given using HCL attribute syntax.
|
||||||
|
Val *cty.Value
|
||||||
|
|
||||||
|
// Blocks contains the HCL blocks that were given for this field.
|
||||||
|
Blocks []*hcl.Block
|
||||||
|
|
||||||
|
// Range determines where in the HCL source the field was given, it is useful
|
||||||
|
// for error messages.
|
||||||
|
Range hcl.Range
|
||||||
|
}
|
||||||
|
|
||||||
|
// FieldIterator is given to MessageDecoder.EachField to iterate over all of the
|
||||||
|
// fields in a given HCL block or object.
|
||||||
|
type FieldIterator struct {
|
||||||
|
// IgnoreUnknown instructs the MessageDecoder to skip over any fields not
|
||||||
|
// included in Desc.
|
||||||
|
IgnoreUnknown bool
|
||||||
|
|
||||||
|
// Desc is the protobuf descriptor for the message the caller is decoding into.
|
||||||
|
// It is used to determine which fields are valid.
|
||||||
|
Desc protoreflect.MessageDescriptor
|
||||||
|
|
||||||
|
// Func is called for each field in the given HCL block or object.
|
||||||
|
Func func(field *IterField) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func newBodyDecoder(
|
||||||
|
body hcl.Body,
|
||||||
|
namer FieldNamer,
|
||||||
|
functions map[string]function.Function,
|
||||||
|
) MessageDecoder {
|
||||||
|
return bodyDecoder{
|
||||||
|
body: body,
|
||||||
|
namer: namer,
|
||||||
|
functions: functions,
|
||||||
|
skipFields: make(map[string]struct{}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type bodyDecoder struct {
|
||||||
|
body hcl.Body
|
||||||
|
namer FieldNamer
|
||||||
|
functions map[string]function.Function
|
||||||
|
skipFields map[string]struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bd bodyDecoder) EachField(iter FieldIterator) error {
|
||||||
|
schema, err := bd.schema(iter.Desc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
content *hcl.BodyContent
|
||||||
|
diags hcl.Diagnostics
|
||||||
|
)
|
||||||
|
if iter.IgnoreUnknown {
|
||||||
|
content, _, diags = bd.body.PartialContent(schema)
|
||||||
|
} else {
|
||||||
|
content, diags = bd.body.Content(schema)
|
||||||
|
}
|
||||||
|
if diags.HasErrors() {
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
fields := make([]*IterField, 0)
|
||||||
|
|
||||||
|
for _, attr := range content.Attributes {
|
||||||
|
if _, ok := bd.skipFields[attr.Name]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
desc := bd.namer.GetField(iter.Desc.Fields(), attr.Name)
|
||||||
|
|
||||||
|
val, err := attr.Expr.Value(&hcl.EvalContext{Functions: bd.functions})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fields = append(fields, &IterField{
|
||||||
|
Name: attr.Name,
|
||||||
|
Desc: desc,
|
||||||
|
Val: &val,
|
||||||
|
Range: attr.Expr.Range(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for blockType, blocks := range content.Blocks.ByType() {
|
||||||
|
if _, ok := bd.skipFields[blockType]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
desc := bd.namer.GetField(iter.Desc.Fields(), blockType)
|
||||||
|
|
||||||
|
fields = append(fields, &IterField{
|
||||||
|
Name: blockType,
|
||||||
|
Desc: desc,
|
||||||
|
Blocks: blocks,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always handle Any fields last, as decoding them may require type information
|
||||||
|
// gathered from other fields (e.g. as in the case of Resource GVKs).
|
||||||
|
sort.Slice(fields, func(a, b int) bool {
|
||||||
|
if isAnyField(fields[b].Desc) && !isAnyField(fields[a].Desc) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return a < b
|
||||||
|
})
|
||||||
|
|
||||||
|
for _, field := range fields {
|
||||||
|
if err := iter.Func(field); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bd bodyDecoder) SkipFields(fields ...string) MessageDecoder {
|
||||||
|
skip := make(map[string]struct{}, len(fields)+len(bd.skipFields))
|
||||||
|
for k, v := range bd.skipFields {
|
||||||
|
skip[k] = v
|
||||||
|
}
|
||||||
|
for _, field := range fields {
|
||||||
|
skip[field] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: we rely on the fact bd isn't a pointer to copy the struct here.
|
||||||
|
bd.skipFields = skip
|
||||||
|
return bd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bd bodyDecoder) schema(desc protoreflect.MessageDescriptor) (*hcl.BodySchema, error) {
|
||||||
|
var schema hcl.BodySchema
|
||||||
|
|
||||||
|
fields := desc.Fields()
|
||||||
|
for i := 0; i < fields.Len(); i++ {
|
||||||
|
f := fields.Get(i)
|
||||||
|
|
||||||
|
kind := f.Kind()
|
||||||
|
// maps are special and whether they use block or attribute syntax depends
|
||||||
|
// on the value type
|
||||||
|
if f.IsMap() {
|
||||||
|
valueDesc := f.MapValue()
|
||||||
|
valueKind := valueDesc.Kind()
|
||||||
|
|
||||||
|
wktHint := wellKnownTypeSchemaHint(valueDesc)
|
||||||
|
|
||||||
|
// Message types should generally be encoded as blocks unless its a special Well Known Type
|
||||||
|
// that should use attribute encoding
|
||||||
|
if valueKind == protoreflect.MessageKind && wktHint != wellKnownAttribute {
|
||||||
|
schema.Blocks = append(schema.Blocks, hcl.BlockHeaderSchema{
|
||||||
|
Type: bd.namer.NameField(f),
|
||||||
|
LabelNames: []string{"key"},
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// non-message types or Well Known Message types that need attribute encoding
|
||||||
|
// get decoded as attributes
|
||||||
|
schema.Attributes = append(schema.Attributes, hcl.AttributeSchema{
|
||||||
|
Name: bd.namer.NameField(f),
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
wktHint := wellKnownTypeSchemaHint(f)
|
||||||
|
|
||||||
|
// message types generally will use block syntax unless its a well known
|
||||||
|
// message type that requires attribute syntax specifically.
|
||||||
|
if kind == protoreflect.MessageKind && wktHint != wellKnownAttribute {
|
||||||
|
schema.Blocks = append(schema.Blocks, hcl.BlockHeaderSchema{
|
||||||
|
Type: bd.namer.NameField(f),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// by default use attribute encoding
|
||||||
|
// - primitives
|
||||||
|
// - repeated primitives
|
||||||
|
// - Well Known Types requiring attribute syntax
|
||||||
|
// - repeated Well Known Types requiring attribute syntax
|
||||||
|
schema.Attributes = append(schema.Attributes, hcl.AttributeSchema{
|
||||||
|
Name: bd.namer.NameField(f),
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add skipped fields to the schema so HCL doesn't throw an error when it finds them.
|
||||||
|
for field := range bd.skipFields {
|
||||||
|
schema.Attributes = append(schema.Attributes, hcl.AttributeSchema{Name: field})
|
||||||
|
schema.Blocks = append(schema.Blocks, hcl.BlockHeaderSchema{Type: field})
|
||||||
|
}
|
||||||
|
|
||||||
|
return &schema, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newObjectDecoder(object cty.Value, namer FieldNamer, rng hcl.Range) MessageDecoder {
|
||||||
|
return objectDecoder{
|
||||||
|
object: object,
|
||||||
|
namer: namer,
|
||||||
|
rng: rng,
|
||||||
|
skipFields: make(map[string]struct{}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type objectDecoder struct {
|
||||||
|
object cty.Value
|
||||||
|
namer FieldNamer
|
||||||
|
rng hcl.Range
|
||||||
|
skipFields map[string]struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (od objectDecoder) EachField(iter FieldIterator) error {
|
||||||
|
for attr := range od.object.Type().AttributeTypes() {
|
||||||
|
if _, ok := od.skipFields[attr]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
desc := od.namer.GetField(iter.Desc.Fields(), attr)
|
||||||
|
if desc == nil {
|
||||||
|
if iter.IgnoreUnknown {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("%s: Unsupported argument; An argument named %q is not expected here.", od.rng, attr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val := od.object.GetAttr(attr)
|
||||||
|
if err := iter.Func(&IterField{
|
||||||
|
Name: attr,
|
||||||
|
Desc: desc,
|
||||||
|
Val: &val,
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (od objectDecoder) SkipFields(fields ...string) MessageDecoder {
|
||||||
|
skip := make(map[string]struct{}, len(fields)+len(od.skipFields))
|
||||||
|
for k, v := range od.skipFields {
|
||||||
|
skip[k] = v
|
||||||
|
}
|
||||||
|
for _, field := range fields {
|
||||||
|
skip[field] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: we rely on the fact od isn't a pointer to copy the struct here.
|
||||||
|
od.skipFields = skip
|
||||||
|
return od
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
// The protohcl package aims to define a canonical way to translate between
|
||||||
|
// protobuf and HCL encodings of data.
|
||||||
|
//
|
||||||
|
// Similar to google.golang.org/protobuf/encoding/protojson it intends to be
|
||||||
|
// opinionated about what the canonical HCL representation of a protobuf type
|
||||||
|
// should be.
|
||||||
|
//
|
||||||
|
// As HCL is a user centric data format as opposed to JSON/Protobuf which
|
||||||
|
// are intended to be used more by machines, efficiency is not a primary goal
|
||||||
|
// of this package as it is expected that users are either doing the encoding to and
|
||||||
|
// decoding from HCL at the edge (such as within the Consul CLI) or that even
|
||||||
|
// when done on servers, the rate that servers perform these translations should
|
||||||
|
// be low enough to have any inefficiency produce a tangible performance impact.
|
||||||
|
//
|
||||||
|
// HCL has two different syntaxes that could be used to represent data: attribute and block
|
||||||
|
//
|
||||||
|
// This implementation chooses to represent primitive values, enums and the well known wrapper types and
|
||||||
|
// collections of these values (maps and repeated fields) with attribute syntax. Other messages and collections
|
||||||
|
// with message value types will be represented with block syntax for example
|
||||||
|
//
|
||||||
|
// message Foo {
|
||||||
|
// map<string, int32> map_of_ints = 1;
|
||||||
|
// map<string, OtherMessage> map_of_messages = 2;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// would have HCL like:
|
||||||
|
//
|
||||||
|
// map_of_ints = {
|
||||||
|
// "foo": 1,
|
||||||
|
// "bar": 2,
|
||||||
|
// }
|
||||||
|
// map_of_messages "foo" {
|
||||||
|
// ...other fields
|
||||||
|
// }
|
||||||
|
// map_of_messages "bar" {
|
||||||
|
// ...other fields
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Similar goes for list of primitives vs list of messages (except the block syntax uses no labels). The differences
|
||||||
|
// between primitive fields outside of a collection and a message field really just amounts to not having to specify
|
||||||
|
// the "=" between the field name and the "{" character.
|
||||||
|
//
|
||||||
|
// Field Mapping
|
||||||
|
// | proto3 | HCL Type | example | notes |
|
||||||
|
// |------------------------+---------------+---------+---------------------------------------------------------------------------------+
|
||||||
|
// | message | Object | | Represented as a block |
|
||||||
|
// | enum | String | | |
|
||||||
|
// | map<K,V> | Map | | All keys are converted to/from strings. |
|
||||||
|
// | repeated V | List | | |
|
||||||
|
// | bool | Bool | | |
|
||||||
|
// | string | String | | |
|
||||||
|
// | bytes | base64 String | | |
|
||||||
|
// | int32, fixed32, uint32 | Number | | |
|
||||||
|
// | int64, fixed64, uint64 | Number | | |
|
||||||
|
// | float, double | Number | | |
|
||||||
|
//
|
||||||
|
// ----- Well Known Types -----
|
||||||
|
//
|
||||||
|
// | Any | Object | | |
|
||||||
|
// | Timestamp | String | | RFC 3339 compliant |
|
||||||
|
// | Duration | String | | String form is what would be accepted by time.ParseDuration |
|
||||||
|
// | Struct | Map | | |
|
||||||
|
// | Empty | Object | | An object with no fields |
|
||||||
|
// | BoolValue | Bool | | Mostly the same as a regular bool except null values in the HCL are preserved |
|
||||||
|
// | BytesValue | Bytes | | Mostly the same as a regular bytes except null values in the HCL are preserved |
|
||||||
|
// | StringValue | String | | Mostly the same as a regular string except null values in the HCL are preserved |
|
||||||
|
// | FloatValue | Number | | Mostly the same as a regular float except null values in the HCL are preserved |
|
||||||
|
// | DoubleValue | Number | | Mostly the same as a regular double except null values in the HCL are preserved |
|
||||||
|
// | Int32Value | Number | | Mostly the same as a regular int32 except null values in the HCL are preserved |
|
||||||
|
// | UInt32Value | Number | | Mostly the same as a regular uint32 except null values in the HCL are preserved |
|
||||||
|
// | Int64Value | Number | | Mostly the same as a regular int64 except null values in the HCL are preserved |
|
||||||
|
// | UInt64Value | Number | | Mostly the same as a regular uint64 except null values in the HCL are preserved |
|
||||||
|
// | FieldMask | String | | Each string of the FieldMask will be joined with a '.' |
|
||||||
|
//
|
||||||
|
|
||||||
|
package protohcl
|
|
@ -0,0 +1,18 @@
|
||||||
|
package protohcl
|
||||||
|
|
||||||
|
import "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
|
||||||
|
type FieldNamer interface {
|
||||||
|
NameField(protoreflect.FieldDescriptor) string
|
||||||
|
GetField(protoreflect.FieldDescriptors, string) protoreflect.FieldDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
|
type textFieldNamer struct{}
|
||||||
|
|
||||||
|
func (textFieldNamer) NameField(fd protoreflect.FieldDescriptor) string {
|
||||||
|
return fd.TextName()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (textFieldNamer) GetField(fds protoreflect.FieldDescriptors, name string) protoreflect.FieldDescriptor {
|
||||||
|
return fds.ByTextName(name)
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package protohcl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
type oneOfTracker struct {
|
||||||
|
namer FieldNamer
|
||||||
|
set map[protoreflect.FullName]string
|
||||||
|
}
|
||||||
|
|
||||||
|
func newOneOfTracker(namer FieldNamer) *oneOfTracker {
|
||||||
|
return &oneOfTracker{
|
||||||
|
namer: namer,
|
||||||
|
set: make(map[protoreflect.FullName]string),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *oneOfTracker) markFieldAsSet(desc protoreflect.FieldDescriptor) error {
|
||||||
|
oneof := desc.ContainingOneof()
|
||||||
|
if oneof == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
oneOfName := oneof.FullName()
|
||||||
|
|
||||||
|
if otherFieldName, ok := o.set[oneOfName]; ok {
|
||||||
|
oneOfFields := oneof.Fields()
|
||||||
|
var builder strings.Builder
|
||||||
|
|
||||||
|
for i := 0; i < oneOfFields.Len(); i++ {
|
||||||
|
name := o.namer.NameField(oneOfFields.Get(i))
|
||||||
|
|
||||||
|
if i == oneOfFields.Len()-1 {
|
||||||
|
builder.WriteString(fmt.Sprintf("%q", name))
|
||||||
|
} else if i == oneOfFields.Len()-2 {
|
||||||
|
builder.WriteString(fmt.Sprintf("%q and ", name))
|
||||||
|
} else {
|
||||||
|
builder.WriteString(fmt.Sprintf("%q, ", name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Errorf("Cannot set %q because %q was previously set. Only one of %s may be set.", o.namer.NameField(desc), otherFieldName, builder.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
o.set[oneOfName] = o.namer.NameField(desc)
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,138 @@
|
||||||
|
package protohcl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
"google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func decodeAttributeToPrimitive(desc protoreflect.FieldDescriptor, val cty.Value) (protoreflect.Value, error) {
|
||||||
|
switch kind := desc.Kind(); kind {
|
||||||
|
case protoreflect.BoolKind:
|
||||||
|
return protoBoolFromCty(val)
|
||||||
|
case protoreflect.EnumKind:
|
||||||
|
return protoEnumFromCty(desc, val)
|
||||||
|
case protoreflect.Int32Kind:
|
||||||
|
return protoInt32FromCty(val)
|
||||||
|
case protoreflect.Sint32Kind:
|
||||||
|
return protoInt32FromCty(val)
|
||||||
|
case protoreflect.Uint32Kind:
|
||||||
|
return protoUint32FromCty(val)
|
||||||
|
case protoreflect.Int64Kind:
|
||||||
|
return protoInt64FromCty(val)
|
||||||
|
case protoreflect.Sint64Kind:
|
||||||
|
return protoInt64FromCty(val)
|
||||||
|
case protoreflect.Uint64Kind:
|
||||||
|
return protoUint64FromCty(val)
|
||||||
|
case protoreflect.Sfixed32Kind:
|
||||||
|
return protoInt32FromCty(val)
|
||||||
|
case protoreflect.Fixed32Kind:
|
||||||
|
return protoUint32FromCty(val)
|
||||||
|
case protoreflect.FloatKind:
|
||||||
|
return protoFloatFromCty(val)
|
||||||
|
case protoreflect.Sfixed64Kind:
|
||||||
|
return protoInt64FromCty(val)
|
||||||
|
case protoreflect.Fixed64Kind:
|
||||||
|
return protoUint64FromCty(val)
|
||||||
|
case protoreflect.DoubleKind:
|
||||||
|
return protoDoubleFromCty(val)
|
||||||
|
case protoreflect.StringKind:
|
||||||
|
return protoStringFromCty(val)
|
||||||
|
case protoreflect.BytesKind:
|
||||||
|
return protoBytesFromCty(val)
|
||||||
|
default:
|
||||||
|
return protoreflect.Value{}, fmt.Errorf("unknown primitive protobuf kind: %q", kind.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoBoolFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
goVal, err := boolFromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoreflect.ValueOfBool(goVal), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoEnumFromCty(desc protoreflect.FieldDescriptor, val cty.Value) (protoreflect.Value, error) {
|
||||||
|
if val.Type() != cty.String {
|
||||||
|
return protoreflect.Value{}, fmt.Errorf("expected value of type %s but actual type is %s", cty.String.FriendlyName(), val.Type().FriendlyName())
|
||||||
|
}
|
||||||
|
|
||||||
|
if val.IsNull() {
|
||||||
|
defaultValDesc := desc.DefaultEnumValue()
|
||||||
|
return protoreflect.ValueOfEnum(defaultValDesc.Number()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
valDesc := desc.Enum().Values().ByName(protoreflect.Name(val.AsString()))
|
||||||
|
if valDesc == nil {
|
||||||
|
defaultValDesc := desc.DefaultEnumValue()
|
||||||
|
return protoreflect.ValueOfEnum(defaultValDesc.Number()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return protoreflect.ValueOfEnum(valDesc.Number()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoInt32FromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
goVal, err := int32FromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoreflect.ValueOfInt32(goVal), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoUint32FromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
goVal, err := uint32FromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoreflect.ValueOfUint32(goVal), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoInt64FromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
goVal, err := int64FromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoreflect.ValueOfInt64(goVal), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoUint64FromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
goVal, err := uint64FromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoreflect.ValueOfUint64(goVal), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoFloatFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
goVal, err := floatFromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoreflect.ValueOfFloat32(goVal), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoDoubleFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
goVal, err := doubleFromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoreflect.ValueOfFloat64(goVal), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoStringFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
goVal, err := stringFromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoreflect.ValueOfString(goVal), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoBytesFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
goVal, err := bytesFromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoreflect.ValueOfBytes(goVal), nil
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
version: v1
|
||||||
|
managed:
|
||||||
|
enabled: true
|
||||||
|
go_package_prefix:
|
||||||
|
default: github.com/hashicorp/consul/internal/protohcl/testproto
|
||||||
|
plugins:
|
||||||
|
- name: go
|
||||||
|
out: .
|
||||||
|
opt: paths=source_relative
|
|
@ -0,0 +1,994 @@
|
||||||
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// protoc-gen-go v1.30.0
|
||||||
|
// protoc (unknown)
|
||||||
|
// source: example.proto
|
||||||
|
|
||||||
|
package testproto
|
||||||
|
|
||||||
|
import (
|
||||||
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||||
|
anypb "google.golang.org/protobuf/types/known/anypb"
|
||||||
|
durationpb "google.golang.org/protobuf/types/known/durationpb"
|
||||||
|
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||||
|
structpb "google.golang.org/protobuf/types/known/structpb"
|
||||||
|
timestamppb "google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
wrapperspb "google.golang.org/protobuf/types/known/wrapperspb"
|
||||||
|
reflect "reflect"
|
||||||
|
sync "sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Verify that this generated code is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||||
|
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||||
|
)
|
||||||
|
|
||||||
|
type Protocol int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
Protocol_PROTOCOL_UNSPECIFIED Protocol = 0
|
||||||
|
Protocol_PROTOCOL_TCP Protocol = 1
|
||||||
|
Protocol_PROTOCOL_UDP Protocol = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
// Enum value maps for Protocol.
|
||||||
|
var (
|
||||||
|
Protocol_name = map[int32]string{
|
||||||
|
0: "PROTOCOL_UNSPECIFIED",
|
||||||
|
1: "PROTOCOL_TCP",
|
||||||
|
2: "PROTOCOL_UDP",
|
||||||
|
}
|
||||||
|
Protocol_value = map[string]int32{
|
||||||
|
"PROTOCOL_UNSPECIFIED": 0,
|
||||||
|
"PROTOCOL_TCP": 1,
|
||||||
|
"PROTOCOL_UDP": 2,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (x Protocol) Enum() *Protocol {
|
||||||
|
p := new(Protocol)
|
||||||
|
*p = x
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x Protocol) String() string {
|
||||||
|
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Protocol) Descriptor() protoreflect.EnumDescriptor {
|
||||||
|
return file_example_proto_enumTypes[0].Descriptor()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (Protocol) Type() protoreflect.EnumType {
|
||||||
|
return &file_example_proto_enumTypes[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x Protocol) Number() protoreflect.EnumNumber {
|
||||||
|
return protoreflect.EnumNumber(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use Protocol.Descriptor instead.
|
||||||
|
func (Protocol) EnumDescriptor() ([]byte, []int) {
|
||||||
|
return file_example_proto_rawDescGZIP(), []int{0}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Primitives struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
DoubleVal float64 `protobuf:"fixed64,1,opt,name=double_val,json=doubleVal,proto3" json:"double_val,omitempty"`
|
||||||
|
FloatVal float32 `protobuf:"fixed32,2,opt,name=float_val,json=floatVal,proto3" json:"float_val,omitempty"`
|
||||||
|
Int32Val int32 `protobuf:"varint,3,opt,name=int32_val,json=int32Val,proto3" json:"int32_val,omitempty"`
|
||||||
|
Int64Val int64 `protobuf:"varint,4,opt,name=int64_val,json=int64Val,proto3" json:"int64_val,omitempty"`
|
||||||
|
Uint32Val uint32 `protobuf:"varint,5,opt,name=uint32_val,json=uint32Val,proto3" json:"uint32_val,omitempty"`
|
||||||
|
Uint64Val uint64 `protobuf:"varint,6,opt,name=uint64_val,json=uint64Val,proto3" json:"uint64_val,omitempty"`
|
||||||
|
Sint32Val int32 `protobuf:"zigzag32,7,opt,name=sint32_val,json=sint32Val,proto3" json:"sint32_val,omitempty"`
|
||||||
|
Sint64Val int64 `protobuf:"zigzag64,8,opt,name=sint64_val,json=sint64Val,proto3" json:"sint64_val,omitempty"`
|
||||||
|
Fixed32Val uint32 `protobuf:"fixed32,9,opt,name=fixed32_val,json=fixed32Val,proto3" json:"fixed32_val,omitempty"`
|
||||||
|
Fixed64Val uint64 `protobuf:"fixed64,10,opt,name=fixed64_val,json=fixed64Val,proto3" json:"fixed64_val,omitempty"`
|
||||||
|
Sfixed32Val int32 `protobuf:"fixed32,11,opt,name=sfixed32_val,json=sfixed32Val,proto3" json:"sfixed32_val,omitempty"`
|
||||||
|
Sfixed64Val int64 `protobuf:"fixed64,12,opt,name=sfixed64_val,json=sfixed64Val,proto3" json:"sfixed64_val,omitempty"`
|
||||||
|
BoolVal bool `protobuf:"varint,13,opt,name=bool_val,json=boolVal,proto3" json:"bool_val,omitempty"`
|
||||||
|
StringVal string `protobuf:"bytes,14,opt,name=string_val,json=stringVal,proto3" json:"string_val,omitempty"`
|
||||||
|
ByteVal []byte `protobuf:"bytes,15,opt,name=byte_val,json=byteVal,proto3" json:"byte_val,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) Reset() {
|
||||||
|
*x = Primitives{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_example_proto_msgTypes[0]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*Primitives) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *Primitives) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_example_proto_msgTypes[0]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use Primitives.ProtoReflect.Descriptor instead.
|
||||||
|
func (*Primitives) Descriptor() ([]byte, []int) {
|
||||||
|
return file_example_proto_rawDescGZIP(), []int{0}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) GetDoubleVal() float64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.DoubleVal
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) GetFloatVal() float32 {
|
||||||
|
if x != nil {
|
||||||
|
return x.FloatVal
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) GetInt32Val() int32 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Int32Val
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) GetInt64Val() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Int64Val
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) GetUint32Val() uint32 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Uint32Val
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) GetUint64Val() uint64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Uint64Val
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) GetSint32Val() int32 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Sint32Val
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) GetSint64Val() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Sint64Val
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) GetFixed32Val() uint32 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Fixed32Val
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) GetFixed64Val() uint64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Fixed64Val
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) GetSfixed32Val() int32 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Sfixed32Val
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) GetSfixed64Val() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Sfixed64Val
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) GetBoolVal() bool {
|
||||||
|
if x != nil {
|
||||||
|
return x.BoolVal
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) GetStringVal() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.StringVal
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Primitives) GetByteVal() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.ByteVal
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type NestedAndCollections struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
Primitives *Primitives `protobuf:"bytes,1,opt,name=primitives,proto3" json:"primitives,omitempty"`
|
||||||
|
PrimitivesList []*Primitives `protobuf:"bytes,2,rep,name=primitives_list,json=primitivesList,proto3" json:"primitives_list,omitempty"`
|
||||||
|
PrimitivesMap map[string]*Primitives `protobuf:"bytes,3,rep,name=primitives_map,json=primitivesMap,proto3" json:"primitives_map,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||||
|
ProtocolMap map[string]Protocol `protobuf:"bytes,4,rep,name=protocol_map,json=protocolMap,proto3" json:"protocol_map,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3,enum=hashicorp.consul.internal.protohcl.testproto.Protocol"`
|
||||||
|
IntList []int32 `protobuf:"varint,5,rep,packed,name=int_list,json=intList,proto3" json:"int_list,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NestedAndCollections) Reset() {
|
||||||
|
*x = NestedAndCollections{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_example_proto_msgTypes[1]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NestedAndCollections) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*NestedAndCollections) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *NestedAndCollections) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_example_proto_msgTypes[1]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use NestedAndCollections.ProtoReflect.Descriptor instead.
|
||||||
|
func (*NestedAndCollections) Descriptor() ([]byte, []int) {
|
||||||
|
return file_example_proto_rawDescGZIP(), []int{1}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NestedAndCollections) GetPrimitives() *Primitives {
|
||||||
|
if x != nil {
|
||||||
|
return x.Primitives
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NestedAndCollections) GetPrimitivesList() []*Primitives {
|
||||||
|
if x != nil {
|
||||||
|
return x.PrimitivesList
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NestedAndCollections) GetPrimitivesMap() map[string]*Primitives {
|
||||||
|
if x != nil {
|
||||||
|
return x.PrimitivesMap
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NestedAndCollections) GetProtocolMap() map[string]Protocol {
|
||||||
|
if x != nil {
|
||||||
|
return x.ProtocolMap
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NestedAndCollections) GetIntList() []int32 {
|
||||||
|
if x != nil {
|
||||||
|
return x.IntList
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Wrappers struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
DoubleVal *wrapperspb.DoubleValue `protobuf:"bytes,1,opt,name=double_val,json=doubleVal,proto3" json:"double_val,omitempty"`
|
||||||
|
FloatVal *wrapperspb.FloatValue `protobuf:"bytes,2,opt,name=float_val,json=floatVal,proto3" json:"float_val,omitempty"`
|
||||||
|
Int32Val *wrapperspb.Int32Value `protobuf:"bytes,3,opt,name=int32_val,json=int32Val,proto3" json:"int32_val,omitempty"`
|
||||||
|
Int64Val *wrapperspb.Int64Value `protobuf:"bytes,4,opt,name=int64_val,json=int64Val,proto3" json:"int64_val,omitempty"`
|
||||||
|
Uint32Val *wrapperspb.UInt32Value `protobuf:"bytes,5,opt,name=uint32_val,json=uint32Val,proto3" json:"uint32_val,omitempty"`
|
||||||
|
Uint64Val *wrapperspb.UInt64Value `protobuf:"bytes,6,opt,name=uint64_val,json=uint64Val,proto3" json:"uint64_val,omitempty"`
|
||||||
|
BoolVal *wrapperspb.BoolValue `protobuf:"bytes,13,opt,name=bool_val,json=boolVal,proto3" json:"bool_val,omitempty"`
|
||||||
|
StringVal *wrapperspb.StringValue `protobuf:"bytes,14,opt,name=string_val,json=stringVal,proto3" json:"string_val,omitempty"`
|
||||||
|
BytesVal *wrapperspb.BytesValue `protobuf:"bytes,15,opt,name=bytes_val,json=bytesVal,proto3" json:"bytes_val,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Wrappers) Reset() {
|
||||||
|
*x = Wrappers{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_example_proto_msgTypes[2]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Wrappers) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*Wrappers) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *Wrappers) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_example_proto_msgTypes[2]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use Wrappers.ProtoReflect.Descriptor instead.
|
||||||
|
func (*Wrappers) Descriptor() ([]byte, []int) {
|
||||||
|
return file_example_proto_rawDescGZIP(), []int{2}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Wrappers) GetDoubleVal() *wrapperspb.DoubleValue {
|
||||||
|
if x != nil {
|
||||||
|
return x.DoubleVal
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Wrappers) GetFloatVal() *wrapperspb.FloatValue {
|
||||||
|
if x != nil {
|
||||||
|
return x.FloatVal
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Wrappers) GetInt32Val() *wrapperspb.Int32Value {
|
||||||
|
if x != nil {
|
||||||
|
return x.Int32Val
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Wrappers) GetInt64Val() *wrapperspb.Int64Value {
|
||||||
|
if x != nil {
|
||||||
|
return x.Int64Val
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Wrappers) GetUint32Val() *wrapperspb.UInt32Value {
|
||||||
|
if x != nil {
|
||||||
|
return x.Uint32Val
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Wrappers) GetUint64Val() *wrapperspb.UInt64Value {
|
||||||
|
if x != nil {
|
||||||
|
return x.Uint64Val
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Wrappers) GetBoolVal() *wrapperspb.BoolValue {
|
||||||
|
if x != nil {
|
||||||
|
return x.BoolVal
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Wrappers) GetStringVal() *wrapperspb.StringValue {
|
||||||
|
if x != nil {
|
||||||
|
return x.StringVal
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *Wrappers) GetBytesVal() *wrapperspb.BytesValue {
|
||||||
|
if x != nil {
|
||||||
|
return x.BytesVal
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type OneOf struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
// Types that are assignable to Data:
|
||||||
|
//
|
||||||
|
// *OneOf_Int32Val
|
||||||
|
// *OneOf_Primitives
|
||||||
|
Data isOneOf_Data `protobuf_oneof:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *OneOf) Reset() {
|
||||||
|
*x = OneOf{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_example_proto_msgTypes[3]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *OneOf) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*OneOf) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *OneOf) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_example_proto_msgTypes[3]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use OneOf.ProtoReflect.Descriptor instead.
|
||||||
|
func (*OneOf) Descriptor() ([]byte, []int) {
|
||||||
|
return file_example_proto_rawDescGZIP(), []int{3}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *OneOf) GetData() isOneOf_Data {
|
||||||
|
if m != nil {
|
||||||
|
return m.Data
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *OneOf) GetInt32Val() int32 {
|
||||||
|
if x, ok := x.GetData().(*OneOf_Int32Val); ok {
|
||||||
|
return x.Int32Val
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *OneOf) GetPrimitives() *Primitives {
|
||||||
|
if x, ok := x.GetData().(*OneOf_Primitives); ok {
|
||||||
|
return x.Primitives
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type isOneOf_Data interface {
|
||||||
|
isOneOf_Data()
|
||||||
|
}
|
||||||
|
|
||||||
|
type OneOf_Int32Val struct {
|
||||||
|
Int32Val int32 `protobuf:"varint,1,opt,name=int32_val,json=int32Val,proto3,oneof"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OneOf_Primitives struct {
|
||||||
|
Primitives *Primitives `protobuf:"bytes,2,opt,name=primitives,proto3,oneof"` // note repeated fields (including maps) are not allowed in oneofs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*OneOf_Int32Val) isOneOf_Data() {}
|
||||||
|
|
||||||
|
func (*OneOf_Primitives) isOneOf_Data() {}
|
||||||
|
|
||||||
|
type NonDynamicWellKnown struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
EmptyVal *emptypb.Empty `protobuf:"bytes,1,opt,name=empty_val,json=emptyVal,proto3" json:"empty_val,omitempty"`
|
||||||
|
TimestampVal *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=timestamp_val,json=timestampVal,proto3" json:"timestamp_val,omitempty"`
|
||||||
|
DurationVal *durationpb.Duration `protobuf:"bytes,3,opt,name=duration_val,json=durationVal,proto3" json:"duration_val,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NonDynamicWellKnown) Reset() {
|
||||||
|
*x = NonDynamicWellKnown{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_example_proto_msgTypes[4]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NonDynamicWellKnown) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*NonDynamicWellKnown) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *NonDynamicWellKnown) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_example_proto_msgTypes[4]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use NonDynamicWellKnown.ProtoReflect.Descriptor instead.
|
||||||
|
func (*NonDynamicWellKnown) Descriptor() ([]byte, []int) {
|
||||||
|
return file_example_proto_rawDescGZIP(), []int{4}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NonDynamicWellKnown) GetEmptyVal() *emptypb.Empty {
|
||||||
|
if x != nil {
|
||||||
|
return x.EmptyVal
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NonDynamicWellKnown) GetTimestampVal() *timestamppb.Timestamp {
|
||||||
|
if x != nil {
|
||||||
|
return x.TimestampVal
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NonDynamicWellKnown) GetDurationVal() *durationpb.Duration {
|
||||||
|
if x != nil {
|
||||||
|
return x.DurationVal
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type DynamicWellKnown struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
AnyVal *anypb.Any `protobuf:"bytes,1,opt,name=any_val,json=anyVal,proto3" json:"any_val,omitempty"`
|
||||||
|
StructVal *structpb.Struct `protobuf:"bytes,2,opt,name=struct_val,json=structVal,proto3" json:"struct_val,omitempty"`
|
||||||
|
AnyList []*anypb.Any `protobuf:"bytes,3,rep,name=any_list,json=anyList,proto3" json:"any_list,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DynamicWellKnown) Reset() {
|
||||||
|
*x = DynamicWellKnown{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_example_proto_msgTypes[5]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DynamicWellKnown) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*DynamicWellKnown) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *DynamicWellKnown) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_example_proto_msgTypes[5]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use DynamicWellKnown.ProtoReflect.Descriptor instead.
|
||||||
|
func (*DynamicWellKnown) Descriptor() ([]byte, []int) {
|
||||||
|
return file_example_proto_rawDescGZIP(), []int{5}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DynamicWellKnown) GetAnyVal() *anypb.Any {
|
||||||
|
if x != nil {
|
||||||
|
return x.AnyVal
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DynamicWellKnown) GetStructVal() *structpb.Struct {
|
||||||
|
if x != nil {
|
||||||
|
return x.StructVal
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *DynamicWellKnown) GetAnyList() []*anypb.Any {
|
||||||
|
if x != nil {
|
||||||
|
return x.AnyList
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var File_example_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
|
var file_example_proto_rawDesc = []byte{
|
||||||
|
0x0a, 0x0d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
|
||||||
|
0x2c, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75,
|
||||||
|
0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||||
|
0x68, 0x63, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67,
|
||||||
|
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64,
|
||||||
|
0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67,
|
||||||
|
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65,
|
||||||
|
0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67,
|
||||||
|
0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65,
|
||||||
|
0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f,
|
||||||
|
0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61,
|
||||||
|
0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f,
|
||||||
|
0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79,
|
||||||
|
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70,
|
||||||
|
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70,
|
||||||
|
0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdb, 0x03, 0x0a, 0x0a, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69,
|
||||||
|
0x76, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61,
|
||||||
|
0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56,
|
||||||
|
0x61, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x18,
|
||||||
|
0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x08, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61, 0x6c, 0x12,
|
||||||
|
0x1b, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01,
|
||||||
|
0x28, 0x05, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x12, 0x1b, 0x0a, 0x09,
|
||||||
|
0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||||
|
0x08, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x69, 0x6e,
|
||||||
|
0x74, 0x33, 0x32, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x75,
|
||||||
|
0x69, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x69, 0x6e, 0x74,
|
||||||
|
0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x75, 0x69,
|
||||||
|
0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x69, 0x6e, 0x74, 0x33,
|
||||||
|
0x32, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x11, 0x52, 0x09, 0x73, 0x69, 0x6e,
|
||||||
|
0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x69, 0x6e, 0x74, 0x36, 0x34,
|
||||||
|
0x5f, 0x76, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x12, 0x52, 0x09, 0x73, 0x69, 0x6e, 0x74,
|
||||||
|
0x36, 0x34, 0x56, 0x61, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32,
|
||||||
|
0x5f, 0x76, 0x61, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x07, 0x52, 0x0a, 0x66, 0x69, 0x78, 0x65,
|
||||||
|
0x64, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x69, 0x78, 0x65, 0x64, 0x36,
|
||||||
|
0x34, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x06, 0x52, 0x0a, 0x66, 0x69, 0x78,
|
||||||
|
0x65, 0x64, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x66, 0x69, 0x78, 0x65,
|
||||||
|
0x64, 0x33, 0x32, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0f, 0x52, 0x0b, 0x73,
|
||||||
|
0x66, 0x69, 0x78, 0x65, 0x64, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x66,
|
||||||
|
0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x10,
|
||||||
|
0x52, 0x0b, 0x73, 0x66, 0x69, 0x78, 0x65, 0x64, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x12, 0x19, 0x0a,
|
||||||
|
0x08, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52,
|
||||||
|
0x07, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x69,
|
||||||
|
0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74,
|
||||||
|
0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x62, 0x79, 0x74, 0x65, 0x5f,
|
||||||
|
0x76, 0x61, 0x6c, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, 0x79, 0x74, 0x65, 0x56,
|
||||||
|
0x61, 0x6c, 0x22, 0xd8, 0x05, 0x0a, 0x14, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x41, 0x6e, 0x64,
|
||||||
|
0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x58, 0x0a, 0x0a, 0x70,
|
||||||
|
0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||||
|
0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73,
|
||||||
|
0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||||
|
0x6f, 0x68, 0x63, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50,
|
||||||
|
0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6d, 0x69,
|
||||||
|
0x74, 0x69, 0x76, 0x65, 0x73, 0x12, 0x61, 0x0a, 0x0f, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69,
|
||||||
|
0x76, 0x65, 0x73, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38,
|
||||||
|
0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75,
|
||||||
|
0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||||
|
0x68, 0x63, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72,
|
||||||
|
0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x52, 0x0e, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74,
|
||||||
|
0x69, 0x76, 0x65, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x7c, 0x0a, 0x0e, 0x70, 0x72, 0x69, 0x6d,
|
||||||
|
0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
|
||||||
|
0x32, 0x55, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e,
|
||||||
|
0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f,
|
||||||
|
0x74, 0x6f, 0x68, 0x63, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
|
||||||
|
0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x41, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,
|
||||||
|
0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x4d,
|
||||||
|
0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69,
|
||||||
|
0x76, 0x65, 0x73, 0x4d, 0x61, 0x70, 0x12, 0x76, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63,
|
||||||
|
0x6f, 0x6c, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x53, 0x2e, 0x68,
|
||||||
|
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e,
|
||||||
|
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x68, 0x63,
|
||||||
|
0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4e, 0x65, 0x73, 0x74,
|
||||||
|
0x65, 0x64, 0x41, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
|
||||||
|
0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72,
|
||||||
|
0x79, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4d, 0x61, 0x70, 0x12, 0x19,
|
||||||
|
0x0a, 0x08, 0x69, 0x6e, 0x74, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x05, 0x20, 0x03, 0x28, 0x05,
|
||||||
|
0x52, 0x07, 0x69, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x1a, 0x7a, 0x0a, 0x12, 0x50, 0x72, 0x69,
|
||||||
|
0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
|
||||||
|
0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
|
||||||
|
0x79, 0x12, 0x4e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
|
||||||
|
0x32, 0x38, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e,
|
||||||
|
0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f,
|
||||||
|
0x74, 0x6f, 0x68, 0x63, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
|
||||||
|
0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||||
|
0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x76, 0x0a, 0x10, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f,
|
||||||
|
0x6c, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
|
||||||
|
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x4c, 0x0a, 0x05, 0x76,
|
||||||
|
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x68, 0x61, 0x73,
|
||||||
|
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e,
|
||||||
|
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x68, 0x63, 0x6c, 0x2e,
|
||||||
|
0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63,
|
||||||
|
0x6f, 0x6c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9d, 0x04,
|
||||||
|
0x0a, 0x08, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x12, 0x3b, 0x0a, 0x0a, 0x64, 0x6f,
|
||||||
|
0x75, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c,
|
||||||
|
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||||
|
0x2e, 0x44, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x64, 0x6f,
|
||||||
|
0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x12, 0x38, 0x0a, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74,
|
||||||
|
0x5f, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f,
|
||||||
|
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x6c, 0x6f,
|
||||||
|
0x61, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x61,
|
||||||
|
0x6c, 0x12, 0x38, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x03,
|
||||||
|
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
|
||||||
|
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75,
|
||||||
|
0x65, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x12, 0x38, 0x0a, 0x09, 0x69,
|
||||||
|
0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b,
|
||||||
|
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||||
|
0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x69, 0x6e, 0x74,
|
||||||
|
0x36, 0x34, 0x56, 0x61, 0x6c, 0x12, 0x3b, 0x0a, 0x0a, 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x5f,
|
||||||
|
0x76, 0x61, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||||
|
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74,
|
||||||
|
0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x75, 0x69, 0x6e, 0x74, 0x33, 0x32, 0x56,
|
||||||
|
0x61, 0x6c, 0x12, 0x3b, 0x0a, 0x0a, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x76, 0x61, 0x6c,
|
||||||
|
0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
|
||||||
|
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56,
|
||||||
|
0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x12,
|
||||||
|
0x35, 0x0a, 0x08, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x0d, 0x20, 0x01, 0x28,
|
||||||
|
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||||
|
0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x62,
|
||||||
|
0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x12, 0x3b, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
|
||||||
|
0x5f, 0x76, 0x61, 0x6c, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f,
|
||||||
|
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72,
|
||||||
|
0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x09, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
|
||||||
|
0x56, 0x61, 0x6c, 0x12, 0x38, 0x0a, 0x09, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x76, 0x61, 0x6c,
|
||||||
|
0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
|
||||||
|
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61,
|
||||||
|
0x6c, 0x75, 0x65, 0x52, 0x08, 0x62, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x22, 0x8a, 0x01,
|
||||||
|
0x0a, 0x05, 0x4f, 0x6e, 0x65, 0x4f, 0x66, 0x12, 0x1d, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x33, 0x32,
|
||||||
|
0x5f, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e,
|
||||||
|
0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x12, 0x5a, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74,
|
||||||
|
0x69, 0x76, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x68, 0x61, 0x73,
|
||||||
|
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e,
|
||||||
|
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x68, 0x63, 0x6c, 0x2e,
|
||||||
|
0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74,
|
||||||
|
0x69, 0x76, 0x65, 0x73, 0x48, 0x00, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76,
|
||||||
|
0x65, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xc9, 0x01, 0x0a, 0x13, 0x4e,
|
||||||
|
0x6f, 0x6e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f,
|
||||||
|
0x77, 0x6e, 0x12, 0x33, 0x0a, 0x09, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x18,
|
||||||
|
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,
|
||||||
|
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x52, 0x08, 0x65,
|
||||||
|
0x6d, 0x70, 0x74, 0x79, 0x56, 0x61, 0x6c, 0x12, 0x3f, 0x0a, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x73,
|
||||||
|
0x74, 0x61, 0x6d, 0x70, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
|
||||||
|
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||||
|
0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0c, 0x74, 0x69, 0x6d, 0x65,
|
||||||
|
0x73, 0x74, 0x61, 0x6d, 0x70, 0x56, 0x61, 0x6c, 0x12, 0x3c, 0x0a, 0x0c, 0x64, 0x75, 0x72, 0x61,
|
||||||
|
0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
|
||||||
|
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||||
|
0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x75, 0x72, 0x61, 0x74,
|
||||||
|
0x69, 0x6f, 0x6e, 0x56, 0x61, 0x6c, 0x22, 0xaa, 0x01, 0x0a, 0x10, 0x44, 0x79, 0x6e, 0x61, 0x6d,
|
||||||
|
0x69, 0x63, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x12, 0x2d, 0x0a, 0x07, 0x61,
|
||||||
|
0x6e, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67,
|
||||||
|
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41,
|
||||||
|
0x6e, 0x79, 0x52, 0x06, 0x61, 0x6e, 0x79, 0x56, 0x61, 0x6c, 0x12, 0x36, 0x0a, 0x0a, 0x73, 0x74,
|
||||||
|
0x72, 0x75, 0x63, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17,
|
||||||
|
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||||
|
0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x09, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x56,
|
||||||
|
0x61, 0x6c, 0x12, 0x2f, 0x0a, 0x08, 0x61, 0x6e, 0x79, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x03,
|
||||||
|
0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
|
||||||
|
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x61, 0x6e, 0x79, 0x4c,
|
||||||
|
0x69, 0x73, 0x74, 0x2a, 0x48, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12,
|
||||||
|
0x18, 0x0a, 0x14, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50,
|
||||||
|
0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x52, 0x4f,
|
||||||
|
0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x54, 0x43, 0x50, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x50,
|
||||||
|
0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x55, 0x44, 0x50, 0x10, 0x02, 0x42, 0xcf, 0x02,
|
||||||
|
0x0a, 0x30, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e,
|
||||||
|
0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e,
|
||||||
|
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x68, 0x63, 0x6c, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f,
|
||||||
|
0x74, 0x6f, 0x42, 0x0c, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f,
|
||||||
|
0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68,
|
||||||
|
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f,
|
||||||
|
0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x68, 0x63,
|
||||||
|
0x6c, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0xa2, 0x02, 0x05, 0x48, 0x43,
|
||||||
|
0x49, 0x50, 0x54, 0xaa, 0x02, 0x2c, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e,
|
||||||
|
0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2e,
|
||||||
|
0x50, 0x72, 0x6f, 0x74, 0x6f, 0x68, 0x63, 0x6c, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f,
|
||||||
|
0x74, 0x6f, 0xca, 0x02, 0x2c, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43,
|
||||||
|
0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x50,
|
||||||
|
0x72, 0x6f, 0x74, 0x6f, 0x68, 0x63, 0x6c, 0x5c, 0x54, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74,
|
||||||
|
0x6f, 0xe2, 0x02, 0x38, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f,
|
||||||
|
0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5c, 0x50, 0x72,
|
||||||
|
0x6f, 0x74, 0x6f, 0x68, 0x63, 0x6c, 0x5c, 0x54, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||||
|
0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x30, 0x48,
|
||||||
|
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
|
||||||
|
0x3a, 0x3a, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x3a, 0x3a, 0x50, 0x72, 0x6f, 0x74,
|
||||||
|
0x6f, 0x68, 0x63, 0x6c, 0x3a, 0x3a, 0x54, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||||
|
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
file_example_proto_rawDescOnce sync.Once
|
||||||
|
file_example_proto_rawDescData = file_example_proto_rawDesc
|
||||||
|
)
|
||||||
|
|
||||||
|
func file_example_proto_rawDescGZIP() []byte {
|
||||||
|
file_example_proto_rawDescOnce.Do(func() {
|
||||||
|
file_example_proto_rawDescData = protoimpl.X.CompressGZIP(file_example_proto_rawDescData)
|
||||||
|
})
|
||||||
|
return file_example_proto_rawDescData
|
||||||
|
}
|
||||||
|
|
||||||
|
var file_example_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||||
|
var file_example_proto_msgTypes = make([]protoimpl.MessageInfo, 8)
|
||||||
|
var file_example_proto_goTypes = []interface{}{
|
||||||
|
(Protocol)(0), // 0: hashicorp.consul.internal.protohcl.testproto.Protocol
|
||||||
|
(*Primitives)(nil), // 1: hashicorp.consul.internal.protohcl.testproto.Primitives
|
||||||
|
(*NestedAndCollections)(nil), // 2: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections
|
||||||
|
(*Wrappers)(nil), // 3: hashicorp.consul.internal.protohcl.testproto.Wrappers
|
||||||
|
(*OneOf)(nil), // 4: hashicorp.consul.internal.protohcl.testproto.OneOf
|
||||||
|
(*NonDynamicWellKnown)(nil), // 5: hashicorp.consul.internal.protohcl.testproto.NonDynamicWellKnown
|
||||||
|
(*DynamicWellKnown)(nil), // 6: hashicorp.consul.internal.protohcl.testproto.DynamicWellKnown
|
||||||
|
nil, // 7: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.PrimitivesMapEntry
|
||||||
|
nil, // 8: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.ProtocolMapEntry
|
||||||
|
(*wrapperspb.DoubleValue)(nil), // 9: google.protobuf.DoubleValue
|
||||||
|
(*wrapperspb.FloatValue)(nil), // 10: google.protobuf.FloatValue
|
||||||
|
(*wrapperspb.Int32Value)(nil), // 11: google.protobuf.Int32Value
|
||||||
|
(*wrapperspb.Int64Value)(nil), // 12: google.protobuf.Int64Value
|
||||||
|
(*wrapperspb.UInt32Value)(nil), // 13: google.protobuf.UInt32Value
|
||||||
|
(*wrapperspb.UInt64Value)(nil), // 14: google.protobuf.UInt64Value
|
||||||
|
(*wrapperspb.BoolValue)(nil), // 15: google.protobuf.BoolValue
|
||||||
|
(*wrapperspb.StringValue)(nil), // 16: google.protobuf.StringValue
|
||||||
|
(*wrapperspb.BytesValue)(nil), // 17: google.protobuf.BytesValue
|
||||||
|
(*emptypb.Empty)(nil), // 18: google.protobuf.Empty
|
||||||
|
(*timestamppb.Timestamp)(nil), // 19: google.protobuf.Timestamp
|
||||||
|
(*durationpb.Duration)(nil), // 20: google.protobuf.Duration
|
||||||
|
(*anypb.Any)(nil), // 21: google.protobuf.Any
|
||||||
|
(*structpb.Struct)(nil), // 22: google.protobuf.Struct
|
||||||
|
}
|
||||||
|
var file_example_proto_depIdxs = []int32{
|
||||||
|
1, // 0: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.primitives:type_name -> hashicorp.consul.internal.protohcl.testproto.Primitives
|
||||||
|
1, // 1: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.primitives_list:type_name -> hashicorp.consul.internal.protohcl.testproto.Primitives
|
||||||
|
7, // 2: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.primitives_map:type_name -> hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.PrimitivesMapEntry
|
||||||
|
8, // 3: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.protocol_map:type_name -> hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.ProtocolMapEntry
|
||||||
|
9, // 4: hashicorp.consul.internal.protohcl.testproto.Wrappers.double_val:type_name -> google.protobuf.DoubleValue
|
||||||
|
10, // 5: hashicorp.consul.internal.protohcl.testproto.Wrappers.float_val:type_name -> google.protobuf.FloatValue
|
||||||
|
11, // 6: hashicorp.consul.internal.protohcl.testproto.Wrappers.int32_val:type_name -> google.protobuf.Int32Value
|
||||||
|
12, // 7: hashicorp.consul.internal.protohcl.testproto.Wrappers.int64_val:type_name -> google.protobuf.Int64Value
|
||||||
|
13, // 8: hashicorp.consul.internal.protohcl.testproto.Wrappers.uint32_val:type_name -> google.protobuf.UInt32Value
|
||||||
|
14, // 9: hashicorp.consul.internal.protohcl.testproto.Wrappers.uint64_val:type_name -> google.protobuf.UInt64Value
|
||||||
|
15, // 10: hashicorp.consul.internal.protohcl.testproto.Wrappers.bool_val:type_name -> google.protobuf.BoolValue
|
||||||
|
16, // 11: hashicorp.consul.internal.protohcl.testproto.Wrappers.string_val:type_name -> google.protobuf.StringValue
|
||||||
|
17, // 12: hashicorp.consul.internal.protohcl.testproto.Wrappers.bytes_val:type_name -> google.protobuf.BytesValue
|
||||||
|
1, // 13: hashicorp.consul.internal.protohcl.testproto.OneOf.primitives:type_name -> hashicorp.consul.internal.protohcl.testproto.Primitives
|
||||||
|
18, // 14: hashicorp.consul.internal.protohcl.testproto.NonDynamicWellKnown.empty_val:type_name -> google.protobuf.Empty
|
||||||
|
19, // 15: hashicorp.consul.internal.protohcl.testproto.NonDynamicWellKnown.timestamp_val:type_name -> google.protobuf.Timestamp
|
||||||
|
20, // 16: hashicorp.consul.internal.protohcl.testproto.NonDynamicWellKnown.duration_val:type_name -> google.protobuf.Duration
|
||||||
|
21, // 17: hashicorp.consul.internal.protohcl.testproto.DynamicWellKnown.any_val:type_name -> google.protobuf.Any
|
||||||
|
22, // 18: hashicorp.consul.internal.protohcl.testproto.DynamicWellKnown.struct_val:type_name -> google.protobuf.Struct
|
||||||
|
21, // 19: hashicorp.consul.internal.protohcl.testproto.DynamicWellKnown.any_list:type_name -> google.protobuf.Any
|
||||||
|
1, // 20: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.PrimitivesMapEntry.value:type_name -> hashicorp.consul.internal.protohcl.testproto.Primitives
|
||||||
|
0, // 21: hashicorp.consul.internal.protohcl.testproto.NestedAndCollections.ProtocolMapEntry.value:type_name -> hashicorp.consul.internal.protohcl.testproto.Protocol
|
||||||
|
22, // [22:22] is the sub-list for method output_type
|
||||||
|
22, // [22:22] is the sub-list for method input_type
|
||||||
|
22, // [22:22] is the sub-list for extension type_name
|
||||||
|
22, // [22:22] is the sub-list for extension extendee
|
||||||
|
0, // [0:22] is the sub-list for field type_name
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() { file_example_proto_init() }
|
||||||
|
func file_example_proto_init() {
|
||||||
|
if File_example_proto != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !protoimpl.UnsafeEnabled {
|
||||||
|
file_example_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*Primitives); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_example_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*NestedAndCollections); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_example_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*Wrappers); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_example_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*OneOf); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_example_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*NonDynamicWellKnown); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_example_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*DynamicWellKnown); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_example_proto_msgTypes[3].OneofWrappers = []interface{}{
|
||||||
|
(*OneOf_Int32Val)(nil),
|
||||||
|
(*OneOf_Primitives)(nil),
|
||||||
|
}
|
||||||
|
type x struct{}
|
||||||
|
out := protoimpl.TypeBuilder{
|
||||||
|
File: protoimpl.DescBuilder{
|
||||||
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
|
RawDescriptor: file_example_proto_rawDesc,
|
||||||
|
NumEnums: 1,
|
||||||
|
NumMessages: 8,
|
||||||
|
NumExtensions: 0,
|
||||||
|
NumServices: 0,
|
||||||
|
},
|
||||||
|
GoTypes: file_example_proto_goTypes,
|
||||||
|
DependencyIndexes: file_example_proto_depIdxs,
|
||||||
|
EnumInfos: file_example_proto_enumTypes,
|
||||||
|
MessageInfos: file_example_proto_msgTypes,
|
||||||
|
}.Build()
|
||||||
|
File_example_proto = out.File
|
||||||
|
file_example_proto_rawDesc = nil
|
||||||
|
file_example_proto_goTypes = nil
|
||||||
|
file_example_proto_depIdxs = nil
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package hashicorp.consul.internal.protohcl.testproto;
|
||||||
|
|
||||||
|
import "google/protobuf/duration.proto";
|
||||||
|
import "google/protobuf/empty.proto";
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
import "google/protobuf/wrappers.proto";
|
||||||
|
import "google/protobuf/any.proto";
|
||||||
|
import "google/protobuf/struct.proto";
|
||||||
|
|
||||||
|
message Primitives {
|
||||||
|
double double_val = 1;
|
||||||
|
float float_val = 2;
|
||||||
|
int32 int32_val = 3;
|
||||||
|
int64 int64_val = 4;
|
||||||
|
uint32 uint32_val = 5;
|
||||||
|
uint64 uint64_val = 6;
|
||||||
|
sint32 sint32_val = 7;
|
||||||
|
sint64 sint64_val = 8;
|
||||||
|
fixed32 fixed32_val = 9;
|
||||||
|
fixed64 fixed64_val = 10;
|
||||||
|
sfixed32 sfixed32_val = 11;
|
||||||
|
sfixed64 sfixed64_val = 12;
|
||||||
|
bool bool_val = 13;
|
||||||
|
string string_val = 14;
|
||||||
|
bytes byte_val = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Protocol {
|
||||||
|
PROTOCOL_UNSPECIFIED = 0;
|
||||||
|
PROTOCOL_TCP = 1;
|
||||||
|
PROTOCOL_UDP = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message NestedAndCollections {
|
||||||
|
Primitives primitives = 1;
|
||||||
|
repeated Primitives primitives_list = 2;
|
||||||
|
map<string, Primitives> primitives_map = 3;
|
||||||
|
map<string, Protocol> protocol_map = 4;
|
||||||
|
repeated int32 int_list = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Wrappers {
|
||||||
|
google.protobuf.DoubleValue double_val = 1;
|
||||||
|
google.protobuf.FloatValue float_val = 2;
|
||||||
|
google.protobuf.Int32Value int32_val = 3;
|
||||||
|
google.protobuf.Int64Value int64_val = 4;
|
||||||
|
google.protobuf.UInt32Value uint32_val = 5;
|
||||||
|
google.protobuf.UInt64Value uint64_val = 6;
|
||||||
|
google.protobuf.BoolValue bool_val = 13;
|
||||||
|
google.protobuf.StringValue string_val = 14;
|
||||||
|
google.protobuf.BytesValue bytes_val = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message OneOf {
|
||||||
|
oneof data {
|
||||||
|
int32 int32_val = 1;
|
||||||
|
Primitives primitives = 2;
|
||||||
|
// note repeated fields (including maps) are not allowed in oneofs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message NonDynamicWellKnown {
|
||||||
|
google.protobuf.Empty empty_val = 1;
|
||||||
|
google.protobuf.Timestamp timestamp_val = 2;
|
||||||
|
google.protobuf.Duration duration_val = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DynamicWellKnown {
|
||||||
|
google.protobuf.Any any_val = 1;
|
||||||
|
google.protobuf.Struct struct_val = 2;
|
||||||
|
repeated google.protobuf.Any any_list = 3;
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
package protohcl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/hcl/v2"
|
||||||
|
"github.com/hashicorp/hcl/v2/hclparse"
|
||||||
|
"github.com/zclconf/go-cty/cty/function"
|
||||||
|
"google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// UnmarshalContext provides information about the context in which we are
|
||||||
|
// unmarshalling HCL. It is primarily used for decoding Any fields based on
|
||||||
|
// surrounding information (e.g. the resource Type block).
|
||||||
|
type UnmarshalContext struct {
|
||||||
|
// Parent context.
|
||||||
|
Parent *UnmarshalContext
|
||||||
|
|
||||||
|
// Name of the field that we are unmarshalling.
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// Message is the protobuf message that we are unmarshalling into (may be nil).
|
||||||
|
Message protoreflect.Message
|
||||||
|
|
||||||
|
// Range of where this field was in the HCL source.
|
||||||
|
Range hcl.Range
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorRange returns a range that can be used in error messages.
|
||||||
|
func (ctx *UnmarshalContext) ErrorRange() hcl.Range {
|
||||||
|
for {
|
||||||
|
if !ctx.Range.Empty() || ctx.Parent == nil {
|
||||||
|
return ctx.Range
|
||||||
|
}
|
||||||
|
ctx = ctx.Parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Unmarshal(src []byte, dest protoreflect.ProtoMessage) error {
|
||||||
|
return UnmarshalOptions{}.Unmarshal(src, dest)
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnmarshalOptions struct {
|
||||||
|
AnyTypeProvider AnyTypeProvider
|
||||||
|
SourceFileName string
|
||||||
|
FieldNamer FieldNamer
|
||||||
|
Functions map[string]function.Function
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UnmarshalOptions) Unmarshal(src []byte, dest protoreflect.ProtoMessage) error {
|
||||||
|
rmsg := dest.ProtoReflect()
|
||||||
|
|
||||||
|
file, diags := hclparse.NewParser().ParseHCL(src, u.SourceFileName)
|
||||||
|
|
||||||
|
// error performing basic HCL parsing
|
||||||
|
if diags.HasErrors() {
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
u.clearAll(rmsg)
|
||||||
|
|
||||||
|
if u.FieldNamer == nil {
|
||||||
|
u.FieldNamer = textFieldNamer{}
|
||||||
|
}
|
||||||
|
|
||||||
|
return u.decodeMessage(
|
||||||
|
&UnmarshalContext{Message: rmsg},
|
||||||
|
u.bodyDecoder(file.Body),
|
||||||
|
rmsg,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UnmarshalOptions) bodyDecoder(body hcl.Body) MessageDecoder {
|
||||||
|
return newBodyDecoder(body, u.FieldNamer, u.Functions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UnmarshalOptions) decodeMessage(ctx *UnmarshalContext, decoder MessageDecoder, msg protoreflect.Message) error {
|
||||||
|
desc := msg.Descriptor()
|
||||||
|
|
||||||
|
if desc.FullName() == wellKnownTypeAny {
|
||||||
|
return u.decodeAny(ctx, decoder, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
tracker := newOneOfTracker(u.FieldNamer)
|
||||||
|
|
||||||
|
return decoder.EachField(FieldIterator{
|
||||||
|
Desc: desc,
|
||||||
|
Func: func(field *IterField) error {
|
||||||
|
if err := tracker.markFieldAsSet(field.Desc); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
protoVal protoreflect.Value
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
switch {
|
||||||
|
case field.Val != nil:
|
||||||
|
protoVal, err = u.decodeAttribute(
|
||||||
|
&UnmarshalContext{
|
||||||
|
Parent: ctx,
|
||||||
|
Name: field.Name,
|
||||||
|
Range: field.Range,
|
||||||
|
},
|
||||||
|
func() protoreflect.Value { return msg.NewField(field.Desc) },
|
||||||
|
field.Desc,
|
||||||
|
*field.Val,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
case len(field.Blocks) != 0:
|
||||||
|
protoVal, err = u.decodeBlocks(ctx, field.Blocks, msg, field.Desc)
|
||||||
|
default:
|
||||||
|
panic("decoder yielded no blocks or attributes")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if protoVal.IsValid() {
|
||||||
|
msg.Set(field.Desc, protoVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type newMessageFn func() protoreflect.Value
|
||||||
|
|
||||||
|
func (u UnmarshalOptions) clearAll(msg protoreflect.Message) {
|
||||||
|
fields := msg.Descriptor().Fields()
|
||||||
|
|
||||||
|
for i := 0; i < fields.Len(); i++ {
|
||||||
|
msg.Clear(fields.Get(i))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,557 @@
|
||||||
|
package protohcl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
"github.com/zclconf/go-cty/cty/function"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
"google.golang.org/protobuf/types/known/anypb"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/internal/protohcl/testproto"
|
||||||
|
"github.com/hashicorp/hcl/v2/hclparse"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPrimitives(t *testing.T) {
|
||||||
|
hcl := `
|
||||||
|
double_val = 1.234
|
||||||
|
float_val = 2.345
|
||||||
|
int32_val = 536870912
|
||||||
|
int64_val = 25769803776
|
||||||
|
uint32_val = 2148532224
|
||||||
|
uint64_val = 9223372041149743104
|
||||||
|
sint32_val = 536870912
|
||||||
|
sint64_val = 25769803776
|
||||||
|
fixed32_val = 2148532224
|
||||||
|
fixed64_val = 9223372041149743104
|
||||||
|
sfixed32_val = 536870912
|
||||||
|
sfixed64_val = 25769803776
|
||||||
|
bool_val = true
|
||||||
|
string_val = "foo"
|
||||||
|
// This is base64 encoded "bar"
|
||||||
|
byte_val = "YmFy"
|
||||||
|
`
|
||||||
|
|
||||||
|
var out testproto.Primitives
|
||||||
|
|
||||||
|
err := Unmarshal([]byte(hcl), &out)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, out.DoubleVal, float64(1.234))
|
||||||
|
require.Equal(t, out.FloatVal, float32(2.345))
|
||||||
|
require.Equal(t, out.Int32Val, int32(536870912))
|
||||||
|
require.Equal(t, out.Int64Val, int64(25769803776))
|
||||||
|
require.Equal(t, out.Uint32Val, uint32(2148532224))
|
||||||
|
require.Equal(t, out.Uint64Val, uint64(9223372041149743104))
|
||||||
|
require.Equal(t, out.Sint32Val, int32(536870912))
|
||||||
|
require.Equal(t, out.Sint64Val, int64(25769803776))
|
||||||
|
require.Equal(t, out.Fixed32Val, uint32(2148532224))
|
||||||
|
require.Equal(t, out.Fixed64Val, uint64(9223372041149743104))
|
||||||
|
require.Equal(t, out.Sfixed32Val, int32(536870912))
|
||||||
|
require.Equal(t, out.Sfixed64Val, int64(25769803776))
|
||||||
|
require.Equal(t, out.BoolVal, true)
|
||||||
|
require.Equal(t, out.StringVal, "foo")
|
||||||
|
require.Equal(t, out.ByteVal, []byte("bar"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNestedAndCollections(t *testing.T) {
|
||||||
|
hcl := `
|
||||||
|
primitives {
|
||||||
|
uint32_val = 42
|
||||||
|
}
|
||||||
|
|
||||||
|
primitives_map "foo" {
|
||||||
|
uint32_val = 42
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol_map = {
|
||||||
|
"foo" = "PROTOCOL_TCP"
|
||||||
|
}
|
||||||
|
|
||||||
|
primitives_list {
|
||||||
|
uint32_val = 42
|
||||||
|
}
|
||||||
|
|
||||||
|
primitives_list {
|
||||||
|
uint32_val = 56
|
||||||
|
}
|
||||||
|
|
||||||
|
int_list = [
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
]
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
var out testproto.NestedAndCollections
|
||||||
|
|
||||||
|
err := Unmarshal([]byte(hcl), &out)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.NotNil(t, out.Primitives)
|
||||||
|
require.Equal(t, out.Primitives.Uint32Val, uint32(42))
|
||||||
|
require.NotNil(t, out.PrimitivesMap)
|
||||||
|
require.Equal(t, out.PrimitivesMap["foo"].Uint32Val, uint32(42))
|
||||||
|
require.NotNil(t, out.ProtocolMap)
|
||||||
|
require.Equal(t, out.ProtocolMap["foo"], testproto.Protocol_PROTOCOL_TCP)
|
||||||
|
require.Len(t, out.PrimitivesList, 2)
|
||||||
|
require.Equal(t, out.PrimitivesList[0].Uint32Val, uint32(42))
|
||||||
|
require.Equal(t, out.PrimitivesList[1].Uint32Val, uint32(56))
|
||||||
|
require.Len(t, out.IntList, 2)
|
||||||
|
require.Equal(t, out.IntList[1], int32(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPrimitiveWrappers(t *testing.T) {
|
||||||
|
hcl := `
|
||||||
|
double_val = 1.234
|
||||||
|
float_val = 2.345
|
||||||
|
int32_val = 536870912
|
||||||
|
int64_val = 25769803776
|
||||||
|
uint32_val = 2148532224
|
||||||
|
uint64_val = 9223372041149743104
|
||||||
|
bool_val = true
|
||||||
|
string_val = "foo"
|
||||||
|
// This is base64 encoded "bar"
|
||||||
|
bytes_val = "YmFy"
|
||||||
|
`
|
||||||
|
var out testproto.Wrappers
|
||||||
|
|
||||||
|
err := Unmarshal([]byte(hcl), &out)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, out.DoubleVal.Value, float64(1.234))
|
||||||
|
require.Equal(t, out.FloatVal.Value, float32(2.345))
|
||||||
|
require.Equal(t, out.Int32Val.Value, int32(536870912))
|
||||||
|
require.Equal(t, out.Int64Val.Value, int64(25769803776))
|
||||||
|
require.Equal(t, out.Uint32Val.Value, uint32(2148532224))
|
||||||
|
require.Equal(t, out.Uint64Val.Value, uint64(9223372041149743104))
|
||||||
|
require.Equal(t, out.BoolVal.Value, true)
|
||||||
|
require.Equal(t, out.StringVal.Value, "foo")
|
||||||
|
require.Equal(t, out.BytesVal.Value, []byte("bar"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNonDynamicWellKnown(t *testing.T) {
|
||||||
|
hcl := `
|
||||||
|
empty_val = {}
|
||||||
|
timestamp_val = "2023-02-27T12:34:56.789Z"
|
||||||
|
duration_val = "12s"
|
||||||
|
`
|
||||||
|
var out testproto.NonDynamicWellKnown
|
||||||
|
|
||||||
|
err := Unmarshal([]byte(hcl), &out)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, out.EmptyVal)
|
||||||
|
require.NotNil(t, out.TimestampVal)
|
||||||
|
require.Equal(t, out.TimestampVal.AsTime(), time.Date(2023, 2, 27, 12, 34, 56, 789000000, time.UTC))
|
||||||
|
require.NotNil(t, out.DurationVal)
|
||||||
|
require.Equal(t, out.DurationVal.AsDuration(), time.Second*12)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInvalidTimestamp(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("too slow for testing.Short")
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
cases := map[string]struct {
|
||||||
|
hcl string
|
||||||
|
expectXDS bool
|
||||||
|
}{
|
||||||
|
"invalid": {
|
||||||
|
hcl: `
|
||||||
|
timestamp_val = "Sat Jun 12 2023 14:59:57 GMT+0200"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"range error": {
|
||||||
|
hcl: `
|
||||||
|
timestamp_val = "2023-02-27T25:34:56.789Z"
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, tc := range cases {
|
||||||
|
tc := tc
|
||||||
|
var out testproto.NonDynamicWellKnown
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
|
||||||
|
err := Unmarshal([]byte(tc.hcl), &out)
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Nil(t, out.TimestampVal)
|
||||||
|
require.ErrorContains(t, err, "error parsing timestamp")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInvalidDuration(t *testing.T) {
|
||||||
|
hcl := `
|
||||||
|
duration_val = "abc"
|
||||||
|
`
|
||||||
|
var out testproto.NonDynamicWellKnown
|
||||||
|
|
||||||
|
err := Unmarshal([]byte(hcl), &out)
|
||||||
|
require.ErrorContains(t, err, "error parsing string duration:")
|
||||||
|
require.Nil(t, out.DurationVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOneOf(t *testing.T) {
|
||||||
|
hcl1 := `
|
||||||
|
int32_val = 3
|
||||||
|
`
|
||||||
|
|
||||||
|
hcl2 := `
|
||||||
|
primitives {
|
||||||
|
int32_val = 3
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
hcl3 := `
|
||||||
|
int32_val = 3
|
||||||
|
primitives {
|
||||||
|
int32_val = 4
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
var out testproto.OneOf
|
||||||
|
|
||||||
|
err := Unmarshal([]byte(hcl1), &out)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, out.GetInt32Val(), int32(3))
|
||||||
|
|
||||||
|
err = Unmarshal([]byte(hcl2), &out)
|
||||||
|
require.NoError(t, err)
|
||||||
|
primitives := out.GetPrimitives()
|
||||||
|
require.NotNil(t, primitives)
|
||||||
|
require.Equal(t, primitives.Int32Val, int32(3))
|
||||||
|
|
||||||
|
err = Unmarshal([]byte(hcl3), &out)
|
||||||
|
require.Error(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAny(t *testing.T) {
|
||||||
|
hcl := `
|
||||||
|
any_val {
|
||||||
|
type_url = "hashicorp.consul.internal.protohcl.testproto.Primitives"
|
||||||
|
uint32_val = 42
|
||||||
|
}
|
||||||
|
|
||||||
|
any_list = [
|
||||||
|
{
|
||||||
|
type_url = "hashicorp.consul.internal.protohcl.testproto.Primitives"
|
||||||
|
uint32_val = 123
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type_url = "hashicorp.consul.internal.protohcl.testproto.Wrappers"
|
||||||
|
uint32_val = 321
|
||||||
|
}
|
||||||
|
]
|
||||||
|
`
|
||||||
|
var out testproto.DynamicWellKnown
|
||||||
|
|
||||||
|
err := Unmarshal([]byte(hcl), &out)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, out.AnyVal)
|
||||||
|
require.Equal(t, out.AnyVal.TypeUrl, "hashicorp.consul.internal.protohcl.testproto.Primitives")
|
||||||
|
|
||||||
|
raw, err := anypb.UnmarshalNew(out.AnyVal, proto.UnmarshalOptions{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, raw)
|
||||||
|
|
||||||
|
primitives, ok := raw.(*testproto.Primitives)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Equal(t, primitives.Uint32Val, uint32(42))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAnyTypeDynamicWellKnown(t *testing.T) {
|
||||||
|
hcl := `
|
||||||
|
any_val {
|
||||||
|
type_url = "hashicorp.consul.internal.protohcl.testproto.DynamicWellKnown"
|
||||||
|
any_val {
|
||||||
|
type_url = "hashicorp.consul.internal.protohcl.testproto.Primitives"
|
||||||
|
uint32_val = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
var out testproto.DynamicWellKnown
|
||||||
|
|
||||||
|
err := Unmarshal([]byte(hcl), &out)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, out.AnyVal)
|
||||||
|
require.Equal(t, out.AnyVal.TypeUrl, "hashicorp.consul.internal.protohcl.testproto.DynamicWellKnown")
|
||||||
|
|
||||||
|
raw, err := anypb.UnmarshalNew(out.AnyVal, proto.UnmarshalOptions{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, raw)
|
||||||
|
|
||||||
|
anyVal, ok := raw.(*testproto.DynamicWellKnown)
|
||||||
|
require.True(t, ok)
|
||||||
|
|
||||||
|
res, err := anypb.UnmarshalNew(anyVal.AnyVal, proto.UnmarshalOptions{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, res)
|
||||||
|
|
||||||
|
primitives, ok := res.(*testproto.Primitives)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.Equal(t, primitives.Uint32Val, uint32(42))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAnyTypeNestedAndCollections(t *testing.T) {
|
||||||
|
hcl := `
|
||||||
|
any_val {
|
||||||
|
type_url = "hashicorp.consul.internal.protohcl.testproto.NestedAndCollections"
|
||||||
|
primitives {
|
||||||
|
uint32_val = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
var out testproto.DynamicWellKnown
|
||||||
|
|
||||||
|
err := Unmarshal([]byte(hcl), &out)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, out.AnyVal)
|
||||||
|
require.Equal(t, out.AnyVal.TypeUrl, "hashicorp.consul.internal.protohcl.testproto.NestedAndCollections")
|
||||||
|
|
||||||
|
raw, err := anypb.UnmarshalNew(out.AnyVal, proto.UnmarshalOptions{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, raw)
|
||||||
|
|
||||||
|
nestedCollections, ok := raw.(*testproto.NestedAndCollections)
|
||||||
|
require.True(t, ok)
|
||||||
|
require.NotNil(t, nestedCollections.Primitives)
|
||||||
|
require.Equal(t, nestedCollections.Primitives.Uint32Val, uint32(42))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAnyTypeErrors(t *testing.T) {
|
||||||
|
type testCase struct {
|
||||||
|
description string
|
||||||
|
hcl string
|
||||||
|
error string
|
||||||
|
}
|
||||||
|
testCases := []testCase{
|
||||||
|
{
|
||||||
|
description: "type_url is expected",
|
||||||
|
hcl: `
|
||||||
|
any_val {
|
||||||
|
uint32_val = 42
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
error: "type_url field is required to decode Any",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "type_url is unknown",
|
||||||
|
hcl: `
|
||||||
|
any_val {
|
||||||
|
type_url = "hashicorp.consul.internal.protohcl.testproto.Integer"
|
||||||
|
uint32_val = 42
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
error: "error looking up type information for hashicorp.consul.internal.protohcl.testproto.Integer",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: "unknown field",
|
||||||
|
hcl: `
|
||||||
|
any_val {
|
||||||
|
type_url = "hashicorp.consul.internal.protohcl.testproto.Primitives"
|
||||||
|
int_val = 42
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
error: "Unsupported argument; An argument named \"int_val\" is not expected here",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
tc := tc
|
||||||
|
t.Run(tc.description, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
var out testproto.DynamicWellKnown
|
||||||
|
|
||||||
|
err := Unmarshal([]byte(tc.hcl), &out)
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Contains(t, err.Error(), tc.error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStruct(t *testing.T) {
|
||||||
|
hcl := `
|
||||||
|
struct_val = {
|
||||||
|
"null"= null
|
||||||
|
"bool"= true
|
||||||
|
"foo" = "bar"
|
||||||
|
"baz" = 1.234
|
||||||
|
"nested" = {
|
||||||
|
"foo" = 12,
|
||||||
|
"bar" = "something"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
var out testproto.DynamicWellKnown
|
||||||
|
|
||||||
|
err := Unmarshal([]byte(hcl), &out)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, out.StructVal)
|
||||||
|
|
||||||
|
valMap := out.StructVal.AsMap()
|
||||||
|
jsonVal, err := json.Marshal(valMap)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
expected := `{
|
||||||
|
"null": null,
|
||||||
|
"bool": true,
|
||||||
|
"foo": "bar",
|
||||||
|
"baz": 1.234,
|
||||||
|
"nested": {
|
||||||
|
"foo": 12,
|
||||||
|
"bar": "something"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
require.JSONEq(t, expected, string(jsonVal))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStructList(t *testing.T) {
|
||||||
|
hcl := `
|
||||||
|
struct_val = {
|
||||||
|
"list_int" = [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
]
|
||||||
|
"list_string": [
|
||||||
|
"abc",
|
||||||
|
"def"
|
||||||
|
]
|
||||||
|
"list_bool": [
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
"list_maps" = [
|
||||||
|
{
|
||||||
|
"arrr" = "matey"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hoist" = "the colors"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
"list_list" = [
|
||||||
|
[
|
||||||
|
"hello",
|
||||||
|
"world",
|
||||||
|
null
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
var out testproto.DynamicWellKnown
|
||||||
|
|
||||||
|
err := Unmarshal([]byte(hcl), &out)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, out.StructVal)
|
||||||
|
|
||||||
|
valMap := out.StructVal.AsMap()
|
||||||
|
jsonVal, err := json.Marshal(valMap)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
expected := `{
|
||||||
|
"list_int": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3
|
||||||
|
],
|
||||||
|
"list_string": [
|
||||||
|
"abc",
|
||||||
|
"def"
|
||||||
|
],
|
||||||
|
"list_bool": [
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
],
|
||||||
|
"list_maps": [
|
||||||
|
{
|
||||||
|
"arrr": "matey"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hoist": "the colors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"list_list": [
|
||||||
|
[
|
||||||
|
"hello",
|
||||||
|
"world",
|
||||||
|
null
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
`
|
||||||
|
require.JSONEq(t, expected, string(jsonVal))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFunctionExecution(t *testing.T) {
|
||||||
|
hcl := `
|
||||||
|
primitives = primitive_defaults()
|
||||||
|
`
|
||||||
|
|
||||||
|
var out testproto.NestedAndCollections
|
||||||
|
|
||||||
|
var (
|
||||||
|
testType = cty.Capsule("type", reflect.TypeOf(testproto.Primitives{}))
|
||||||
|
|
||||||
|
test = function.New(&function.Spec{
|
||||||
|
Params: []function.Parameter{},
|
||||||
|
Type: function.StaticReturnType(testType),
|
||||||
|
Impl: func(args []cty.Value, _ cty.Type) (cty.Value, error) {
|
||||||
|
t := &testproto.Primitives{
|
||||||
|
StringVal: "test",
|
||||||
|
Int32Val: 10,
|
||||||
|
BoolVal: false,
|
||||||
|
}
|
||||||
|
return cty.CapsuleVal(testType, t), nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
err := UnmarshalOptions{
|
||||||
|
Functions: map[string]function.Function{"primitive_defaults": test},
|
||||||
|
}.Unmarshal([]byte(hcl), &out)
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.NotNil(t, out.Primitives)
|
||||||
|
require.Equal(t, out.Primitives.StringVal, "test")
|
||||||
|
require.Equal(t, out.Primitives.Int32Val, int32(10))
|
||||||
|
require.Equal(t, out.Primitives.BoolVal, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSkipFields(t *testing.T) {
|
||||||
|
|
||||||
|
u := UnmarshalOptions{}
|
||||||
|
|
||||||
|
hcl := `
|
||||||
|
any_val {
|
||||||
|
type_url = "hashicorp.consul.internal.protohcl.testproto.Primitives"
|
||||||
|
uint32_val = 10
|
||||||
|
}`
|
||||||
|
|
||||||
|
file, diags := hclparse.NewParser().ParseHCL([]byte(hcl), "")
|
||||||
|
|
||||||
|
require.False(t, diags.HasErrors())
|
||||||
|
|
||||||
|
decoder := u.bodyDecoder(file.Body)
|
||||||
|
|
||||||
|
decoder = decoder.SkipFields("type_url")
|
||||||
|
|
||||||
|
decoder = decoder.SkipFields("type_url", "uint32_val")
|
||||||
|
|
||||||
|
expected := map[string]struct{}{
|
||||||
|
"type_url": {},
|
||||||
|
"uint32_val": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Contains(t, fmt.Sprintf("%v", decoder), fmt.Sprintf("%v", expected))
|
||||||
|
}
|
|
@ -0,0 +1,418 @@
|
||||||
|
package protohcl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
"google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
"google.golang.org/protobuf/types/known/durationpb"
|
||||||
|
"google.golang.org/protobuf/types/known/emptypb"
|
||||||
|
"google.golang.org/protobuf/types/known/structpb"
|
||||||
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// maximum time in seconds that a time.Time which comes from
|
||||||
|
// an RFC 3339 timestamp can represent
|
||||||
|
maxTimestampSeconds = 253402300799
|
||||||
|
// minimum time in seconds that a time.Time which comes from
|
||||||
|
// an RFC 3339 timestamp can represent. This is negative
|
||||||
|
// because RFC 3339 base time is year 0001 whereas time.Time
|
||||||
|
// starts in 1970
|
||||||
|
minTimestampSeconds = -62135596800
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// minTime is the earliest time representable as both an
|
||||||
|
// RFC 3339 timestamp and a time.Time value
|
||||||
|
minTime = time.Unix(minTimestampSeconds, 0)
|
||||||
|
// maxTime is the latest time respresentable as both an
|
||||||
|
// RFC 3339 timestamp and a time.Time value
|
||||||
|
maxTime = time.Unix(maxTimestampSeconds, 999999999)
|
||||||
|
)
|
||||||
|
|
||||||
|
type wktSchemaHint int
|
||||||
|
|
||||||
|
const (
|
||||||
|
notWellKnownType wktSchemaHint = iota
|
||||||
|
wellKnownBlock
|
||||||
|
wellKnownAttribute
|
||||||
|
)
|
||||||
|
|
||||||
|
// wellKnownTypeSchemaHint returns what sort of syntax should be used to represent
|
||||||
|
// the well known type field.
|
||||||
|
//
|
||||||
|
// NotWellKnownType - use attribute block syntax based on other information
|
||||||
|
// WellKnownAttribute - use attribute syntax
|
||||||
|
// WellKnownBlock - use block syntax
|
||||||
|
func wellKnownTypeSchemaHint(desc protoreflect.FieldDescriptor) wktSchemaHint {
|
||||||
|
if desc.Kind() != protoreflect.MessageKind {
|
||||||
|
return notWellKnownType
|
||||||
|
}
|
||||||
|
|
||||||
|
switch desc.Message().FullName() {
|
||||||
|
case "google.protobuf.DoubleValue":
|
||||||
|
return wellKnownAttribute
|
||||||
|
case "google.protobuf.FloatValue":
|
||||||
|
return wellKnownAttribute
|
||||||
|
case "google.protobuf.Int32Value":
|
||||||
|
return wellKnownAttribute
|
||||||
|
case "google.protobuf.Int64Value":
|
||||||
|
return wellKnownAttribute
|
||||||
|
case "google.protobuf.UInt32Value":
|
||||||
|
return wellKnownAttribute
|
||||||
|
case "google.protobuf.UInt64Value":
|
||||||
|
return wellKnownAttribute
|
||||||
|
case "google.protobuf.BoolValue":
|
||||||
|
return wellKnownAttribute
|
||||||
|
case "google.protobuf.StringValue":
|
||||||
|
return wellKnownAttribute
|
||||||
|
case "google.protobuf.BytesValue":
|
||||||
|
return wellKnownAttribute
|
||||||
|
case "google.protobuf.Empty":
|
||||||
|
// block syntax is used for Empty to allow transitioning to using
|
||||||
|
// a different proto message with fields in the future.
|
||||||
|
return wellKnownBlock
|
||||||
|
case "google.protobuf.Timestamp":
|
||||||
|
return wellKnownAttribute
|
||||||
|
case "google.protobuf.Duration":
|
||||||
|
return wellKnownAttribute
|
||||||
|
case "google.protobuf.Struct":
|
||||||
|
// as the Struct has completely free form fields that we cannot
|
||||||
|
// know about in advance we cannot use block syntax
|
||||||
|
return wellKnownAttribute
|
||||||
|
case "google.protobuf.Any":
|
||||||
|
return wellKnownBlock
|
||||||
|
default:
|
||||||
|
return notWellKnownType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeAttributeToWellKnownType(desc protoreflect.FieldDescriptor, val cty.Value) (bool, protoreflect.Value, error) {
|
||||||
|
if desc.Kind() != protoreflect.MessageKind {
|
||||||
|
return false, protoreflect.Value{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch desc.Message().FullName() {
|
||||||
|
case "google.protobuf.DoubleValue":
|
||||||
|
protoVal, err := protoDoubleWrapperFromCty(val)
|
||||||
|
return true, protoVal, err
|
||||||
|
case "google.protobuf.FloatValue":
|
||||||
|
protoVal, err := protoFloatWrapperFromCty(val)
|
||||||
|
return true, protoVal, err
|
||||||
|
case "google.protobuf.Int32Value":
|
||||||
|
protoVal, err := protoInt32WrapperFromCty(val)
|
||||||
|
return true, protoVal, err
|
||||||
|
case "google.protobuf.Int64Value":
|
||||||
|
protoVal, err := protoInt64WrapperFromCty(val)
|
||||||
|
return true, protoVal, err
|
||||||
|
case "google.protobuf.UInt32Value":
|
||||||
|
protoVal, err := protoUint32WrapperFromCty(val)
|
||||||
|
return true, protoVal, err
|
||||||
|
case "google.protobuf.UInt64Value":
|
||||||
|
protoVal, err := protoUint64WrapperFromCty(val)
|
||||||
|
return true, protoVal, err
|
||||||
|
case "google.protobuf.BoolValue":
|
||||||
|
protoVal, err := protoBoolWrapperFromCty(val)
|
||||||
|
return true, protoVal, err
|
||||||
|
case "google.protobuf.StringValue":
|
||||||
|
protoVal, err := protoStringWrapperFromCty(val)
|
||||||
|
return true, protoVal, err
|
||||||
|
case "google.protobuf.BytesValue":
|
||||||
|
protoVal, err := protoBytesWrapperFromCty(val)
|
||||||
|
return true, protoVal, err
|
||||||
|
case "google.protobuf.Empty":
|
||||||
|
protoVal, err := protoEmptyFromCty(val)
|
||||||
|
return true, protoVal, err
|
||||||
|
case "google.protobuf.Timestamp":
|
||||||
|
protoVal, err := protoTimestampFromCty(val)
|
||||||
|
return true, protoVal, err
|
||||||
|
case "google.protobuf.Duration":
|
||||||
|
protoVal, err := protoDurationFromCty(val)
|
||||||
|
return true, protoVal, err
|
||||||
|
case "google.protobuf.Struct":
|
||||||
|
protoVal, err := protoStructFromCty(val)
|
||||||
|
return true, protoVal, err
|
||||||
|
default:
|
||||||
|
return false, protoreflect.Value{}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoWrapperFromBool(v bool) protoreflect.Value {
|
||||||
|
return protoreflect.ValueOfMessage(wrapperspb.Bool(v).ProtoReflect())
|
||||||
|
}
|
||||||
|
func protoWrapperFromInt32(v int32) protoreflect.Value {
|
||||||
|
return protoreflect.ValueOfMessage(wrapperspb.Int32(v).ProtoReflect())
|
||||||
|
}
|
||||||
|
func protoWrapperFromInt64(v int64) protoreflect.Value {
|
||||||
|
return protoreflect.ValueOfMessage(wrapperspb.Int64(v).ProtoReflect())
|
||||||
|
}
|
||||||
|
func protoWrapperFromUint32(v uint32) protoreflect.Value {
|
||||||
|
return protoreflect.ValueOfMessage(wrapperspb.UInt32(v).ProtoReflect())
|
||||||
|
}
|
||||||
|
func protoWrapperFromUint64(v uint64) protoreflect.Value {
|
||||||
|
return protoreflect.ValueOfMessage(wrapperspb.UInt64(v).ProtoReflect())
|
||||||
|
}
|
||||||
|
func protoWrapperFromFloat(v float32) protoreflect.Value {
|
||||||
|
return protoreflect.ValueOfMessage(wrapperspb.Float(v).ProtoReflect())
|
||||||
|
}
|
||||||
|
func protoWrapperFromDouble(v float64) protoreflect.Value {
|
||||||
|
return protoreflect.ValueOfMessage(wrapperspb.Double(v).ProtoReflect())
|
||||||
|
}
|
||||||
|
func protoWrapperFromString(v string) protoreflect.Value {
|
||||||
|
return protoreflect.ValueOfMessage(wrapperspb.String(v).ProtoReflect())
|
||||||
|
}
|
||||||
|
func protoWrapperFromBytes(v []byte) protoreflect.Value {
|
||||||
|
return protoreflect.ValueOfMessage(wrapperspb.Bytes(v).ProtoReflect())
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoBoolWrapperFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
v, err := boolFromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoWrapperFromBool(v), nil
|
||||||
|
}
|
||||||
|
func protoInt32WrapperFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
v, err := int32FromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoWrapperFromInt32(v), nil
|
||||||
|
}
|
||||||
|
func protoInt64WrapperFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
v, err := int64FromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoWrapperFromInt64(v), nil
|
||||||
|
}
|
||||||
|
func protoUint32WrapperFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
v, err := uint32FromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoWrapperFromUint32(v), nil
|
||||||
|
}
|
||||||
|
func protoUint64WrapperFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
v, err := uint64FromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoWrapperFromUint64(v), nil
|
||||||
|
}
|
||||||
|
func protoFloatWrapperFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
v, err := floatFromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoWrapperFromFloat(v), nil
|
||||||
|
}
|
||||||
|
func protoDoubleWrapperFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
v, err := doubleFromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoWrapperFromDouble(v), nil
|
||||||
|
}
|
||||||
|
func protoStringWrapperFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
v, err := stringFromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoWrapperFromString(v), nil
|
||||||
|
}
|
||||||
|
func protoBytesWrapperFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
v, err := bytesFromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
return protoWrapperFromBytes(v), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoEmptyFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
var e emptypb.Empty
|
||||||
|
if val.IsNull() {
|
||||||
|
return protoreflect.Value{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
valType := val.Type()
|
||||||
|
if (valType.IsObjectType() || valType.IsMapType()) && val.LengthInt() == 0 {
|
||||||
|
return protoreflect.ValueOfMessage(e.ProtoReflect()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return protoreflect.Value{}, fmt.Errorf("well known empty type can only be represented as an hcl map/object - actual type %q", valType.FriendlyName())
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoTimestampFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
v, err := stringFromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
t, err := time.Parse(time.RFC3339Nano, v)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, fmt.Errorf("error parsing timestamp: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.Before(minTime) || t.After(maxTime) {
|
||||||
|
return protoreflect.Value{}, fmt.Errorf("time is out of range %s to %s - %s", minTime.String(), maxTime.String(), v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return protoreflect.ValueOfMessage(timestamppb.New(t).ProtoReflect()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoDurationFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
v, err := stringFromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
d, err := time.ParseDuration(v)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, fmt.Errorf("error parsing string duration: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return protoreflect.ValueOfMessage(durationpb.New(d).ProtoReflect()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoStructFromCty(val cty.Value) (protoreflect.Value, error) {
|
||||||
|
s, err := protoStructObjectFromCty(val)
|
||||||
|
if err != nil {
|
||||||
|
return protoreflect.Value{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return protoreflect.ValueOfMessage(s.ProtoReflect()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoStructObjectFromCty(val cty.Value) (*structpb.Struct, error) {
|
||||||
|
valType := val.Type()
|
||||||
|
if !valType.IsObjectType() && !valType.IsMapType() {
|
||||||
|
return nil, fmt.Errorf("Struct type must be either an object or map type")
|
||||||
|
}
|
||||||
|
|
||||||
|
structValues := make(map[string]*structpb.Value)
|
||||||
|
|
||||||
|
for k, v := range val.AsValueMap() {
|
||||||
|
vType := v.Type()
|
||||||
|
|
||||||
|
if v.IsNull() {
|
||||||
|
structValues[k] = structpb.NewNullValue()
|
||||||
|
} else if vType.IsListType() || vType.IsSetType() || vType.IsTupleType() {
|
||||||
|
listVal, err := protoStructListValueFromCty(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
structValues[k] = structpb.NewListValue(listVal)
|
||||||
|
} else if vType.IsMapType() || vType.IsObjectType() {
|
||||||
|
objVal, err := protoStructObjectFromCty(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
structValues[k] = structpb.NewStructValue(objVal)
|
||||||
|
} else if vType.IsPrimitiveType() {
|
||||||
|
switch vType {
|
||||||
|
case cty.String:
|
||||||
|
stringVal, err := stringFromCty(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
structValues[k] = structpb.NewStringValue(stringVal)
|
||||||
|
case cty.Bool:
|
||||||
|
boolVal, err := boolFromCty(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
structValues[k] = structpb.NewBoolValue(boolVal)
|
||||||
|
case cty.Number:
|
||||||
|
doubleVal, err := doubleFromCty(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
structValues[k] = structpb.NewNumberValue(doubleVal)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown cty primitive type: %s", vType.FriendlyName())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, fmt.Errorf("unsupported cty type: %s", vType.FriendlyName())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &structpb.Struct{
|
||||||
|
Fields: structValues,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func protoStructListValueFromCty(val cty.Value) (*structpb.ListValue, error) {
|
||||||
|
var values []*structpb.Value
|
||||||
|
|
||||||
|
var err error
|
||||||
|
val.ForEachElement(func(_ cty.Value, value cty.Value) bool {
|
||||||
|
vType := value.Type()
|
||||||
|
|
||||||
|
if value.IsNull() {
|
||||||
|
values = append(values, structpb.NewNullValue())
|
||||||
|
} else if vType.IsListType() || vType.IsSetType() || vType.IsTupleType() {
|
||||||
|
var listVal *structpb.ListValue
|
||||||
|
listVal, err = protoStructListValueFromCty(value)
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
values = append(values, structpb.NewListValue(listVal))
|
||||||
|
} else if vType.IsMapType() || vType.IsObjectType() {
|
||||||
|
var objVal *structpb.Struct
|
||||||
|
objVal, err = protoStructObjectFromCty(value)
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
values = append(values, structpb.NewStructValue(objVal))
|
||||||
|
} else if vType.IsPrimitiveType() {
|
||||||
|
switch vType {
|
||||||
|
case cty.String:
|
||||||
|
var stringVal string
|
||||||
|
stringVal, err = stringFromCty(value)
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
values = append(values, structpb.NewStringValue(stringVal))
|
||||||
|
case cty.Bool:
|
||||||
|
var boolVal bool
|
||||||
|
boolVal, err = boolFromCty(value)
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
values = append(values, structpb.NewBoolValue(boolVal))
|
||||||
|
case cty.Number:
|
||||||
|
var doubleVal float64
|
||||||
|
doubleVal, err = doubleFromCty(value)
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
values = append(values, structpb.NewNumberValue(doubleVal))
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("unknown cty primitive type: %s", vType.FriendlyName())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("unsupported cty type: %s", vType.FriendlyName())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &structpb.ListValue{
|
||||||
|
Values: values,
|
||||||
|
}, nil
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ package resource
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
|
@ -171,3 +172,15 @@ func (r *TypeRegistry) Types() []Registration {
|
||||||
func ToGVK(resourceType *pbresource.Type) string {
|
func ToGVK(resourceType *pbresource.Type) string {
|
||||||
return fmt.Sprintf("%s.%s.%s", resourceType.Group, resourceType.GroupVersion, resourceType.Kind)
|
return fmt.Sprintf("%s.%s.%s", resourceType.Group, resourceType.GroupVersion, resourceType.Kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ParseGVK(gvk string) (*pbresource.Type, error) {
|
||||||
|
parts := strings.Split(gvk, ".")
|
||||||
|
if len(parts) != 3 {
|
||||||
|
return nil, fmt.Errorf("GVK string must be in the form <Group>.<GroupVersion>.<Kind>, got: %s", gvk)
|
||||||
|
}
|
||||||
|
return &pbresource.Type{
|
||||||
|
Group: parts[0],
|
||||||
|
GroupVersion: parts[1],
|
||||||
|
Kind: parts[2],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package resourcehcl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/internal/protohcl"
|
||||||
|
"github.com/hashicorp/consul/internal/resource"
|
||||||
|
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||||
|
)
|
||||||
|
|
||||||
|
// anyProvider implements protohcl.AnyTypeProvider to infer the `Data` block
|
||||||
|
// type from `ID.Type`.
|
||||||
|
type anyProvider struct {
|
||||||
|
base protohcl.AnyTypeProvider
|
||||||
|
reg resource.Registry
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p anyProvider) AnyType(ctx *protohcl.UnmarshalContext, decoder protohcl.MessageDecoder) (protoreflect.FullName, protohcl.MessageDecoder, error) {
|
||||||
|
if ctx.Name != "Data" {
|
||||||
|
return p.base.AnyType(ctx, decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctx.Parent == nil || ctx.Parent.Message == nil {
|
||||||
|
return p.base.AnyType(ctx, decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, isResource := ctx.Parent.Message.Interface().(*pbresource.Resource)
|
||||||
|
if !isResource {
|
||||||
|
return p.base.AnyType(ctx, decoder)
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceType := res.GetId().GetType()
|
||||||
|
if res == nil {
|
||||||
|
return "", nil, errors.New("ID.Type not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
reg, ok := p.reg.Resolve(resourceType)
|
||||||
|
if !ok {
|
||||||
|
return "", nil, fmt.Errorf("unknown resource type: %s", resource.ToGVK(resourceType))
|
||||||
|
}
|
||||||
|
|
||||||
|
return reg.Proto.ProtoReflect().Descriptor().FullName(), decoder, nil
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package resourcehcl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
// fieldNamer implements protohcl.FieldNamer to name fields using PascalCase
|
||||||
|
// with support for acroynms (e.g. ID, TCP).
|
||||||
|
type fieldNamer struct{ acroynms []string }
|
||||||
|
|
||||||
|
func (n fieldNamer) NameField(fd protoreflect.FieldDescriptor) string {
|
||||||
|
camel := fd.JSONName()
|
||||||
|
upper := strings.ToUpper(camel)
|
||||||
|
|
||||||
|
for _, a := range n.acroynms {
|
||||||
|
if upper == a {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.ToUpper(camel[:1]) + camel[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n fieldNamer) GetField(fds protoreflect.FieldDescriptors, name string) protoreflect.FieldDescriptor {
|
||||||
|
for _, a := range n.acroynms {
|
||||||
|
if name == a {
|
||||||
|
return fds.ByJSONName(strings.ToLower(a))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
camel := strings.ToLower(name[:1]) + name[1:]
|
||||||
|
return fds.ByJSONName(camel)
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
gvk-no-arguments.hcl:2,14-15: Not enough function arguments; Function "gvk" expects 1 argument(s). Missing value for "GVK String".
|
|
@ -0,0 +1,4 @@
|
||||||
|
ID {
|
||||||
|
Type = gvk()
|
||||||
|
Name = "foo"
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
invalid-group.hcl:3,13-17: Failed to unmarshal argument Group: expected value of type string but actual type is number
|
|
@ -0,0 +1,8 @@
|
||||||
|
ID {
|
||||||
|
Type {
|
||||||
|
Group = 1234
|
||||||
|
GroupVersion = "v1"
|
||||||
|
Kind = "Artist"
|
||||||
|
}
|
||||||
|
Name = "foo"
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
invalid-gvk.hcl:2,10-14: Error in function call; Call to function "gvk" failed: GVK string must be in the form <Group>.<GroupVersion>.<Kind>, got: nope.
|
|
@ -0,0 +1,4 @@
|
||||||
|
ID {
|
||||||
|
Type = gvk("nope")
|
||||||
|
Name = "foo"
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
invalid-metadata.hcl:6,12-8,2: Failed to unmarshal argument Metadata["foo"]: expected value of type string but actual type is tuple
|
|
@ -0,0 +1,8 @@
|
||||||
|
ID {
|
||||||
|
Type = gvk("demo.v1.Artist")
|
||||||
|
Name = "korn"
|
||||||
|
}
|
||||||
|
|
||||||
|
Metadata = {
|
||||||
|
"foo" = ["bar"]
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
invalid-name.hcl:3,10-14: Failed to unmarshal argument Name: expected value of type string but actual type is number
|
|
@ -0,0 +1,4 @@
|
||||||
|
ID {
|
||||||
|
Type = gvk("demo.v1.Artist")
|
||||||
|
Name = 1234
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
{"id":{"name":"korn","type":{"group":"demo","groupVersion":"v1","kind":"Artist"}},"data":{"@type":"hashicorp.consul.internal.demo.v1.Artist","name":"Korn"}}
|
|
@ -0,0 +1,8 @@
|
||||||
|
Data = {
|
||||||
|
Name = "Korn"
|
||||||
|
}
|
||||||
|
|
||||||
|
ID = {
|
||||||
|
Type = gvk("demo.v1.Artist")
|
||||||
|
Name = "korn"
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
{"id":{"type":{"group":"mesh","groupVersion":"v1alpha1","kind":"Upstreams"}},"data":{"@type":"hashicorp.consul.mesh.v1alpha1.Upstreams","workloads":{"prefixes":["api"]},"upstreams":[{"destinationRef":{"name":"db","type":{"group":"catalog","groupVersion":"v1alpha1","kind":"Service"}},"destinationPort":"tcp","ipPort":{"port":1234}}]}}
|
|
@ -0,0 +1,33 @@
|
||||||
|
ID = {
|
||||||
|
Type = {
|
||||||
|
Group = "mesh"
|
||||||
|
GroupVersion = "v1alpha1"
|
||||||
|
Kind = "Upstreams"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Data = {
|
||||||
|
Workloads = {
|
||||||
|
Prefixes = ["api"]
|
||||||
|
}
|
||||||
|
|
||||||
|
Upstreams = [
|
||||||
|
{
|
||||||
|
DestinationRef = {
|
||||||
|
Type = {
|
||||||
|
Group = "catalog"
|
||||||
|
GroupVersion = "v1alpha1"
|
||||||
|
Kind = "Service"
|
||||||
|
}
|
||||||
|
|
||||||
|
Name = "db"
|
||||||
|
}
|
||||||
|
|
||||||
|
DestinationPort = "tcp"
|
||||||
|
|
||||||
|
IpPort = {
|
||||||
|
Port = 1234
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
{"id":{"name":"twisted-transistor","type":{"group":"demo","groupVersion":"v1","kind":"Album"}},"owner":{"name":"korn","type":{"group":"demo","groupVersion":"v1","kind":"Artist"}}}
|
|
@ -0,0 +1,9 @@
|
||||||
|
ID {
|
||||||
|
Type = gvk("demo.v1.Album")
|
||||||
|
Name = "twisted-transistor"
|
||||||
|
}
|
||||||
|
|
||||||
|
Owner {
|
||||||
|
Type = gvk("demo.v1.Artist")
|
||||||
|
Name = "korn"
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
{"id":{"name":"korn","type":{"group":"demo","groupVersion":"v1","kind":"Artist"}},"metadata":{"foo":"bar"},"data":{"@type":"hashicorp.consul.internal.demo.v1.Artist","name":"Korn","genre":"GENRE_METAL"}}
|
|
@ -0,0 +1,13 @@
|
||||||
|
ID {
|
||||||
|
Type = gvk("demo.v1.Artist")
|
||||||
|
Name = "korn"
|
||||||
|
}
|
||||||
|
|
||||||
|
Data {
|
||||||
|
Name = "Korn"
|
||||||
|
Genre = "GENRE_METAL"
|
||||||
|
}
|
||||||
|
|
||||||
|
Metadata = {
|
||||||
|
"foo" = "bar"
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
{"id":{"name":"korn","type":{"group":"demo","groupVersion":"v1","kind":"Artist"}}}
|
|
@ -0,0 +1,8 @@
|
||||||
|
ID {
|
||||||
|
Type {
|
||||||
|
Group = "demo"
|
||||||
|
GroupVersion = "v1"
|
||||||
|
Kind = "Artist"
|
||||||
|
}
|
||||||
|
Name = "korn"
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
unknown-field-block.hcl:2,3-6: Unsupported argument; An argument named "Foo" is not expected here.
|
|
@ -0,0 +1,3 @@
|
||||||
|
ID {
|
||||||
|
Foo = "bar"
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
unknown-field-object.hcl:1,6-3,2: Unsupported argument; An argument named "Foo" is not expected here.
|
|
@ -0,0 +1,3 @@
|
||||||
|
ID = {
|
||||||
|
Foo = "bar"
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
error getting type for Any field: unknown resource type: foo.bar.Baz
|
|
@ -0,0 +1,8 @@
|
||||||
|
ID {
|
||||||
|
Type = gvk("foo.bar.Baz")
|
||||||
|
Name = "qux"
|
||||||
|
}
|
||||||
|
|
||||||
|
Data {
|
||||||
|
Foo = "bar"
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
{"id":{"name":"api","type":{"group":"mesh","groupVersion":"v1alpha1","kind":"Upstreams"}},"data":{"@type":"hashicorp.consul.mesh.v1alpha1.Upstreams","workloads":{"prefixes":["api"]},"upstreams":[{"destinationRef":{"name":"db","type":{"group":"catalog","groupVersion":"v1alpha1","kind":"Service"}},"destinationPort":"tcp","ipPort":{"port":1234}}]}}
|
|
@ -0,0 +1,25 @@
|
||||||
|
ID {
|
||||||
|
Type = gvk("mesh.v1alpha1.Upstreams")
|
||||||
|
Name = "api"
|
||||||
|
}
|
||||||
|
|
||||||
|
Data {
|
||||||
|
Workloads {
|
||||||
|
Prefixes = ["api"]
|
||||||
|
}
|
||||||
|
|
||||||
|
Upstreams = [
|
||||||
|
{
|
||||||
|
DestinationRef = {
|
||||||
|
Type = gvk("catalog.v1alpha1.Service")
|
||||||
|
Name = "db"
|
||||||
|
}
|
||||||
|
|
||||||
|
DestinationPort = "tcp"
|
||||||
|
|
||||||
|
IpPort = {
|
||||||
|
Port = 1234
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package resourcehcl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/zclconf/go-cty/cty"
|
||||||
|
"github.com/zclconf/go-cty/cty/function"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/internal/protohcl"
|
||||||
|
"github.com/hashicorp/consul/internal/resource"
|
||||||
|
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Unmarshal the given HCL source into a resource.
|
||||||
|
func Unmarshal(src []byte, reg resource.Registry) (*pbresource.Resource, error) {
|
||||||
|
return UnmarshalOptions{}.Unmarshal(src, reg)
|
||||||
|
}
|
||||||
|
|
||||||
|
type UnmarshalOptions struct{ SourceFileName string }
|
||||||
|
|
||||||
|
// Unmarshal the given HCL source into a resource.
|
||||||
|
func (u UnmarshalOptions) Unmarshal(src []byte, reg resource.Registry) (*pbresource.Resource, error) {
|
||||||
|
var out pbresource.Resource
|
||||||
|
err := (protohcl.UnmarshalOptions{
|
||||||
|
SourceFileName: u.SourceFileName,
|
||||||
|
AnyTypeProvider: anyProvider{
|
||||||
|
base: &protohcl.AnyTypeURLProvider{TypeURLFieldName: "Type"},
|
||||||
|
reg: reg,
|
||||||
|
},
|
||||||
|
FieldNamer: fieldNamer{acroynms: []string{"ID", "TCP", "UDP", "HTTP"}},
|
||||||
|
Functions: map[string]function.Function{"gvk": gvk},
|
||||||
|
}).Unmarshal(src, &out)
|
||||||
|
return &out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
typeType = cty.Capsule("type", reflect.TypeOf(pbresource.Type{}))
|
||||||
|
|
||||||
|
gvk = function.New(&function.Spec{
|
||||||
|
Params: []function.Parameter{
|
||||||
|
{Name: "GVK String", Type: cty.String},
|
||||||
|
},
|
||||||
|
Type: function.StaticReturnType(typeType),
|
||||||
|
Impl: func(args []cty.Value, _ cty.Type) (cty.Value, error) {
|
||||||
|
t, err := resource.ParseGVK(args[0].AsString())
|
||||||
|
if err != nil {
|
||||||
|
return cty.NilVal, err
|
||||||
|
}
|
||||||
|
return cty.CapsuleVal(typeType, t), nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)
|
|
@ -0,0 +1,103 @@
|
||||||
|
package resourcehcl_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"google.golang.org/protobuf/encoding/protojson"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/internal/mesh"
|
||||||
|
"github.com/hashicorp/consul/internal/resource"
|
||||||
|
"github.com/hashicorp/consul/internal/resource/demo"
|
||||||
|
"github.com/hashicorp/consul/internal/resourcehcl"
|
||||||
|
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||||
|
"github.com/hashicorp/consul/proto/private/prototest"
|
||||||
|
)
|
||||||
|
|
||||||
|
var update = flag.Bool("update", false, "update golden files")
|
||||||
|
|
||||||
|
func TestUnmarshal(t *testing.T) {
|
||||||
|
entries, err := os.ReadDir("./testdata")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
read := func(t *testing.T, path string) ([]byte, bool) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
bytes, err := os.ReadFile(fmt.Sprintf("./testdata/%s", path))
|
||||||
|
switch {
|
||||||
|
case err == nil:
|
||||||
|
return bytes, true
|
||||||
|
case os.IsNotExist(err):
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Fatalf("failed to read file %s %v", path, err)
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
write := func(t *testing.T, path string, src []byte) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
require.NoError(t, os.WriteFile(fmt.Sprintf("./testdata/%s", path), src, 0o600))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entry := range entries {
|
||||||
|
name := entry.Name()
|
||||||
|
ext := path.Ext(name)
|
||||||
|
|
||||||
|
if ext != ".hcl" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
base := name[0 : len(name)-len(ext)]
|
||||||
|
|
||||||
|
t.Run(base, func(t *testing.T) {
|
||||||
|
input, _ := read(t, name)
|
||||||
|
|
||||||
|
registry := resource.NewRegistry()
|
||||||
|
demo.RegisterTypes(registry)
|
||||||
|
mesh.RegisterTypes(registry)
|
||||||
|
|
||||||
|
output, err := resourcehcl.UnmarshalOptions{SourceFileName: name}.
|
||||||
|
Unmarshal(input, registry)
|
||||||
|
|
||||||
|
if *update {
|
||||||
|
if err == nil {
|
||||||
|
json, err := protojson.Marshal(output)
|
||||||
|
require.NoError(t, err)
|
||||||
|
write(t, base+".golden", json)
|
||||||
|
} else {
|
||||||
|
write(t, base+".error", []byte(err.Error()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
goldenJSON, haveGoldenJSON := read(t, base+".golden")
|
||||||
|
goldenError, haveGoldenError := read(t, base+".error")
|
||||||
|
|
||||||
|
if haveGoldenError && haveGoldenJSON {
|
||||||
|
t.Fatalf("both %s.golden and %s.error exist, delete one", base, base)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !haveGoldenError && !haveGoldenJSON && !*update {
|
||||||
|
t.Fatalf("neither %s.golden or %s.error exist, run the tests again with the -update flag to create one", base, base)
|
||||||
|
}
|
||||||
|
|
||||||
|
if haveGoldenError {
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Equal(t, string(goldenError), err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
if haveGoldenJSON {
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var exp pbresource.Resource
|
||||||
|
require.NoError(t, protojson.Unmarshal(goldenJSON, &exp))
|
||||||
|
prototest.AssertDeepEqual(t, &exp, output)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue