Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 30 additions & 38 deletions src/bicep-types-go/index/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,9 @@ func (s *TypeSettings) UnmarshalJSON(data []byte) error {
// ResourceVersionMap maps API versions to type references
type ResourceVersionMap map[string]types.ITypeReference

// ResourceFunctionMap maps function names to type references
type ResourceFunctionMap map[string]types.ITypeReference

// ResourceFunctionVersionMap maps API versions to function maps
type ResourceFunctionVersionMap map[string]ResourceFunctionMap
// ResourceFunctionVersionMap maps API versions to the list of resource-function
// references declared for that version.
type ResourceFunctionVersionMap map[string][]types.ITypeReference

// TypeIndex represents an index of types organized by resource type
type TypeIndex struct {
Expand Down Expand Up @@ -140,7 +138,7 @@ func BuildIndex(typeFiles []TypeFile, logFunc func(string), settings *TypeSettin
functionSeen[lowerFuncKey] = struct{}{}

ref := types.CrossFileTypeReference{RelativePath: file.RelativePath, Ref: typeIndex}
idx.AddResourceFunction(concrete.ResourceType, concrete.ApiVersion, concrete.Name, ref)
idx.AddResourceFunction(concrete.ResourceType, concrete.ApiVersion, ref)

case *types.NamespaceFunctionType:
ref := types.CrossFileTypeReference{RelativePath: file.RelativePath, Ref: typeIndex}
Expand Down Expand Up @@ -175,7 +173,7 @@ func (idx *TypeIndex) AddResource(resourceType string, apiVersion string, typeRe
}

// AddResourceFunction adds a resource function to the index
func (idx *TypeIndex) AddResourceFunction(resourceType string, apiVersion string, functionName string, typeRef types.ITypeReference) {
func (idx *TypeIndex) AddResourceFunction(resourceType string, apiVersion string, typeRef types.ITypeReference) {
if idx.ResourceFunctions == nil {
idx.ResourceFunctions = make(map[string]ResourceFunctionVersionMap)
}
Expand All @@ -184,11 +182,7 @@ func (idx *TypeIndex) AddResourceFunction(resourceType string, apiVersion string
idx.ResourceFunctions[resourceType] = make(ResourceFunctionVersionMap)
}

if _, exists := idx.ResourceFunctions[resourceType][apiVersion]; !exists {
idx.ResourceFunctions[resourceType][apiVersion] = make(ResourceFunctionMap)
}

idx.ResourceFunctions[resourceType][apiVersion][functionName] = typeRef
idx.ResourceFunctions[resourceType][apiVersion] = append(idx.ResourceFunctions[resourceType][apiVersion], typeRef)
}

// AddNamespaceFunction adds a namespace function to the index
Expand All @@ -211,8 +205,8 @@ func (idx *TypeIndex) GetResource(resourceType string, apiVersion string) (types
return ref, exists
}

// GetResourceFunction retrieves a resource function reference
func (idx *TypeIndex) GetResourceFunction(resourceType string, apiVersion string, functionName string) (types.ITypeReference, bool) {
// GetResourceFunctions retrieves the list of resource function references
func (idx *TypeIndex) GetResourceFunctions(resourceType string, apiVersion string) ([]types.ITypeReference, bool) {
if idx.ResourceFunctions == nil {
return nil, false
}
Expand All @@ -222,13 +216,8 @@ func (idx *TypeIndex) GetResourceFunction(resourceType string, apiVersion string
return nil, false
}

functionMap, exists := versionMap[apiVersion]
if !exists {
return nil, false
}

ref, exists := functionMap[functionName]
return ref, exists
refs, exists := versionMap[apiVersion]
return refs, exists
}

// MarshalJSON implements custom JSON marshaling for TypeIndex
Expand Down Expand Up @@ -265,11 +254,11 @@ func (idx *TypeIndex) MarshalJSON() ([]byte, error) {
// UnmarshalJSON implements custom JSON unmarshaling for TypeIndex
func (idx *TypeIndex) UnmarshalJSON(data []byte) error {
var temp struct {
Resources map[string]json.RawMessage `json:"resources,omitempty"`
ResourceFunctions map[string]map[string]map[string]json.RawMessage `json:"resourceFunctions,omitempty"`
NamespaceFunctions []json.RawMessage `json:"namespaceFunctions,omitempty"`
FallbackResource json.RawMessage `json:"fallbackResourceType,omitempty"`
Settings *TypeSettings `json:"settings,omitempty"`
Resources map[string]json.RawMessage `json:"resources,omitempty"`
ResourceFunctions map[string]map[string][]json.RawMessage `json:"resourceFunctions,omitempty"`
NamespaceFunctions []json.RawMessage `json:"namespaceFunctions,omitempty"`
FallbackResource json.RawMessage `json:"fallbackResourceType,omitempty"`
Settings *TypeSettings `json:"settings,omitempty"`
}

if err := json.Unmarshal(data, &temp); err != nil {
Expand Down Expand Up @@ -309,20 +298,23 @@ func (idx *TypeIndex) UnmarshalJSON(data []byte) error {
// Unmarshal resource functions
if temp.ResourceFunctions != nil {
for resourceType, versionMap := range temp.ResourceFunctions {
if versionMap != nil {
idx.ResourceFunctions[resourceType] = make(ResourceFunctionVersionMap)
for version, functionMap := range versionMap {
if functionMap != nil {
idx.ResourceFunctions[resourceType][version] = make(ResourceFunctionMap)
for functionName, refData := range functionMap {
ref, err := unmarshalTypeReference(refData)
if err != nil {
return err
}
idx.ResourceFunctions[resourceType][version][functionName] = ref
}
if versionMap == nil {
continue
}
idx.ResourceFunctions[resourceType] = make(ResourceFunctionVersionMap)
for version, refList := range versionMap {
if refList == nil {
continue
}
refs := make([]types.ITypeReference, 0, len(refList))
for i, refData := range refList {
ref, err := unmarshalTypeReference(refData)
if err != nil {
return fmt.Errorf("failed to unmarshal resource function reference for %s@%s at index %d: %w", resourceType, version, i, err)
}
refs = append(refs, ref)
}
idx.ResourceFunctions[resourceType][version] = refs
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions src/bicep-types-go/index/index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,8 @@ func TestBuildIndex_Basic(t *testing.T) {
require.True(t, exists)
funcs, exists := funcVersions["2023-01-01"]
require.True(t, exists)
funcRef, exists := funcs["list"]
require.True(t, exists)
crossFunc, ok := funcRef.(types.CrossFileTypeReference)
require.Len(t, funcs, 1)
crossFunc, ok := funcs[0].(types.CrossFileTypeReference)
require.True(t, ok)
assert.Equal(t, "foo/types.json", crossFunc.RelativePath)
assert.Equal(t, 2, crossFunc.Ref)
Expand Down
13 changes: 9 additions & 4 deletions src/bicep-types-go/types/objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -492,10 +492,15 @@ func (t *ResourceFunctionType) UnmarshalJSON(data []byte) error {
return err
}

// Unmarshal return type reference
outputRef, err := unmarshalTypeReference(temp.Output)
if err != nil {
return fmt.Errorf("failed to unmarshal output type: %w", err)
var err error

// Unmarshal return type reference if present
var outputRef ITypeReference
if temp.Output != nil {
outputRef, err = unmarshalTypeReference(temp.Output)
if err != nil {
return fmt.Errorf("failed to unmarshal output type: %w", err)
}
}

// Unmarshal input type reference if present
Expand Down
3 changes: 1 addition & 2 deletions src/bicep-types-go/writers/writers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestJSONWriter_WriteTypeIndex(t *testing.T) {
// Create test index
idx := index.NewTypeIndex()
idx.AddResource("Microsoft.Test/resources", "2023-01-01", types.TypeReference{Ref: 0})
idx.AddResourceFunction("Microsoft.Test/resources", "2023-01-01", "list", types.TypeReference{Ref: 1})
idx.AddResourceFunction("Microsoft.Test/resources", "2023-01-01", types.TypeReference{Ref: 1})

var buf bytes.Buffer
err := writer.WriteTypeIndex(&buf, idx)
Expand All @@ -55,7 +55,6 @@ func TestJSONWriter_WriteTypeIndex(t *testing.T) {
// Should contain resource and function mappings
assert.Contains(t, output, "Microsoft.Test/resources")
assert.Contains(t, output, "2023-01-01")
assert.Contains(t, output, "list")
assert.Contains(t, output, `"$ref"`)
}

Expand Down
Loading