Skip to content

feat: improve performance and type-safety #83

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
63 changes: 33 additions & 30 deletions ld/api_compact.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright 2015-2017 Piprate Limited
// Copyright 2025 Siemens AG
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -48,9 +49,8 @@ func (api *JsonLdApi) Compact(activeCtx *Context, activeProperty string, element
}

// use any scoped context on activeProperty
td := activeCtx.GetTermDefinition(activeProperty)
if ctx, hasCtx := td["@context"]; hasCtx {
newCtx, err := activeCtx.parse(ctx, make([]string, 0), false, true, false, true)
if td := activeCtx.GetTermDefinition(activeProperty); td != nil && td.hasContext {
newCtx, err := activeCtx.parse(td.context, make([]string, 0), false, true, false, true)
if err != nil {
return nil, err
}
Expand All @@ -66,7 +66,10 @@ func (api *JsonLdApi) Compact(activeCtx *Context, activeProperty string, element
return nil, err
}

propType := activeCtx.GetTermDefinition(activeProperty)["@type"]
propType := ""
if td := activeCtx.GetTermDefinition(activeProperty); td != nil {
propType = td.typ
}
if _, isMap := compactedValue.(map[string]interface{}); !isMap || propType == "@json" {
return compactedValue, nil
}
Expand Down Expand Up @@ -94,9 +97,8 @@ func (api *JsonLdApi) Compact(activeCtx *Context, activeProperty string, element
}

// apply property-scoped context after reverting term-scoped context
propertyScopedCtx := inputCtx.GetTermDefinition(activeProperty)["@context"]
if propertyScopedCtx != nil {
newCtx, err := activeCtx.parse(propertyScopedCtx, nil, false, true, false, true)
if td := inputCtx.GetTermDefinition(activeProperty); td != nil && td.context != nil {
newCtx, err := activeCtx.parse(td.context, nil, false, true, false, true)
if err != nil {
return nil, err
}
Expand All @@ -122,9 +124,8 @@ func (api *JsonLdApi) Compact(activeCtx *Context, activeProperty string, element
// process in lexicographical order, see https://github.com/json-ld/json-ld.org/issues/616
sort.Strings(types)
for _, tt := range types {
td := inputCtx.GetTermDefinition(tt)
if ctx, hasCtx := td["@context"]; hasCtx {
newCtx, err := activeCtx.parse(ctx, nil, false, false, false, false)
if td := inputCtx.GetTermDefinition(tt); td != nil && td.hasContext {
newCtx, err := activeCtx.parse(td.context, nil, false, false, false, false)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -273,15 +274,15 @@ func (api *JsonLdApi) Compact(activeCtx *Context, activeProperty string, element
}

nestResult := result
nestProperty, hasNest := activeCtx.GetTermDefinition(itemActiveProperty)["@nest"]
if hasNest {
if err := api.checkNestProperty(activeCtx, nestProperty.(string)); err != nil {
if td := activeCtx.GetTermDefinition(itemActiveProperty); td != nil && td.nest != "" {
nestProperty := td.nest
if err := api.checkNestProperty(activeCtx, nestProperty); err != nil {
return nil, err
}
if _, isMap := result[nestProperty.(string)].(map[string]interface{}); !isMap {
result[nestProperty.(string)] = make(map[string]interface{})
if _, isMap := result[nestProperty].(map[string]interface{}); !isMap {
result[nestProperty] = make(map[string]interface{})
}
nestResult = result[nestProperty.(string)].(map[string]interface{})
nestResult = result[nestProperty].(map[string]interface{})
}

AddValue(nestResult, itemActiveProperty, make([]interface{}, 0), true, false, true, false)
Expand All @@ -302,15 +303,16 @@ func (api *JsonLdApi) Compact(activeCtx *Context, activeProperty string, element

// if itemActiveProperty is a @nest property, add values to nestResult, otherwise result
nestResult := result
nestProperty, hasNest := activeCtx.GetTermDefinition(itemActiveProperty)["@nest"]
if hasNest {
if err := api.checkNestProperty(activeCtx, nestProperty.(string)); err != nil {

if td := activeCtx.GetTermDefinition(itemActiveProperty); td != nil && td.nest != "" {
nestProperty := td.nest
if err := api.checkNestProperty(activeCtx, nestProperty); err != nil {
return nil, err
}
if _, isMap := result[nestProperty.(string)].(map[string]interface{}); !isMap {
result[nestProperty.(string)] = make(map[string]interface{})
if _, isMap := result[nestProperty].(map[string]interface{}); !isMap {
result[nestProperty] = make(map[string]interface{})
}
nestResult = result[nestProperty.(string)].(map[string]interface{})
nestResult = result[nestProperty].(map[string]interface{})
}

// get @list value if appropriate
Expand Down Expand Up @@ -471,12 +473,13 @@ func (api *JsonLdApi) Compact(activeCtx *Context, activeProperty string, element
mapKey = v.(string)
}
} else if isIndexContainer {
indexKey := activeCtx.GetTermDefinition(itemActiveProperty)["@index"]
if indexKey == nil {
indexKey = "@index"

indexKey := "@index"
if td := activeCtx.GetTermDefinition(itemActiveProperty); td != nil && td.index != "" {
indexKey = td.index
}

containerKey, err := activeCtx.CompactIri(indexKey.(string), nil, true, false)
containerKey, err := activeCtx.CompactIri(indexKey, nil, true, false)
if err != nil {
return nil, err
}
Expand All @@ -490,7 +493,7 @@ func (api *JsonLdApi) Compact(activeCtx *Context, activeProperty string, element
var propsArray []interface{}
compactedItemMap, isMap := compactedItem.(map[string]interface{})
if isMap {
props, found := compactedItemMap[indexKey.(string)]
props, found := compactedItemMap[indexKey]
if found {
propsArray = Arrayify(props)
} else {
Expand All @@ -510,11 +513,11 @@ func (api *JsonLdApi) Compact(activeCtx *Context, activeProperty string, element
} else {
switch len(others) {
case 0:
delete(compactedItemMap, indexKey.(string))
delete(compactedItemMap, indexKey)
case 1:
compactedItemMap[indexKey.(string)] = others[0]
compactedItemMap[indexKey] = others[0]
default:
compactedItemMap[indexKey.(string)] = others
compactedItemMap[indexKey] = others
}
}
}
Expand Down
46 changes: 24 additions & 22 deletions ld/api_expand.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright 2015-2017 Piprate Limited
// Copyright 2025 Siemens AG
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -85,7 +86,10 @@ func (api *JsonLdApi) Expand(activeCtx *Context, activeProperty string, element
}

// Get any property-scoped context for activeProperty
propertyScopedCtx := activeCtx.GetTermDefinition(activeProperty)["@context"]
var propertyScopedCtx interface{}
if td := activeCtx.GetTermDefinition(activeProperty); td != nil {
propertyScopedCtx = td.context
}

// second, determine if any type-scoped context should be reverted; it
// should only be reverted when the following are all true:
Expand Down Expand Up @@ -178,9 +182,8 @@ func (api *JsonLdApi) Expand(activeCtx *Context, activeProperty string, element
}

for _, tt := range types {
td := typeScopedContext.GetTermDefinition(tt)
if ctx, hasCtx := td["@context"]; hasCtx {
newCtx, err := activeCtx.parse(ctx, nil, false, false, false, false)
if td := typeScopedContext.GetTermDefinition(tt); td != nil && td.hasContext {
newCtx, err := activeCtx.parse(td.context, nil, false, false, false, false)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -666,10 +669,10 @@ func (api *JsonLdApi) expandObject(activeCtx *Context, activeProperty string, ex
// use potential scoped context for key
termCtx := activeCtx
td := activeCtx.GetTermDefinition(key)
if ctx, hasCtx := td["@context"]; hasCtx {
if td != nil && td.hasContext {
// TODO: fix calling a private method
//termCtx, err = activeCtx.Parse(ctx)
termCtx, err = activeCtx.parse(ctx, make([]string, 0), false, true, false, true)
termCtx, err = activeCtx.parse(td.context, make([]string, 0), false, true, false, true)
if err != nil {
return err
}
Expand All @@ -679,7 +682,8 @@ func (api *JsonLdApi) expandObject(activeCtx *Context, activeProperty string, ex
if termCtx.HasContainerMapping(key, "@language") && isMap {
var expandedValueList []interface{}

dir, hasDir := td["@direction"]
dir, hasDir := td.direction, td.hasDirection

for _, language := range GetOrderedKeys(valueMap) {
expandedLanguage, err := termCtx.ExpandIri(language, false, true, nil, nil)
if err != nil {
Expand All @@ -706,7 +710,7 @@ func (api *JsonLdApi) expandObject(activeCtx *Context, activeProperty string, ex
if dir != nil {
v["@direction"] = dir
}
} else if defaultDir, found := termCtx.values["@direction"]; found {
} else if defaultDir := termCtx.values.direction; defaultDir != "" {
v["@direction"] = defaultDir
}
expandedValueList = append(expandedValueList, v)
Expand All @@ -715,18 +719,18 @@ func (api *JsonLdApi) expandObject(activeCtx *Context, activeProperty string, ex
expandedValue = expandedValueList
} else if termCtx.HasContainerMapping(key, "@index") && isMap { // 7.6)
asGraph := termCtx.HasContainerMapping(key, "@graph")
indexKey := termCtx.GetTermDefinition(key)["@index"]
if indexKey == nil {
indexKey = "@index"
indexKey := "@index"
if tdKey := termCtx.GetTermDefinition(key); tdKey != nil && tdKey.index != "" {
indexKey = tdKey.index
}
var propertyIndex string
if indexKey != "@index" {
propertyIndex, err = activeCtx.ExpandIri(indexKey.(string), false, true, nil, nil)
propertyIndex, err = activeCtx.ExpandIri(indexKey, false, true, nil, nil)
if err != nil {
return err
}
}
expandedValue, err = api.expandIndexMap(termCtx, key, valueMap, indexKey.(string), asGraph, propertyIndex,
expandedValue, err = api.expandIndexMap(termCtx, key, valueMap, indexKey, asGraph, propertyIndex,
opts)
if err != nil {
return err
Expand All @@ -747,6 +751,7 @@ func (api *JsonLdApi) expandObject(activeCtx *Context, activeProperty string, ex
}
} else {
isList := expandedProperty == "@list"
tdKey := activeCtx.GetTermDefinition(key)
if isList || expandedProperty == "@set" {
nextActiveProperty := activeProperty
if isList && expandedActiveProperty == "@graph" {
Expand All @@ -756,7 +761,7 @@ func (api *JsonLdApi) expandObject(activeCtx *Context, activeProperty string, ex
if err != nil {
return err
}
} else if activeCtx.GetTermDefinition(key)["@type"] == "@json" {
} else if tdKey != nil && tdKey.typ == "@json" {
expandedValue = map[string]interface{}{
"@type": "@json",
"@value": value,
Expand Down Expand Up @@ -908,15 +913,12 @@ func (api *JsonLdApi) expandIndexMap(activeCtx *Context, activeProperty string,

indexCtx := activeCtx
// if indexKey is @type, there may be a context defined for it
if indexKey == "@type" {
td := activeCtx.GetTermDefinition(key)
if ctx, hasCtx := td["@context"]; hasCtx {
newCtx, err := activeCtx.Parse(ctx)
if err != nil {
return nil, err
}
indexCtx = newCtx
if td := activeCtx.GetTermDefinition(key); indexKey == "@type" && td != nil && td.hasContext {
newCtx, err := activeCtx.Parse(td.context)
if err != nil {
return nil, err
}
indexCtx = newCtx
}

// 7.6.2.1)
Expand Down
Loading
Loading