From a601fdb080e2e362cc621facf2cbd6833ad4216a Mon Sep 17 00:00:00 2001 From: Ian Wahbe Date: Wed, 2 Nov 2022 12:39:57 -0700 Subject: [PATCH] Support a logical name for config vars --- ...upport-a-logical-name-for-config-vars.yaml | 4 ++++ pkg/codegen/dotnet/gen_program.go | 10 ++++++--- pkg/codegen/go/gen_program.go | 21 ++++++++++--------- pkg/codegen/nodejs/gen_program.go | 4 +++- pkg/codegen/pcl/binder_nodes.go | 8 +++++++ pkg/codegen/pcl/config.go | 12 +++++++++++ pkg/codegen/python/gen_program.go | 2 +- pkg/codegen/python/python_test.go | 1 + 8 files changed, 47 insertions(+), 15 deletions(-) create mode 100644 changelog/pending/20221102--programgen-dotnet-go-java-nodejs-python--support-a-logical-name-for-config-vars.yaml diff --git a/changelog/pending/20221102--programgen-dotnet-go-java-nodejs-python--support-a-logical-name-for-config-vars.yaml b/changelog/pending/20221102--programgen-dotnet-go-java-nodejs-python--support-a-logical-name-for-config-vars.yaml new file mode 100644 index 000000000000..2df9f7a9a33f --- /dev/null +++ b/changelog/pending/20221102--programgen-dotnet-go-java-nodejs-python--support-a-logical-name-for-config-vars.yaml @@ -0,0 +1,4 @@ +changes: +- type: feat + scope: programgen/dotnet,go,java,nodejs,python + description: Support a logical name for config vars diff --git a/pkg/codegen/dotnet/gen_program.go b/pkg/codegen/dotnet/gen_program.go index f3d215bd800f..5521cd04d769 100644 --- a/pkg/codegen/dotnet/gen_program.go +++ b/pkg/codegen/dotnet/gen_program.go @@ -744,17 +744,21 @@ func (g *generator) genConfigVariable(w io.Writer, v *pcl.ConfigVariable) { getOrRequire = "Require" } + name := makeValidIdentifier(v.Name()) if v.DefaultValue != nil { typ := v.DefaultValue.Type() if _, ok := typ.(*model.PromiseType); ok { - g.Fgenf(w, "%[1]svar %[2]s = Output.Create(config.%[3]s%[4]s(\"%[2]s\"))", g.Indent, v.Name(), getOrRequire, getType) + g.Fgenf(w, "%svar %s = Output.Create(config.%s%s(\"%s\"))", + g.Indent, name, getOrRequire, getType, v.LogicalName()) } else { - g.Fgenf(w, "%[1]svar %[2]s = config.%[3]s%[4]s(\"%[2]s\")", g.Indent, v.Name(), getOrRequire, getType) + g.Fgenf(w, "%svar %s = config.%s%s(\"%s\")", + g.Indent, name, getOrRequire, getType, v.LogicalName()) } expr := g.lowerExpression(v.DefaultValue, v.DefaultValue.Type()) g.Fgenf(w, " ?? %.v", expr) } else { - g.Fgenf(w, "%[1]svar %[2]s = config.%[3]s%[4]s(\"%[2]s\")", g.Indent, v.Name(), getOrRequire, getType) + g.Fgenf(w, "%svar %s = config.%s%s(\"%s\")", + g.Indent, name, getOrRequire, getType, v.LogicalName()) } g.Fgenf(w, ";\n") } diff --git a/pkg/codegen/go/gen_program.go b/pkg/codegen/go/gen_program.go index fc9e61599e21..93268790320d 100644 --- a/pkg/codegen/go/gen_program.go +++ b/pkg/codegen/go/gen_program.go @@ -903,8 +903,9 @@ func (g *generator) genConfigVariable(w io.Writer, v *pcl.ConfigVariable) { getOrRequire = "Require" } + name := makeValidIdentifier(v.Name()) if v.DefaultValue == nil { - g.Fgenf(w, "%[1]s := cfg.%[2]s%[3]s(\"%[1]s\")\n", v.Name(), getOrRequire, getType) + g.Fgenf(w, "%s := cfg.%s%s(\"%s\")\n", name, getOrRequire, getType, v.LogicalName()) } else { expr, temps := g.lowerExpression(v.DefaultValue, v.DefaultValue.Type()) g.genTemps(w, temps) @@ -912,7 +913,7 @@ func (g *generator) genConfigVariable(w io.Writer, v *pcl.ConfigVariable) { case *model.FunctionCallExpression: switch expr.Name { case pcl.Invoke: - g.Fgenf(w, "%s, err := %.3v;\n", v.Name(), expr) + g.Fgenf(w, "%s, err := %.3v;\n", name, expr) g.isErrAssigned = true g.Fgenf(w, "if err != nil {\n") g.Fgenf(w, "return err\n") @@ -922,24 +923,24 @@ func (g *generator) genConfigVariable(w io.Writer, v *pcl.ConfigVariable) { switch v.Type() { // Go will default to interpreting integers (i.e. 3) as ints, even if the config is Number case model.NumberType: - g.Fgenf(w, "%s := float64(%.3v);\n", v.Name(), expr) + g.Fgenf(w, "%s := float64(%.3v);\n", name, expr) default: - g.Fgenf(w, "%s := %.3v;\n", v.Name(), expr) + g.Fgenf(w, "%s := %.3v;\n", name, expr) } } switch v.Type() { case model.StringType: - g.Fgenf(w, "if param := cfg.Get(\"%s\"); param != \"\"{\n", v.Name()) + g.Fgenf(w, "if param := cfg.Get(\"%s\"); param != \"\"{\n", v.LogicalName()) case model.NumberType: - g.Fgenf(w, "if param := cfg.GetFloat64(\"%s\"); param != 0 {\n", v.Name()) + g.Fgenf(w, "if param := cfg.GetFloat64(\"%s\"); param != 0 {\n", v.LogicalName()) case model.IntType: - g.Fgenf(w, "if param := cfg.GetInt(\"%s\"); param != 0 {\n", v.Name()) + g.Fgenf(w, "if param := cfg.GetInt(\"%s\"); param != 0 {\n", v.LogicalName()) case model.BoolType: - g.Fgenf(w, "if param := cfg.GetBool(\"%s\"); param {\n", v.Name()) + g.Fgenf(w, "if param := cfg.GetBool(\"%s\"); param {\n", v.LogicalName()) default: - g.Fgenf(w, "if param := cfg.GetBool(\"%s\"); param != nil {\n", v.Name()) + g.Fgenf(w, "if param := cfg.GetBool(\"%s\"); param != nil {\n", v.LogicalName()) } - g.Fgenf(w, "%s = param\n", v.Name()) + g.Fgenf(w, "%s = param\n", name) g.Fgen(w, "}\n") } } diff --git a/pkg/codegen/nodejs/gen_program.go b/pkg/codegen/nodejs/gen_program.go index e02db5fc2976..e8caac5626ee 100644 --- a/pkg/codegen/nodejs/gen_program.go +++ b/pkg/codegen/nodejs/gen_program.go @@ -579,7 +579,9 @@ func (g *generator) genConfigVariable(w io.Writer, v *pcl.ConfigVariable) { getOrRequire = "require" } - g.Fgenf(w, "%[1]sconst %[2]s = config.%[3]s%[4]s(\"%[2]s\")", g.Indent, v.Name(), getOrRequire, getType) + name := makeValidIdentifier(v.Name()) + g.Fgenf(w, "%[1]sconst %[2]s = config.%[3]s%[4]s(\"%[5]s\")", + g.Indent, name, getOrRequire, getType, v.LogicalName()) if v.DefaultValue != nil { g.Fgenf(w, " || %.v", g.lowerExpression(v.DefaultValue, v.DefaultValue.Type())) } diff --git a/pkg/codegen/pcl/binder_nodes.go b/pkg/codegen/pcl/binder_nodes.go index e32a1e21d82e..21d66cc91655 100644 --- a/pkg/codegen/pcl/binder_nodes.go +++ b/pkg/codegen/pcl/binder_nodes.go @@ -108,6 +108,14 @@ func (b *binder) bindConfigVariable(node *ConfigVariable) hcl.Diagnostics { diagnostics = append(diagnostics, model.ExprNotConvertible(model.InputType(node.typ), node.DefaultValue)) } } + if attr, ok := block.Body.Attribute(LogicalNamePropertyKey); ok { + logicalName, lDiags := getStringAttrValue(attr) + if lDiags != nil { + diagnostics = diagnostics.Append(lDiags) + } else { + node.logicalName = logicalName + } + } node.Definition = block return diagnostics } diff --git a/pkg/codegen/pcl/config.go b/pkg/codegen/pcl/config.go index 2cb896477e4d..4a85a0724105 100644 --- a/pkg/codegen/pcl/config.go +++ b/pkg/codegen/pcl/config.go @@ -32,6 +32,11 @@ type ConfigVariable struct { Definition *model.Block // The default value for the config variable, if any. DefaultValue model.Expression + + // The name visible to API calls related to the config. Used as the argument when + // fetching config variables. Must not be modified during code generation to ensure + // that valid config calls don't become invalid. + logicalName string } // SyntaxNode returns the syntax node associated with the config variable. @@ -51,6 +56,13 @@ func (cv *ConfigVariable) Name() string { return cv.Definition.Labels[0] } +func (cv *ConfigVariable) LogicalName() string { + if cv.logicalName != "" { + return cv.logicalName + } + return cv.Name() +} + // Type returns the type of the config variable. func (cv *ConfigVariable) Type() model.Type { return cv.typ diff --git a/pkg/codegen/python/gen_program.go b/pkg/codegen/python/gen_program.go index 690d9af83719..c9dfe4f8e547 100644 --- a/pkg/codegen/python/gen_program.go +++ b/pkg/codegen/python/gen_program.go @@ -553,7 +553,7 @@ func (g *generator) genConfigVariable(w io.Writer, v *pcl.ConfigVariable) { g.genTemps(w, temps) name := PyName(v.Name()) - g.Fgenf(w, "%s%s = config.%s%s(\"%s\")\n", g.Indent, name, getOrRequire, getType, v.Name()) + g.Fgenf(w, "%s%s = config.%s%s(\"%s\")\n", g.Indent, name, getOrRequire, getType, v.LogicalName()) if defaultValue != nil { g.Fgenf(w, "%sif %s is None:\n", g.Indent, name) g.Indented(func() { diff --git a/pkg/codegen/python/python_test.go b/pkg/codegen/python/python_test.go index a83eb3ccd905..40752ebf9754 100644 --- a/pkg/codegen/python/python_test.go +++ b/pkg/codegen/python/python_test.go @@ -21,6 +21,7 @@ var pyNameTests = []struct { {"podCIDRSet", "pod_cidr_set", "pod_cidr_set"}, {"Sha256Hash", "sha256_hash", "sha256_hash"}, {"SHA256Hash", "sha256_hash", "sha256_hash"}, + {"proj:config", "proj_config", "proj_config"}, // PyName should return the legacy name for these: {"openXJsonSerDe", "open_x_json_ser_de", "open_x_json_ser_de"},