Skip to content

Commit

Permalink
new parse tree
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew-Morozko committed Feb 16, 2024
1 parent 924170e commit 5b9401f
Show file tree
Hide file tree
Showing 11 changed files with 482 additions and 303 deletions.
110 changes: 40 additions & 70 deletions parser/caller.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/blackstork-io/fabric/parser/definitions"
"github.com/blackstork-io/fabric/parser/evaluation"
"github.com/blackstork-io/fabric/parser/plugincaller"
"github.com/blackstork-io/fabric/pkg/diagnostics"
"github.com/blackstork-io/fabric/pkg/utils"
"github.com/blackstork-io/fabric/plugin"
Expand All @@ -21,10 +22,6 @@ type pluginData struct {
ConfigSpec hcldec.Spec
InvocationSpec hcldec.Spec
}
type PluginCaller interface {
CallContent(name string, config evaluation.Configuration, invocation evaluation.Invocation, context map[string]any) (result string, diag diagnostics.Diag)
CallData(name string, config evaluation.Configuration, invocation evaluation.Invocation) (result map[string]any, diag diagnostics.Diag)
}

type Caller struct {
plugins *runner.Runner
Expand All @@ -36,7 +33,7 @@ func NewPluginCaller(r *runner.Runner) *Caller {
}
}

var _ PluginCaller = (*Caller)(nil)
var _ plugincaller.PluginCaller = (*Caller)(nil)

func (c *Caller) pluginData(kind, name string) (pluginData, diagnostics.Diag) {
switch kind {
Expand Down Expand Up @@ -69,35 +66,27 @@ func (c *Caller) pluginData(kind, name string) (pluginData, diagnostics.Diag) {
}
}

func (c *Caller) callPlugin(kind, name string, config evaluation.Configuration, invocation evaluation.Invocation, dataCtx map[string]any) (res any, diags diagnostics.Diag) {
func (c *Caller) callPlugin(ctx context.Context, kind, name string, config evaluation.Configuration, invocation evaluation.Invocation, dataCtx plugin.MapData) (res any, diags diagnostics.Diag) {
data, diags := c.pluginData(kind, name)
if diags.HasErrors() {
return
}

dataCtxAny, err := plugin.ParseDataMapAny(dataCtx)
if err != nil {
diags.Add("Error while parsing context", err.Error())
return
}

acceptsConfig := !utils.IsNil(data.ConfigSpec)
hasConfig := config.Exists()

var configVal cty.Value
if acceptsConfig {
var stdDiag diagnostics.Diag
configVal, stdDiag = config.ParseConfig(data.ConfigSpec)
if !diags.Extend(stdDiag) {
var diag diagnostics.Diag
configVal, diag = config.ParseConfig(data.ConfigSpec)
if !diags.Extend(diag) {
typ := hcldec.ImpliedType(data.ConfigSpec)
errs := configVal.Type().TestConformance(typ)
if errs != nil {
// Attempt a conversion
var err error
configVal, err = convert.Convert(configVal, typ)
if err != nil {
diags.AppendErr(err, "Error while serializing config")
}
diags.AppendErr(err, "Error while serializing config")
}
}
} else if hasConfig {
Expand All @@ -114,94 +103,75 @@ func (c *Caller) callPlugin(kind, name string, config evaluation.Configuration,

pluginArgs, diag := invocation.ParseInvocation(data.InvocationSpec)
diags.Extend(diag)
if diag.HasErrors() {
return
}
if data.InvocationSpec != nil {
typ := hcldec.ImpliedType(data.InvocationSpec)
errs := pluginArgs.Type().TestConformance(typ)
if errs != nil {
// Attempt a conversion
var err error
pluginArgs, err = convert.Convert(pluginArgs, typ)
if err != nil {
diag.AppendErr(err, "Error while serializing args")

return nil, diag
}
diags.AppendErr(err, "Error while serializing args")
}
}

var result struct {
Result any
Diags hcl.Diagnostics
if diags.HasErrors() {
return
}

switch kind {
case "data":
source, diags := c.plugins.DataSource(name)
if diags.HasErrors() {
return nil, diagnostics.Diag(diags)
source, diag := c.plugins.DataSource(name)
if diags.ExtendHcl(diag) {
return
}
data, diags := source.Execute(context.Background(), &plugin.RetrieveDataParams{
data, diag := source.Execute(ctx, &plugin.RetrieveDataParams{
Config: configVal,
Args: pluginArgs,
})
if data != nil {
result.Result = data.Any()
}
result.Diags = diags
res = data
diags.ExtendHcl(diag)
case "content":
provider, diags := c.plugins.ContentProvider(name)
if diags.HasErrors() {
return nil, diagnostics.Diag(diags)
provider, diag := c.plugins.ContentProvider(name)
if diags.ExtendHcl(diag) {
return
}
content, diags := provider.Execute(context.Background(), &plugin.ProvideContentParams{
content, diag := provider.Execute(ctx, &plugin.ProvideContentParams{
Config: configVal,
Args: pluginArgs,
DataContext: dataCtxAny,
DataContext: dataCtx,
})
result.Result = ""
res = ""
if content != nil {
result.Result = content.Markdown
res = content.Markdown
}
result.Diags = diags
}

for _, d := range result.Diags {
diags = append(diags, d)
diags.ExtendHcl(diag)
}
res = result.Result
return
}

func (c *Caller) CallContent(name string, config evaluation.Configuration, invocation evaluation.Invocation, context map[string]any) (result string, diag diagnostics.Diag) {
func (c *Caller) CallContent(ctx context.Context, name string, config evaluation.Configuration, invocation evaluation.Invocation, dataCtx plugin.MapData) (result string, diag diagnostics.Diag) {
var ok bool
var res any
res, diag = c.callPlugin(definitions.BlockKindContent, name, config, invocation, context)
res, diag = c.callPlugin(ctx, definitions.BlockKindContent, name, config, invocation, dataCtx)
if diag.HasErrors() {
return
}
result, ok = res.(string)
if !diag.HasErrors() && !ok {
diag.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Incorrect result type",
Detail: "Plugin returned incorrect data type. Please contact fabric developers about this issue",
Subject: invocation.DefRange().Ptr(),
})
if !ok {
panic("Incorrect plugin result type")
}
return
}

func (c *Caller) CallData(name string, config evaluation.Configuration, invocation evaluation.Invocation) (result map[string]any, diag diagnostics.Diag) {
func (c *Caller) CallData(ctx context.Context, name string, config evaluation.Configuration, invocation evaluation.Invocation) (result plugin.MapData, diag diagnostics.Diag) {
var ok bool
var res any
res, diag = c.callPlugin(definitions.BlockKindData, name, config, invocation, nil)
result, ok = res.(map[string]any)
if !diag.HasErrors() && !ok {
diag.Append(&hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Incorrect result type",
Detail: "Plugin returned incorrect data type. Please contact fabric developers about this issue",
Subject: invocation.DefRange().Ptr(),
})
res, diag = c.callPlugin(ctx, definitions.BlockKindData, name, config, invocation, nil)
if diag.HasErrors() {
return
}
result, ok = res.(plugin.MapData)
if !ok {
panic("Incorrect plugin result type")
}
return
}
8 changes: 6 additions & 2 deletions parser/definedBlocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,13 @@ func (db *DefinedBlocks) AsValueMap() map[string]cty.Value {
}

func (db *DefinedBlocks) DefaultConfigFor(plugin *definitions.Plugin) (config *definitions.Config) {
return db.DefaultConfig(plugin.Kind(), plugin.Name())
}

func (db *DefinedBlocks) DefaultConfig(pluginKind, pluginName string) (config *definitions.Config) {
return db.Config[definitions.Key{
PluginKind: plugin.Kind(),
PluginName: plugin.Name(),
PluginKind: pluginKind,
PluginName: pluginName,
BlockName: "",
}]
}
Expand Down
13 changes: 13 additions & 0 deletions parser/definitions/meta.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
package definitions

import "github.com/blackstork-io/fabric/plugin"

type MetaBlock struct {
// XXX: is empty sting enougth or use a proper ptr-nil-if-missing?
Author string `hcl:"author,optional"`
Tags []string `hcl:"tags,optional"`

// TODO: ?store def range defRange hcl.Range
}

func (m *MetaBlock) AsJQ() plugin.Data {
tags := make(plugin.ListData, len(m.Tags))
for i, tag := range m.Tags {
tags[i] = plugin.StringData(tag)
}
return plugin.ConvMapData{
"author": plugin.StringData(m.Author),
"tags": tags,
}
}
2 changes: 1 addition & 1 deletion parser/definitions/section.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var _ ContentPluginOrSection = (*ParsedPlugin)(nil)

type ParsedSection struct {
Meta *MetaBlock
Title *hclsyntax.Attribute
Title *ParsedPlugin
Content []ContentPluginOrSection
}

Expand Down
Loading

0 comments on commit 5b9401f

Please sign in to comment.