mirror of
https://github.com/hashicorp/terraform.git
synced 2026-03-22 02:20:07 -04:00
Some checks failed
build / Determine intended Terraform version (push) Has been cancelled
build / Determine Go toolchain version (push) Has been cancelled
Quick Checks / Unit Tests (push) Has been cancelled
Quick Checks / Race Tests (push) Has been cancelled
Quick Checks / End-to-end Tests (push) Has been cancelled
Quick Checks / Code Consistency Checks (push) Has been cancelled
build / Generate release metadata (push) Has been cancelled
build / Build for freebsd_386 (push) Has been cancelled
build / Build for linux_386 (push) Has been cancelled
build / Build for openbsd_386 (push) Has been cancelled
build / Build for windows_386 (push) Has been cancelled
build / Build for darwin_amd64 (push) Has been cancelled
build / Build for freebsd_amd64 (push) Has been cancelled
build / Build for linux_amd64 (push) Has been cancelled
build / Build for openbsd_amd64 (push) Has been cancelled
build / Build for solaris_amd64 (push) Has been cancelled
build / Build for windows_amd64 (push) Has been cancelled
build / Build for freebsd_arm (push) Has been cancelled
build / Build for linux_arm (push) Has been cancelled
build / Build for darwin_arm64 (push) Has been cancelled
build / Build for linux_arm64 (push) Has been cancelled
build / Build for windows_arm64 (push) Has been cancelled
build / Build Docker image for linux_386 (push) Has been cancelled
build / Build Docker image for linux_amd64 (push) Has been cancelled
build / Build Docker image for linux_arm (push) Has been cancelled
build / Build Docker image for linux_arm64 (push) Has been cancelled
build / Build e2etest for linux_386 (push) Has been cancelled
build / Build e2etest for windows_386 (push) Has been cancelled
build / Build e2etest for darwin_amd64 (push) Has been cancelled
build / Build e2etest for linux_amd64 (push) Has been cancelled
build / Build e2etest for windows_amd64 (push) Has been cancelled
build / Build e2etest for linux_arm (push) Has been cancelled
build / Build e2etest for darwin_arm64 (push) Has been cancelled
build / Build e2etest for linux_arm64 (push) Has been cancelled
build / Run e2e test for linux_386 (push) Has been cancelled
build / Run e2e test for windows_386 (push) Has been cancelled
build / Run e2e test for darwin_amd64 (push) Has been cancelled
build / Run e2e test for linux_amd64 (push) Has been cancelled
build / Run e2e test for windows_amd64 (push) Has been cancelled
build / Run e2e test for linux_arm (push) Has been cancelled
build / Run e2e test for linux_arm64 (push) Has been cancelled
build / Run terraform-exec test for linux amd64 (push) Has been cancelled
inline type conversions
249 lines
7 KiB
Go
249 lines
7 KiB
Go
// Copyright IBM Corp. 2014, 2026
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package jsonfunction
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/hashicorp/terraform/internal/providers"
|
|
"github.com/hashicorp/terraform/internal/tfdiags"
|
|
"github.com/zclconf/go-cty/cty"
|
|
"github.com/zclconf/go-cty/cty/function"
|
|
)
|
|
|
|
// FormatVersion represents the version of the json format and will be
|
|
// incremented for any change to this format that requires changes to a
|
|
// consuming parser.
|
|
//
|
|
// Any changes to this version should also consider compatibility in the
|
|
// jsonprovider package versioning as well, as that functionality is also
|
|
// reliant on this package.
|
|
const FormatVersion = "1.0"
|
|
|
|
// functions is the top-level object returned when exporting function signatures
|
|
type functions struct {
|
|
FormatVersion string `json:"format_version"`
|
|
Signatures map[string]*FunctionSignature `json:"function_signatures,omitempty"`
|
|
}
|
|
|
|
// FunctionSignature represents a function signature.
|
|
type FunctionSignature struct {
|
|
// Description is an optional human-readable description
|
|
// of the function
|
|
Description string `json:"description,omitempty"`
|
|
|
|
// Summary is the optional shortened description of the function
|
|
Summary string `json:"summary,omitempty"`
|
|
|
|
// DeprecationMessage is an optional message that indicates that the
|
|
// function should be considered deprecated and what actions should be
|
|
// performed by the practitioner to handle the deprecation.
|
|
DeprecationMessage string `json:"deprecation_message,omitempty"`
|
|
|
|
// ReturnTypes is the ctyjson representation of the function's
|
|
// return types based on supplying all parameters using
|
|
// dynamic types. Functions can have dynamic return types.
|
|
ReturnType cty.Type `json:"return_type"`
|
|
|
|
// Parameters describes the function's fixed positional parameters.
|
|
Parameters []*parameter `json:"parameters,omitempty"`
|
|
|
|
// VariadicParameter describes the function's variadic
|
|
// parameters, if any are supported.
|
|
VariadicParameter *parameter `json:"variadic_parameter,omitempty"`
|
|
}
|
|
|
|
func newFunctions() *functions {
|
|
signatures := make(map[string]*FunctionSignature)
|
|
return &functions{
|
|
FormatVersion: FormatVersion,
|
|
Signatures: signatures,
|
|
}
|
|
}
|
|
|
|
func MarshalProviderFunctions(f map[string]providers.FunctionDecl) map[string]*FunctionSignature {
|
|
if f == nil {
|
|
return nil
|
|
}
|
|
|
|
result := make(map[string]*FunctionSignature, len(f))
|
|
|
|
for name, v := range f {
|
|
result[name] = marshalProviderFunction(v)
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func Marshal(f map[string]function.Function) ([]byte, tfdiags.Diagnostics) {
|
|
var diags tfdiags.Diagnostics
|
|
signatures := newFunctions()
|
|
|
|
for name, v := range f {
|
|
switch name {
|
|
case "can", "core::can":
|
|
signatures.Signatures[name] = marshalCan(v)
|
|
case "try", "core::try":
|
|
signatures.Signatures[name] = marshalTry(v)
|
|
case "templatestring", "core::templatestring":
|
|
signatures.Signatures[name] = marshalTemplatestring(v)
|
|
case "convert", "core::convert":
|
|
signatures.Signatures[name] = marshalConvert(v)
|
|
default:
|
|
signature, err := marshalFunction(v)
|
|
if err != nil {
|
|
diags = diags.Append(tfdiags.Sourceless(
|
|
tfdiags.Error,
|
|
fmt.Sprintf("Failed to serialize function %q", name),
|
|
err.Error(),
|
|
))
|
|
}
|
|
signatures.Signatures[name] = signature
|
|
}
|
|
}
|
|
|
|
if diags.HasErrors() {
|
|
return nil, diags
|
|
}
|
|
|
|
ret, err := json.Marshal(signatures)
|
|
if err != nil {
|
|
diags = diags.Append(tfdiags.Sourceless(
|
|
tfdiags.Error,
|
|
"Failed to serialize functions",
|
|
err.Error(),
|
|
))
|
|
return nil, diags
|
|
}
|
|
return ret, nil
|
|
}
|
|
|
|
func marshalFunction(f function.Function) (*FunctionSignature, error) {
|
|
var err error
|
|
var vp *parameter
|
|
if f.VarParam() != nil {
|
|
vp = marshalParameter(f.VarParam())
|
|
}
|
|
|
|
var p []*parameter
|
|
if len(f.Params()) > 0 {
|
|
p = marshalParameters(f.Params())
|
|
}
|
|
|
|
r, err := getReturnType(f)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &FunctionSignature{
|
|
Description: f.Description(),
|
|
ReturnType: r,
|
|
Parameters: p,
|
|
VariadicParameter: vp,
|
|
}, nil
|
|
}
|
|
|
|
func marshalProviderFunction(f providers.FunctionDecl) *FunctionSignature {
|
|
var vp *parameter
|
|
if f.VariadicParameter != nil {
|
|
vp = marshalProviderParameter(*f.VariadicParameter)
|
|
}
|
|
|
|
var p []*parameter
|
|
if len(f.Parameters) > 0 {
|
|
p = marshalProviderParameters(f.Parameters)
|
|
}
|
|
|
|
return &FunctionSignature{
|
|
Description: f.Description,
|
|
Summary: f.Summary,
|
|
DeprecationMessage: f.DeprecationMessage,
|
|
ReturnType: f.ReturnType,
|
|
Parameters: p,
|
|
VariadicParameter: vp,
|
|
}
|
|
}
|
|
|
|
// marshalTry returns a static function signature for the try function.
|
|
// We need this exception because the function implementation uses capsule
|
|
// types that we can't marshal.
|
|
func marshalTry(try function.Function) *FunctionSignature {
|
|
return &FunctionSignature{
|
|
Description: try.Description(),
|
|
ReturnType: cty.DynamicPseudoType,
|
|
VariadicParameter: ¶meter{
|
|
Name: try.VarParam().Name,
|
|
Description: try.VarParam().Description,
|
|
IsNullable: try.VarParam().AllowNull,
|
|
Type: cty.DynamicPseudoType,
|
|
},
|
|
}
|
|
}
|
|
|
|
// marshalConvert returns a static function signature for the try function.
|
|
// We need this exception because the function implementation uses capsule
|
|
// types that we can't marshal.
|
|
func marshalConvert(convert function.Function) *FunctionSignature {
|
|
return &FunctionSignature{
|
|
Description: convert.Description(),
|
|
ReturnType: cty.DynamicPseudoType,
|
|
Parameters: []*parameter{
|
|
{
|
|
Name: convert.Params()[0].Name,
|
|
Description: convert.Params()[0].Description,
|
|
IsNullable: convert.Params()[0].AllowNull,
|
|
Type: cty.DynamicPseudoType,
|
|
},
|
|
{
|
|
Name: convert.Params()[1].Name,
|
|
Description: convert.Params()[1].Description,
|
|
Type: cty.DynamicPseudoType,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// marshalCan returns a static function signature for the can function.
|
|
// We need this exception because the function implementation uses capsule
|
|
// types that we can't marshal.
|
|
func marshalCan(can function.Function) *FunctionSignature {
|
|
return &FunctionSignature{
|
|
Description: can.Description(),
|
|
ReturnType: cty.Bool,
|
|
Parameters: []*parameter{
|
|
{
|
|
Name: can.Params()[0].Name,
|
|
Description: can.Params()[0].Description,
|
|
IsNullable: can.Params()[0].AllowNull,
|
|
Type: cty.DynamicPseudoType,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// marshalTemplatestring returns a static function signature for the
|
|
// templatestring function.
|
|
// We need this exception because the function implementation uses capsule
|
|
// types that we can't marshal.
|
|
func marshalTemplatestring(templatestring function.Function) *FunctionSignature {
|
|
return &FunctionSignature{
|
|
Description: templatestring.Description(),
|
|
ReturnType: cty.String,
|
|
Parameters: []*parameter{
|
|
{
|
|
Name: templatestring.Params()[0].Name,
|
|
Description: templatestring.Params()[0].Description,
|
|
IsNullable: templatestring.Params()[0].AllowNull,
|
|
Type: cty.String,
|
|
},
|
|
{
|
|
Name: templatestring.Params()[1].Name,
|
|
Description: templatestring.Params()[1].Description,
|
|
IsNullable: templatestring.Params()[1].AllowNull,
|
|
Type: cty.DynamicPseudoType,
|
|
},
|
|
},
|
|
}
|
|
}
|