diff --git a/changelog/pending/20221104--sdkgen-go--guard-against-conflicting-field-names.yaml b/changelog/pending/20221104--sdkgen-go--guard-against-conflicting-field-names.yaml new file mode 100644 index 000000000000..9cb09fc39145 --- /dev/null +++ b/changelog/pending/20221104--sdkgen-go--guard-against-conflicting-field-names.yaml @@ -0,0 +1,4 @@ +changes: +- type: fix + scope: sdkgen/go + description: Guard against conflicting field names. diff --git a/pkg/codegen/go/gen.go b/pkg/codegen/go/gen.go index f820ff771d7c..da01ae9a0f82 100644 --- a/pkg/codegen/go/gen.go +++ b/pkg/codegen/go/gen.go @@ -1295,16 +1295,21 @@ func (pkg *pkgContext) assignProperty(w io.Writer, p *schema.Property, object, v if t != "" { value = fmt.Sprintf("%s(%s)", t, value) } - fmt.Fprintf(w, "\t%s.%s = %s\n", object, Title(p.Name), value) + fmt.Fprintf(w, "\t%s.%s = %s\n", object, pkg.fieldName(nil, p), value) } else if indirectAssign { tmpName := cgstrings.Camel(p.Name) + "_" fmt.Fprintf(w, "%s := %s\n", tmpName, value) - fmt.Fprintf(w, "%s.%s = &%s\n", object, Title(p.Name), tmpName) + fmt.Fprintf(w, "%s.%s = &%s\n", object, pkg.fieldName(nil, p), tmpName) } else { - fmt.Fprintf(w, "%s.%s = %s\n", object, Title(p.Name), value) + fmt.Fprintf(w, "%s.%s = %s\n", object, pkg.fieldName(nil, p), value) } } +func (pkg *pkgContext) fieldName(r *schema.Resource, field *schema.Property) string { + contract.Assert(field != nil) + return fieldName(pkg, r, field) +} + func (pkg *pkgContext) genPlainType(w io.Writer, name, comment, deprecationMessage string, properties []*schema.Property) { @@ -1312,7 +1317,7 @@ func (pkg *pkgContext) genPlainType(w io.Writer, name, comment, deprecationMessa fmt.Fprintf(w, "type %s struct {\n", name) for _, p := range properties { printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true) - fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", Title(p.Name), pkg.typeString(codegen.ResolvedType(p.Type)), p.Name) + fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", pkg.fieldName(nil, p), pkg.typeString(codegen.ResolvedType(p.Type)), p.Name) } fmt.Fprintf(w, "}\n\n") } @@ -1342,16 +1347,16 @@ func (pkg *pkgContext) genObjectDefaultFunc(w io.Writer, name string, return err } pkg.needsUtils = true - fmt.Fprintf(w, "if isZero(tmp.%s) {\n", Title(p.Name)) + fmt.Fprintf(w, "if isZero(tmp.%s) {\n", pkg.fieldName(nil, p)) pkg.assignProperty(w, p, "tmp", dv, !p.IsRequired()) fmt.Fprintf(w, "}\n") } else if funcName := pkg.provideDefaultsFuncName(p.Type); funcName != "" { var member string if codegen.IsNOptionalInput(p.Type) { // f := fmt.Sprintf("func(v %[1]s) %[1]s { return *v.%[2]s() }", name, funcName) - // member = fmt.Sprintf("tmp.%[1]s.ApplyT(%[2]s)", Title(p.Name), f) + // member = fmt.Sprintf("tmp.%[1]s.ApplyT(%[2]s)", pkg.fieldName(nil, p), f) } else { - member = fmt.Sprintf("tmp.%[1]s.%[2]s()", Title(p.Name), funcName) + member = fmt.Sprintf("tmp.%[1]s.%[2]s()", pkg.fieldName(nil, p), funcName) sigil := "" if p.IsRequired() { sigil = "*" @@ -1441,7 +1446,7 @@ func (pkg *pkgContext) genInputArgsStruct(w io.Writer, typeName string, t *schem fmt.Fprintf(w, "type %s struct {\n", typeName) for _, p := range t.Properties { printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true) - fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", Title(p.Name), pkg.typeString(p.Type), p.Name) + fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", pkg.fieldName(nil, p), pkg.typeString(p.Type), p.Name) } fmt.Fprintf(w, "}\n\n") } @@ -1476,14 +1481,14 @@ func (pkg *pkgContext) genOutputTypes(w io.Writer, genArgs genOutputTypesArgs) { printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, false) outputType, applyType := pkg.outputType(p.Type), pkg.typeString(p.Type) - propName := Title(p.Name) + propName := pkg.fieldName(nil, p) switch strings.ToLower(p.Name) { case "elementtype", "issecret": propName = "Get" + propName } fmt.Fprintf(w, "func (o %sOutput) %s() %s {\n", name, propName, outputType) fmt.Fprintf(w, "\treturn o.ApplyT(func (v %s) %s { return v.%s }).(%s)\n", - name, applyType, Title(p.Name), outputType) + name, applyType, pkg.fieldName(nil, p), outputType) fmt.Fprintf(w, "}\n\n") } } @@ -1515,7 +1520,7 @@ func (pkg *pkgContext) genOutputTypes(w io.Writer, genArgs genOutputTypesArgs) { fmt.Fprintf(w, "\t\tif v == nil {\n") fmt.Fprintf(w, "\t\t\treturn nil\n") fmt.Fprintf(w, "\t\t}\n") - fmt.Fprintf(w, "\t\treturn %sv.%s\n", deref, Title(p.Name)) + fmt.Fprintf(w, "\t\treturn %sv.%s\n", deref, pkg.fieldName(nil, p)) fmt.Fprintf(w, "\t}).(%s)\n", outputType) fmt.Fprintf(w, "}\n\n") } @@ -1638,7 +1643,7 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource, generateReso for _, p := range r.Properties { printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true) - fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", Title(p.Name), pkg.outputType(p.Type), p.Name) + fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", pkg.fieldName(r, p), pkg.outputType(p.Type), p.Name) if p.Secret { secretProps = append(secretProps, p) @@ -1673,8 +1678,8 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource, generateReso // Check all required inputs are present for _, p := range r.InputProperties { if p.IsRequired() && isNilType(p.Type) && p.DefaultValue == nil { - fmt.Fprintf(w, "\tif args.%s == nil {\n", Title(p.Name)) - fmt.Fprintf(w, "\t\treturn nil, errors.New(\"invalid value for required argument '%s'\")\n", Title(p.Name)) + fmt.Fprintf(w, "\tif args.%s == nil {\n", pkg.fieldName(r, p)) + fmt.Fprintf(w, "\t\treturn nil, errors.New(\"invalid value for required argument '%s'\")\n", pkg.fieldName(r, p)) fmt.Fprintf(w, "\t}\n") } @@ -1700,7 +1705,7 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource, generateReso return err } pkg.needsUtils = true - fmt.Fprintf(w, "\tif isZero(args.%s) {\n", Title(p.Name)) + fmt.Fprintf(w, "\tif isZero(args.%s) {\n", pkg.fieldName(r, p)) assign(p, dv) fmt.Fprintf(w, "\t}\n") } else if name := pkg.provideDefaultsFuncName(p.Type); name != "" && !pkg.disableObjectDefaults { @@ -1712,19 +1717,19 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource, generateReso toOutputMethod := pkg.toOutputMethod(p.Type) outputType := pkg.outputType(p.Type) resolvedType := pkg.typeString(codegen.ResolvedType(p.Type)) - originalValue := fmt.Sprintf("args.%s.%s()", Title(p.Name), toOutputMethod) + originalValue := fmt.Sprintf("args.%s.%s()", pkg.fieldName(r, p), toOutputMethod) valueWithDefaults := fmt.Sprintf("%[1]v.ApplyT(func (v %[2]s) %[2]s { return %[3]sv.%[4]s() }).(%[5]s)", originalValue, resolvedType, optionalDeref, name, outputType) if p.Plain { - valueWithDefaults = fmt.Sprintf("args.%v.Defaults()", Title(p.Name)) + valueWithDefaults = fmt.Sprintf("args.%v.Defaults()", pkg.fieldName(r, p)) } if !p.IsRequired() { - fmt.Fprintf(w, "if args.%s != nil {\n", Title(p.Name)) - fmt.Fprintf(w, "args.%[1]s = %s\n", Title(p.Name), valueWithDefaults) + fmt.Fprintf(w, "if args.%s != nil {\n", pkg.fieldName(r, p)) + fmt.Fprintf(w, "args.%[1]s = %s\n", pkg.fieldName(r, p), valueWithDefaults) fmt.Fprint(w, "}\n") } else { - fmt.Fprintf(w, "args.%[1]s = %s\n", Title(p.Name), valueWithDefaults) + fmt.Fprintf(w, "args.%[1]s = %s\n", pkg.fieldName(r, p), valueWithDefaults) } } @@ -1753,8 +1758,8 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource, generateReso // Setup secrets for _, p := range secretInputProps { - fmt.Fprintf(w, "\tif args.%s != nil {\n", Title(p.Name)) - fmt.Fprintf(w, "\t\targs.%[1]s = pulumi.ToSecret(args.%[1]s).(%[2]s)\n", Title(p.Name), pkg.outputType(p.Type)) + fmt.Fprintf(w, "\tif args.%s != nil {\n", pkg.fieldName(r, p)) + fmt.Fprintf(w, "\t\targs.%[1]s = pulumi.ToSecret(args.%[1]s).(%[2]s)\n", pkg.fieldName(r, p), pkg.outputType(p.Type)) fmt.Fprintf(w, "\t}\n") } if len(secretProps) > 0 { @@ -1817,7 +1822,7 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource, generateReso if r.StateInputs != nil { for _, p := range r.StateInputs.Properties { printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true) - fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", Title(p.Name), pkg.typeString(codegen.ResolvedType(codegen.OptionalType(p))), p.Name) + fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", pkg.fieldName(r, p), pkg.typeString(codegen.ResolvedType(codegen.OptionalType(p))), p.Name) } } fmt.Fprintf(w, "}\n\n") @@ -1826,7 +1831,7 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource, generateReso if r.StateInputs != nil { for _, p := range r.StateInputs.Properties { printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true) - fmt.Fprintf(w, "\t%s %s\n", Title(p.Name), pkg.inputType(p.Type)) + fmt.Fprintf(w, "\t%s %s\n", pkg.fieldName(r, p), pkg.inputType(p.Type)) } } fmt.Fprintf(w, "}\n\n") @@ -1840,7 +1845,7 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource, generateReso fmt.Fprintf(w, "type %sArgs struct {\n", cgstrings.Camel(name)) for _, p := range r.InputProperties { printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true) - fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", Title(p.Name), pkg.typeString(codegen.ResolvedType(p.Type)), p.Name) + fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", pkg.fieldName(r, p), pkg.typeString(codegen.ResolvedType(p.Type)), p.Name) } fmt.Fprintf(w, "}\n\n") @@ -1858,7 +1863,7 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource, generateReso } printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true) - fmt.Fprintf(w, "\t%s %s\n", Title(p.Name), pkg.typeString(typ)) + fmt.Fprintf(w, "\t%s %s\n", pkg.fieldName(r, p), pkg.typeString(typ)) } fmt.Fprintf(w, "}\n\n") @@ -1948,7 +1953,7 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource, generateReso fmt.Fprintf(w, "type %s%sArgs struct {\n", cgstrings.Camel(name), methodName) for _, p := range args { printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true) - fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", Title(p.Name), pkg.typeString(codegen.ResolvedType(p.Type)), + fmt.Fprintf(w, "\t%s %s `pulumi:\"%s\"`\n", pkg.fieldName(nil, p), pkg.typeString(codegen.ResolvedType(p.Type)), p.Name) } fmt.Fprintf(w, "}\n\n") @@ -1957,7 +1962,7 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource, generateReso fmt.Fprintf(w, "type %s%sArgs struct {\n", name, methodName) for _, p := range args { printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, true) - fmt.Fprintf(w, "\t%s %s\n", Title(p.Name), pkg.typeString(p.Type)) + fmt.Fprintf(w, "\t%s %s\n", pkg.fieldName(nil, p), pkg.typeString(p.Type)) } fmt.Fprintf(w, "}\n\n") @@ -2026,14 +2031,14 @@ func (pkg *pkgContext) genResource(w io.Writer, r *schema.Resource, generateReso printCommentWithDeprecationMessage(w, p.Comment, p.DeprecationMessage, false) outputType := pkg.outputType(p.Type) - propName := Title(p.Name) + propName := pkg.fieldName(r, p) switch strings.ToLower(p.Name) { case "elementtype", "issecret": propName = "Get" + propName } fmt.Fprintf(w, "func (o %sOutput) %s() %s {\n", name, propName, outputType) fmt.Fprintf(w, "\treturn o.ApplyT(func (v *%s) %s { return v.%s }).(%s)\n", - name, outputType, Title(p.Name), outputType) + name, outputType, pkg.fieldName(r, p), outputType) fmt.Fprintf(w, "}\n\n") } diff --git a/pkg/codegen/go/utilities.go b/pkg/codegen/go/utilities.go index b7f5635f6a3f..d914a1578d4d 100644 --- a/pkg/codegen/go/utilities.go +++ b/pkg/codegen/go/utilities.go @@ -22,6 +22,8 @@ import ( "github.com/pulumi/pulumi/pkg/v3/codegen" "github.com/pulumi/pulumi/pkg/v3/codegen/cgstrings" + "github.com/pulumi/pulumi/pkg/v3/codegen/schema" + "github.com/pulumi/pulumi/sdk/v3/go/common/util/contract" ) // isReservedWord returns true if s is a Go reserved word as per @@ -40,6 +42,21 @@ func isReservedWord(s string) bool { } } +// isReservedResourceField returns true if s would conflict with a method on a generated +// resource. +func isReservedResourceField(resourceName, s string) bool { + switch s { + case "ID", "URN", "GetProvider", "ElementType": + return true + default: + if resourceName != "" { + toOutput := "To" + resourceName + "Output" + return s == toOutput || s == toOutput+"WithContext" + } + return false + } +} + // isLegalIdentifierStart returns true if it is legal for c to be the first character of a Go identifier as per // https://golang.org/ref/spec#Identifiers func isLegalIdentifierStart(c rune) bool { @@ -120,3 +137,19 @@ func enumTitle(s string) string { return "_" + cgstrings.UppercaseFirst(next) }) } + +// Calculate the name of a field in a resource +func fieldName(pkg *pkgContext, r *schema.Resource, p *schema.Property) string { + s := Title(p.Name) + var name string + if r != nil { + name = disambiguatedResourceName(r, pkg) + } + if !isReservedResourceField(name, s) { + return s + } + + res := s + "_" + contract.Assert(!isReservedResourceField(name, res)) + return res +} diff --git a/pkg/codegen/testing/test/testdata/go-nested-collections/go/codegen-manifest.json b/pkg/codegen/testing/test/testdata/go-nested-collections/go/codegen-manifest.json index d7ea23ad8016..d92fa9d9f697 100644 --- a/pkg/codegen/testing/test/testdata/go-nested-collections/go/codegen-manifest.json +++ b/pkg/codegen/testing/test/testdata/go-nested-collections/go/codegen-manifest.json @@ -1,6 +1,9 @@ { "emittedFiles": [ "repro/doc.go", + "repro/elementtype/elementType.go", + "repro/elementtype/init.go", + "repro/elementtype/pulumiTypes.go", "repro/foo.go", "repro/init.go", "repro/overlap/consumer.go", diff --git a/pkg/codegen/testing/test/testdata/go-nested-collections/go/repro/elementtype/elementType.go b/pkg/codegen/testing/test/testdata/go-nested-collections/go/repro/elementtype/elementType.go new file mode 100644 index 000000000000..4bda26a5f394 --- /dev/null +++ b/pkg/codegen/testing/test/testdata/go-nested-collections/go/repro/elementtype/elementType.go @@ -0,0 +1,202 @@ +// Code generated by test DO NOT EDIT. +// *** WARNING: Do not edit by hand unless you're certain you know what you are doing! *** + +package elementtype + +import ( + "context" + "reflect" + + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +type ElementType struct { + pulumi.CustomResourceState + + ElementType_ ElementTypeTypePtrOutput `pulumi:"elementType"` +} + +// NewElementType registers a new resource with the given unique name, arguments, and options. +func NewElementType(ctx *pulumi.Context, + name string, args *ElementTypeArgs, opts ...pulumi.ResourceOption) (*ElementType, error) { + if args == nil { + args = &ElementTypeArgs{} + } + + var resource ElementType + err := ctx.RegisterResource("repro:elementType:ElementType", name, args, &resource, opts...) + if err != nil { + return nil, err + } + return &resource, nil +} + +// GetElementType gets an existing ElementType resource's state with the given name, ID, and optional +// state properties that are used to uniquely qualify the lookup (nil if not required). +func GetElementType(ctx *pulumi.Context, + name string, id pulumi.IDInput, state *ElementTypeState, opts ...pulumi.ResourceOption) (*ElementType, error) { + var resource ElementType + err := ctx.ReadResource("repro:elementType:ElementType", name, id, state, &resource, opts...) + if err != nil { + return nil, err + } + return &resource, nil +} + +// Input properties used for looking up and filtering ElementType resources. +type elementTypeState struct { +} + +type ElementTypeState struct { +} + +func (ElementTypeState) ElementType() reflect.Type { + return reflect.TypeOf((*elementTypeState)(nil)).Elem() +} + +type elementTypeArgs struct { +} + +// The set of arguments for constructing a ElementType resource. +type ElementTypeArgs struct { +} + +func (ElementTypeArgs) ElementType() reflect.Type { + return reflect.TypeOf((*elementTypeArgs)(nil)).Elem() +} + +type ElementTypeInput interface { + pulumi.Input + + ToElementTypeOutput() ElementTypeOutput + ToElementTypeOutputWithContext(ctx context.Context) ElementTypeOutput +} + +func (*ElementType) ElementType() reflect.Type { + return reflect.TypeOf((**ElementType)(nil)).Elem() +} + +func (i *ElementType) ToElementTypeOutput() ElementTypeOutput { + return i.ToElementTypeOutputWithContext(context.Background()) +} + +func (i *ElementType) ToElementTypeOutputWithContext(ctx context.Context) ElementTypeOutput { + return pulumi.ToOutputWithContext(ctx, i).(ElementTypeOutput) +} + +// ElementTypeArrayInput is an input type that accepts ElementTypeArray and ElementTypeArrayOutput values. +// You can construct a concrete instance of `ElementTypeArrayInput` via: +// +// ElementTypeArray{ ElementTypeArgs{...} } +type ElementTypeArrayInput interface { + pulumi.Input + + ToElementTypeArrayOutput() ElementTypeArrayOutput + ToElementTypeArrayOutputWithContext(context.Context) ElementTypeArrayOutput +} + +type ElementTypeArray []ElementTypeInput + +func (ElementTypeArray) ElementType() reflect.Type { + return reflect.TypeOf((*[]*ElementType)(nil)).Elem() +} + +func (i ElementTypeArray) ToElementTypeArrayOutput() ElementTypeArrayOutput { + return i.ToElementTypeArrayOutputWithContext(context.Background()) +} + +func (i ElementTypeArray) ToElementTypeArrayOutputWithContext(ctx context.Context) ElementTypeArrayOutput { + return pulumi.ToOutputWithContext(ctx, i).(ElementTypeArrayOutput) +} + +// ElementTypeMapInput is an input type that accepts ElementTypeMap and ElementTypeMapOutput values. +// You can construct a concrete instance of `ElementTypeMapInput` via: +// +// ElementTypeMap{ "key": ElementTypeArgs{...} } +type ElementTypeMapInput interface { + pulumi.Input + + ToElementTypeMapOutput() ElementTypeMapOutput + ToElementTypeMapOutputWithContext(context.Context) ElementTypeMapOutput +} + +type ElementTypeMap map[string]ElementTypeInput + +func (ElementTypeMap) ElementType() reflect.Type { + return reflect.TypeOf((*map[string]*ElementType)(nil)).Elem() +} + +func (i ElementTypeMap) ToElementTypeMapOutput() ElementTypeMapOutput { + return i.ToElementTypeMapOutputWithContext(context.Background()) +} + +func (i ElementTypeMap) ToElementTypeMapOutputWithContext(ctx context.Context) ElementTypeMapOutput { + return pulumi.ToOutputWithContext(ctx, i).(ElementTypeMapOutput) +} + +type ElementTypeOutput struct{ *pulumi.OutputState } + +func (ElementTypeOutput) ElementType() reflect.Type { + return reflect.TypeOf((**ElementType)(nil)).Elem() +} + +func (o ElementTypeOutput) ToElementTypeOutput() ElementTypeOutput { + return o +} + +func (o ElementTypeOutput) ToElementTypeOutputWithContext(ctx context.Context) ElementTypeOutput { + return o +} + +func (o ElementTypeOutput) GetElementType_() ElementTypeTypePtrOutput { + return o.ApplyT(func(v *ElementType) ElementTypeTypePtrOutput { return v.ElementType_ }).(ElementTypeTypePtrOutput) +} + +type ElementTypeArrayOutput struct{ *pulumi.OutputState } + +func (ElementTypeArrayOutput) ElementType() reflect.Type { + return reflect.TypeOf((*[]*ElementType)(nil)).Elem() +} + +func (o ElementTypeArrayOutput) ToElementTypeArrayOutput() ElementTypeArrayOutput { + return o +} + +func (o ElementTypeArrayOutput) ToElementTypeArrayOutputWithContext(ctx context.Context) ElementTypeArrayOutput { + return o +} + +func (o ElementTypeArrayOutput) Index(i pulumi.IntInput) ElementTypeOutput { + return pulumi.All(o, i).ApplyT(func(vs []interface{}) *ElementType { + return vs[0].([]*ElementType)[vs[1].(int)] + }).(ElementTypeOutput) +} + +type ElementTypeMapOutput struct{ *pulumi.OutputState } + +func (ElementTypeMapOutput) ElementType() reflect.Type { + return reflect.TypeOf((*map[string]*ElementType)(nil)).Elem() +} + +func (o ElementTypeMapOutput) ToElementTypeMapOutput() ElementTypeMapOutput { + return o +} + +func (o ElementTypeMapOutput) ToElementTypeMapOutputWithContext(ctx context.Context) ElementTypeMapOutput { + return o +} + +func (o ElementTypeMapOutput) MapIndex(k pulumi.StringInput) ElementTypeOutput { + return pulumi.All(o, k).ApplyT(func(vs []interface{}) *ElementType { + return vs[0].(map[string]*ElementType)[vs[1].(string)] + }).(ElementTypeOutput) +} + +func init() { + pulumi.RegisterInputType(reflect.TypeOf((*ElementTypeInput)(nil)).Elem(), &ElementType{}) + pulumi.RegisterInputType(reflect.TypeOf((*ElementTypeArrayInput)(nil)).Elem(), ElementTypeArray{}) + pulumi.RegisterInputType(reflect.TypeOf((*ElementTypeMapInput)(nil)).Elem(), ElementTypeMap{}) + pulumi.RegisterOutputType(ElementTypeOutput{}) + pulumi.RegisterOutputType(ElementTypeArrayOutput{}) + pulumi.RegisterOutputType(ElementTypeMapOutput{}) +} diff --git a/pkg/codegen/testing/test/testdata/go-nested-collections/go/repro/elementtype/init.go b/pkg/codegen/testing/test/testdata/go-nested-collections/go/repro/elementtype/init.go new file mode 100644 index 000000000000..d47a365f4945 --- /dev/null +++ b/pkg/codegen/testing/test/testdata/go-nested-collections/go/repro/elementtype/init.go @@ -0,0 +1,44 @@ +// Code generated by test DO NOT EDIT. +// *** WARNING: Do not edit by hand unless you're certain you know what you are doing! *** + +package elementtype + +import ( + "fmt" + + "github.com/blang/semver" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + "go-nested-collections/repro" +) + +type module struct { + version semver.Version +} + +func (m *module) Version() semver.Version { + return m.version +} + +func (m *module) Construct(ctx *pulumi.Context, name, typ, urn string) (r pulumi.Resource, err error) { + switch typ { + case "repro:elementType:ElementType": + r = &ElementType{} + default: + return nil, fmt.Errorf("unknown resource type: %s", typ) + } + + err = ctx.RegisterResource(typ, name, nil, r, pulumi.URN_(urn)) + return +} + +func init() { + version, err := repro.PkgVersion() + if err != nil { + version = semver.Version{Major: 1} + } + pulumi.RegisterResourceModule( + "repro", + "elementType", + &module{version}, + ) +} diff --git a/pkg/codegen/testing/test/testdata/go-nested-collections/go/repro/elementtype/pulumiTypes.go b/pkg/codegen/testing/test/testdata/go-nested-collections/go/repro/elementtype/pulumiTypes.go new file mode 100644 index 000000000000..d0cce7e731f3 --- /dev/null +++ b/pkg/codegen/testing/test/testdata/go-nested-collections/go/repro/elementtype/pulumiTypes.go @@ -0,0 +1,71 @@ +// Code generated by test DO NOT EDIT. +// *** WARNING: Do not edit by hand unless you're certain you know what you are doing! *** + +package elementtype + +import ( + "context" + "reflect" + + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +type ElementTypeType struct { + ElementType_ *string `pulumi:"elementType"` +} + +type ElementTypeTypeOutput struct{ *pulumi.OutputState } + +func (ElementTypeTypeOutput) ElementType() reflect.Type { + return reflect.TypeOf((*ElementTypeType)(nil)).Elem() +} + +func (o ElementTypeTypeOutput) ToElementTypeTypeOutput() ElementTypeTypeOutput { + return o +} + +func (o ElementTypeTypeOutput) ToElementTypeTypeOutputWithContext(ctx context.Context) ElementTypeTypeOutput { + return o +} + +func (o ElementTypeTypeOutput) GetElementType_() pulumi.StringPtrOutput { + return o.ApplyT(func(v ElementTypeType) *string { return v.ElementType_ }).(pulumi.StringPtrOutput) +} + +type ElementTypeTypePtrOutput struct{ *pulumi.OutputState } + +func (ElementTypeTypePtrOutput) ElementType() reflect.Type { + return reflect.TypeOf((**ElementTypeType)(nil)).Elem() +} + +func (o ElementTypeTypePtrOutput) ToElementTypeTypePtrOutput() ElementTypeTypePtrOutput { + return o +} + +func (o ElementTypeTypePtrOutput) ToElementTypeTypePtrOutputWithContext(ctx context.Context) ElementTypeTypePtrOutput { + return o +} + +func (o ElementTypeTypePtrOutput) Elem() ElementTypeTypeOutput { + return o.ApplyT(func(v *ElementTypeType) ElementTypeType { + if v != nil { + return *v + } + var ret ElementTypeType + return ret + }).(ElementTypeTypeOutput) +} + +func (o ElementTypeTypePtrOutput) ElementTypeProp() pulumi.StringPtrOutput { + return o.ApplyT(func(v *ElementTypeType) *string { + if v == nil { + return nil + } + return v.ElementType_ + }).(pulumi.StringPtrOutput) +} + +func init() { + pulumi.RegisterOutputType(ElementTypeTypeOutput{}) + pulumi.RegisterOutputType(ElementTypeTypePtrOutput{}) +} diff --git a/pkg/codegen/testing/test/testdata/go-nested-collections/schema.json b/pkg/codegen/testing/test/testdata/go-nested-collections/schema.json index 6594b7e0f692..784924ab0c88 100644 --- a/pkg/codegen/testing/test/testdata/go-nested-collections/schema.json +++ b/pkg/codegen/testing/test/testdata/go-nested-collections/schema.json @@ -32,9 +32,20 @@ } } } + }, + "repro:elementType:ElementType": { + "properties": { + "elementType": { "$ref": "#/types/repro:elementType:ElementType" } + } } }, "types": { + "repro:elementType:ElementType": { + "type": "object", + "properties": { + "elementType": { "type": "string" } + } + }, "repro:index:Bar": { "type": "object", "properties": { diff --git a/sdk/python/lib/pulumi/automation/_project_settings.py b/sdk/python/lib/pulumi/automation/_project_settings.py index 33f70af9aabe..d15d6a35ab8f 100644 --- a/sdk/python/lib/pulumi/automation/_project_settings.py +++ b/sdk/python/lib/pulumi/automation/_project_settings.py @@ -56,7 +56,7 @@ def __init__( self, description: Optional[str] = None, quickstart: Optional[str] = None, - config: Mapping[str, ProjectTemplateConfigValue] = None, + config: Optional[Mapping[str, ProjectTemplateConfigValue]] = None, important: Optional[bool] = None, ): self.description = description diff --git a/sdk/python/lib/pulumi/automation/events.py b/sdk/python/lib/pulumi/automation/events.py index 9afae4e19503..978237d43be0 100644 --- a/sdk/python/lib/pulumi/automation/events.py +++ b/sdk/python/lib/pulumi/automation/events.py @@ -347,8 +347,8 @@ def __init__( custom: Optional[bool] = None, delete: Optional[bool] = None, protect: Optional[bool] = None, - inputs: Mapping[str, Any] = None, - outputs: Mapping[str, Any] = None, + inputs: Optional[Mapping[str, Any]] = None, + outputs: Optional[Mapping[str, Any]] = None, init_errors: Optional[List[str]] = None, ): self.type = type diff --git a/sdk/python/lib/pulumi/resource.py b/sdk/python/lib/pulumi/resource.py index 41beb37c926b..fcbc44c5d3a5 100644 --- a/sdk/python/lib/pulumi/resource.py +++ b/sdk/python/lib/pulumi/resource.py @@ -1251,8 +1251,8 @@ def create_urn( name: "Input[str]", type_: "Input[str]", parent: Optional[Union["Resource", "Input[str]"]] = None, - project: str = None, - stack: str = None, + project: Optional[str] = None, + stack: Optional[str] = None, ) -> "Output[str]": """ create_urn computes a URN from the combination of a resource name, resource type, optional