diff --git a/pkg/codegen/internal/test/testdata/resource-args-python/nodejs/package.json b/pkg/codegen/internal/test/testdata/resource-args-python/nodejs/package.json
index 9ac06bdfc..63e5dd7b9 100644
--- a/pkg/codegen/internal/test/testdata/resource-args-python/nodejs/package.json
+++ b/pkg/codegen/internal/test/testdata/resource-args-python/nodejs/package.json
@@ -4,11 +4,11 @@
"scripts": {
"build": "tsc"
},
- "devDependencies": {
- "typescript": "^4.3.5"
+ "dependencies": {
+ "@pulumi/pulumi": "^3.12"
},
- "peerDependencies": {
- "@pulumi/pulumi": "latest"
+ "devDependencies": {
+ "typescript": "^3.7.0"
},
"pulumi": {
"resource": true
diff --git a/pkg/codegen/internal/test/testdata/resource-args-python/schema.json b/pkg/codegen/internal/test/testdata/resource-args-python/schema.json
index 1799f0c11..55e963b77 100644
--- a/pkg/codegen/internal/test/testdata/resource-args-python/schema.json
+++ b/pkg/codegen/internal/test/testdata/resource-args-python/schema.json
@@ -52,11 +52,22 @@
}
},
"language": {
- "csharp": {},
+ "csharp": {
+ "packageReferences": {
+ "Pulumi": "3.12.0"
+ }
+ },
"go": {
"generateResourceContainerTypes": true
},
- "nodejs": {},
+ "nodejs": {
+ "dependencies": {
+ "@pulumi/pulumi": "^3.12"
+ },
+ "devDependencies": {
+ "typescript": "^3.7.0"
+ }
+ },
"python": {}
}
}
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/_index.md b/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/_index.md
new file mode 100644
index 000000000..7ab5533fd
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/_index.md
@@ -0,0 +1,30 @@
+---
+title: "example"
+title_tag: "example.example"
+meta_desc: ""
+menu:
+ reference:
+ parent: API Reference
+---
+
+
+
+
+
+
+Resources
+
+
+Package Details
+
+ - Repository
+
+ - License
+
+ - Version
+ - 0.0.1
+
+
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/provider/_index.md b/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/provider/_index.md
new file mode 100644
index 000000000..15bd29e34
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/provider/_index.md
@@ -0,0 +1,239 @@
+
+---
+title: "Provider"
+title_tag: "example.Provider"
+meta_desc: "Documentation for the example.Provider resource with examples, input properties, output properties, lookup functions, and supporting types."
+---
+
+
+
+
+
+
+
+
+
+## Create a Provider Resource {#create}
+{{< chooser language "typescript,python,go,csharp" / >}}
+
+
+{{% choosable language nodejs %}}
+
+{{% /choosable %}}
+
+{{% choosable language python %}}
+
+{{% /choosable %}}
+
+{{% choosable language go %}}
+
+{{% /choosable %}}
+
+{{% choosable language csharp %}}
+
+{{% /choosable %}}
+
+{{% choosable language nodejs %}}
+
+-
+ name
+
+ string
+
+ - The unique name of the resource.
-
+ args
+
+ ProviderArgs
+
+ - The arguments to resource properties.
-
+ opts
+
+ CustomResourceOptions
+
+ - Bag of options to control resource's behavior.
+
+{{% /choosable %}}
+
+{{% choosable language python %}}
+
+-
+ resource_name
+
+ str
+
+ - The unique name of the resource.
-
+ args
+
+ ProviderArgs
+
+ - The arguments to resource properties.
-
+ opts
+
+ ResourceOptions
+
+ - Bag of options to control resource's behavior.
+
+{{% /choosable %}}
+
+{{% choosable language go %}}
+
+-
+ ctx
+
+ Context
+
+ - Context object for the current deployment.
-
+ name
+
+ string
+
+ - The unique name of the resource.
-
+ args
+
+ ProviderArgs
+
+ - The arguments to resource properties.
-
+ opts
+
+ ResourceOption
+
+ - Bag of options to control resource's behavior.
+
+{{% /choosable %}}
+
+{{% choosable language csharp %}}
+
+-
+ name
+
+ string
+
+ - The unique name of the resource.
-
+ args
+
+ ProviderArgs
+
+ - The arguments to resource properties.
-
+ opts
+
+ CustomResourceOptions
+
+ - Bag of options to control resource's behavior.
+
+{{% /choosable %}}
+
+## Provider Resource Properties {#properties}
+
+To learn more about resource properties and how to use them, see [Inputs and Outputs]({{< relref "/docs/intro/concepts/inputs-outputs" >}}) in the Architecture and Concepts docs.
+
+### Inputs
+
+The Provider resource accepts the following [input]({{< relref "/docs/intro/concepts/inputs-outputs" >}}) properties:
+
+
+
+{{% choosable language csharp %}}
+
+{{% /choosable %}}
+
+{{% choosable language go %}}
+
+{{% /choosable %}}
+
+{{% choosable language nodejs %}}
+
+{{% /choosable %}}
+
+{{% choosable language python %}}
+
+{{% /choosable %}}
+
+
+### Outputs
+
+All [input](#inputs) properties are implicitly available as output properties. Additionally, the Provider resource produces the following output properties:
+
+
+
+{{% choosable language csharp %}}
+-
+
+Id
+
+
+ string
+
+ - {{% md %}}The provider-assigned unique ID for this managed resource.{{% /md %}}
+{{% /choosable %}}
+
+{{% choosable language go %}}
+-
+
+Id
+
+
+ string
+
+ - {{% md %}}The provider-assigned unique ID for this managed resource.{{% /md %}}
+{{% /choosable %}}
+
+{{% choosable language nodejs %}}
+-
+
+id
+
+
+ string
+
+ - {{% md %}}The provider-assigned unique ID for this managed resource.{{% /md %}}
+{{% /choosable %}}
+
+{{% choosable language python %}}
+-
+
+id
+
+
+ str
+
+ - {{% md %}}The provider-assigned unique ID for this managed resource.{{% /md %}}
+{{% /choosable %}}
+
+
+
+
+
+
+
+
+Package Details
+
+ - Repository
+
+ - License
+
+
+
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/rec/_index.md b/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/rec/_index.md
new file mode 100644
index 000000000..fcf15621a
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/docs/rec/_index.md
@@ -0,0 +1,271 @@
+
+---
+title: "Rec"
+title_tag: "example.Rec"
+meta_desc: "Documentation for the example.Rec resource with examples, input properties, output properties, lookup functions, and supporting types."
+---
+
+
+
+
+
+
+
+
+
+## Create a Rec Resource {#create}
+{{< chooser language "typescript,python,go,csharp" / >}}
+
+
+{{% choosable language nodejs %}}
+
+{{% /choosable %}}
+
+{{% choosable language python %}}
+
+{{% /choosable %}}
+
+{{% choosable language go %}}
+
+{{% /choosable %}}
+
+{{% choosable language csharp %}}
+
+{{% /choosable %}}
+
+{{% choosable language nodejs %}}
+
+-
+ name
+
+ string
+
+ - The unique name of the resource.
-
+ args
+
+ RecArgs
+
+ - The arguments to resource properties.
-
+ opts
+
+ CustomResourceOptions
+
+ - Bag of options to control resource's behavior.
+
+{{% /choosable %}}
+
+{{% choosable language python %}}
+
+-
+ resource_name
+
+ str
+
+ - The unique name of the resource.
-
+ args
+
+ RecArgs
+
+ - The arguments to resource properties.
-
+ opts
+
+ ResourceOptions
+
+ - Bag of options to control resource's behavior.
+
+{{% /choosable %}}
+
+{{% choosable language go %}}
+
+-
+ ctx
+
+ Context
+
+ - Context object for the current deployment.
-
+ name
+
+ string
+
+ - The unique name of the resource.
-
+ args
+
+ RecArgs
+
+ - The arguments to resource properties.
-
+ opts
+
+ ResourceOption
+
+ - Bag of options to control resource's behavior.
+
+{{% /choosable %}}
+
+{{% choosable language csharp %}}
+
+-
+ name
+
+ string
+
+ - The unique name of the resource.
-
+ args
+
+ RecArgs
+
+ - The arguments to resource properties.
-
+ opts
+
+ CustomResourceOptions
+
+ - Bag of options to control resource's behavior.
+
+{{% /choosable %}}
+
+## Rec Resource Properties {#properties}
+
+To learn more about resource properties and how to use them, see [Inputs and Outputs]({{< relref "/docs/intro/concepts/inputs-outputs" >}}) in the Architecture and Concepts docs.
+
+### Inputs
+
+The Rec resource accepts the following [input]({{< relref "/docs/intro/concepts/inputs-outputs" >}}) properties:
+
+
+
+{{% choosable language csharp %}}
+
+{{% /choosable %}}
+
+{{% choosable language go %}}
+
+{{% /choosable %}}
+
+{{% choosable language nodejs %}}
+
+{{% /choosable %}}
+
+{{% choosable language python %}}
+
+{{% /choosable %}}
+
+
+### Outputs
+
+All [input](#inputs) properties are implicitly available as output properties. Additionally, the Rec resource produces the following output properties:
+
+
+
+{{% choosable language csharp %}}
+-
+
+Id
+
+
+ string
+
+ - {{% md %}}The provider-assigned unique ID for this managed resource.{{% /md %}}
-
+
+Rec
+
+
+ Rec
+
+ - {{% md %}}{{% /md %}}
+{{% /choosable %}}
+
+{{% choosable language go %}}
+-
+
+Id
+
+
+ string
+
+ - {{% md %}}The provider-assigned unique ID for this managed resource.{{% /md %}}
-
+
+Rec
+
+
+ Rec
+
+ - {{% md %}}{{% /md %}}
+{{% /choosable %}}
+
+{{% choosable language nodejs %}}
+-
+
+id
+
+
+ string
+
+ - {{% md %}}The provider-assigned unique ID for this managed resource.{{% /md %}}
-
+
+rec
+
+
+ Rec
+
+ - {{% md %}}{{% /md %}}
+{{% /choosable %}}
+
+{{% choosable language python %}}
+-
+
+id
+
+
+ str
+
+ - {{% md %}}The provider-assigned unique ID for this managed resource.{{% /md %}}
-
+
+rec
+
+
+ Any
+
+ - {{% md %}}{{% /md %}}
+{{% /choosable %}}
+
+
+
+
+
+
+
+
+Package Details
+
+ - Repository
+
+ - License
+
+
+
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Provider.cs b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Provider.cs
new file mode 100644
index 000000000..d730dadcd
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Provider.cs
@@ -0,0 +1,46 @@
+// *** WARNING: this file was generated by test. ***
+// *** Do not edit by hand unless you're certain you know what you are doing! ***
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Threading.Tasks;
+using Pulumi.Serialization;
+
+namespace Pulumi.Example
+{
+ [ExampleResourceType("pulumi:providers:example")]
+ public partial class Provider : Pulumi.ProviderResource
+ {
+ ///
+ /// Create a Provider resource with the given unique name, arguments, and options.
+ ///
+ ///
+ /// The unique name of the resource
+ /// The arguments used to populate this resource's properties
+ /// A bag of options that control this resource's behavior
+ public Provider(string name, ProviderArgs? args = null, CustomResourceOptions? options = null)
+ : base("example", name, args ?? new ProviderArgs(), MakeResourceOptions(options, ""))
+ {
+ }
+
+ private static CustomResourceOptions MakeResourceOptions(CustomResourceOptions? options, Input? id)
+ {
+ var defaultOptions = new CustomResourceOptions
+ {
+ Version = Utilities.Version,
+ };
+ var merged = CustomResourceOptions.Merge(defaultOptions, options);
+ // Override the ID if one was specified for consistency with other language SDKs.
+ merged.Id = id ?? merged.Id;
+ return merged;
+ }
+ }
+
+ public sealed class ProviderArgs : Pulumi.ResourceArgs
+ {
+ public ProviderArgs()
+ {
+ }
+ }
+}
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Pulumi.Example.csproj b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Pulumi.Example.csproj
new file mode 100644
index 000000000..6d53245f3
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Pulumi.Example.csproj
@@ -0,0 +1,53 @@
+
+
+
+ true
+ Pulumi Corp.
+ Pulumi Corp.
+
+
+
+
+ logo.png
+
+ netcoreapp3.1
+ enable
+ false
+
+
+
+ true
+ 1701;1702;1591
+
+
+
+ $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
+ true
+ true
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+
+
+
+
+
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/README.md b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/README.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Rec.cs b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Rec.cs
new file mode 100644
index 000000000..c5a8e2480
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Rec.cs
@@ -0,0 +1,67 @@
+// *** WARNING: this file was generated by test. ***
+// *** Do not edit by hand unless you're certain you know what you are doing! ***
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Threading.Tasks;
+using Pulumi.Serialization;
+
+namespace Pulumi.Example
+{
+ [ExampleResourceType("example::Rec")]
+ public partial class Rec : Pulumi.CustomResource
+ {
+ [Output("rec")]
+ public Output Rec { get; private set; } = null!;
+
+
+ ///
+ /// Create a Rec resource with the given unique name, arguments, and options.
+ ///
+ ///
+ /// The unique name of the resource
+ /// The arguments used to populate this resource's properties
+ /// A bag of options that control this resource's behavior
+ public Rec(string name, RecArgs? args = null, CustomResourceOptions? options = null)
+ : base("example::Rec", name, args ?? new RecArgs(), MakeResourceOptions(options, ""))
+ {
+ }
+
+ private Rec(string name, Input id, CustomResourceOptions? options = null)
+ : base("example::Rec", name, null, MakeResourceOptions(options, id))
+ {
+ }
+
+ private static CustomResourceOptions MakeResourceOptions(CustomResourceOptions? options, Input? id)
+ {
+ var defaultOptions = new CustomResourceOptions
+ {
+ Version = Utilities.Version,
+ };
+ var merged = CustomResourceOptions.Merge(defaultOptions, options);
+ // Override the ID if one was specified for consistency with other language SDKs.
+ merged.Id = id ?? merged.Id;
+ return merged;
+ }
+ ///
+ /// Get an existing Rec resource's state with the given name, ID, and optional extra
+ /// properties used to qualify the lookup.
+ ///
+ ///
+ /// The unique name of the resulting resource.
+ /// The unique provider ID of the resource to lookup.
+ /// A bag of options that control this resource's behavior
+ public static Rec Get(string name, Input id, CustomResourceOptions? options = null)
+ {
+ return new Rec(name, id, options);
+ }
+ }
+
+ public sealed class RecArgs : Pulumi.ResourceArgs
+ {
+ public RecArgs()
+ {
+ }
+ }
+}
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Utilities.cs b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Utilities.cs
new file mode 100644
index 000000000..e99f7fe43
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/Utilities.cs
@@ -0,0 +1,87 @@
+// *** WARNING: this file was generated by test. ***
+// *** Do not edit by hand unless you're certain you know what you are doing! ***
+
+using System;
+using System.IO;
+using System.Reflection;
+using Pulumi;
+
+namespace Pulumi.Example
+{
+ static class Utilities
+ {
+ public static string? GetEnv(params string[] names)
+ {
+ foreach (var n in names)
+ {
+ var value = Environment.GetEnvironmentVariable(n);
+ if (value != null)
+ {
+ return value;
+ }
+ }
+ return null;
+ }
+
+ static string[] trueValues = { "1", "t", "T", "true", "TRUE", "True" };
+ static string[] falseValues = { "0", "f", "F", "false", "FALSE", "False" };
+ public static bool? GetEnvBoolean(params string[] names)
+ {
+ var s = GetEnv(names);
+ if (s != null)
+ {
+ if (Array.IndexOf(trueValues, s) != -1)
+ {
+ return true;
+ }
+ if (Array.IndexOf(falseValues, s) != -1)
+ {
+ return false;
+ }
+ }
+ return null;
+ }
+
+ public static int? GetEnvInt32(params string[] names) => int.TryParse(GetEnv(names), out int v) ? (int?)v : null;
+
+ public static double? GetEnvDouble(params string[] names) => double.TryParse(GetEnv(names), out double v) ? (double?)v : null;
+
+ public static InvokeOptions WithVersion(this InvokeOptions? options)
+ {
+ if (options?.Version != null)
+ {
+ return options;
+ }
+ return new InvokeOptions
+ {
+ Parent = options?.Parent,
+ Provider = options?.Provider,
+ Version = Version,
+ };
+ }
+
+ private readonly static string version;
+ public static string Version => version;
+
+ static Utilities()
+ {
+ var assembly = typeof(Utilities).GetTypeInfo().Assembly;
+ using var stream = assembly.GetManifestResourceStream("Pulumi.Example.version.txt");
+ using var reader = new StreamReader(stream ?? throw new NotSupportedException("Missing embedded version.txt file"));
+ version = reader.ReadToEnd().Trim();
+ var parts = version.Split("\n");
+ if (parts.Length == 2)
+ {
+ // The first part is the provider name.
+ version = parts[1].Trim();
+ }
+ }
+ }
+
+ internal sealed class ExampleResourceTypeAttribute : Pulumi.ResourceTypeAttribute
+ {
+ public ExampleResourceTypeAttribute(string type) : base(type, Utilities.Version)
+ {
+ }
+ }
+}
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/logo.png b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/logo.png
new file mode 100644
index 000000000..181f421e9
Binary files /dev/null and b/pkg/codegen/internal/test/testdata/resource-property-overlap/dotnet/logo.png differ
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/doc.go b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/doc.go
new file mode 100644
index 000000000..24cd778aa
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/doc.go
@@ -0,0 +1,3 @@
+// Package example exports types, functions, subpackages for provisioning example resources.
+//
+package example
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/init.go b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/init.go
new file mode 100644
index 000000000..bba613c6f
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/init.go
@@ -0,0 +1,65 @@
+// *** WARNING: this file was generated by test. ***
+// *** Do not edit by hand unless you're certain you know what you are doing! ***
+
+package example
+
+import (
+ "fmt"
+
+ "github.com/blang/semver"
+ "github.com/pulumi/pulumi/sdk/v3/go/pulumi"
+)
+
+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 "example::Rec":
+ r = &Rec{}
+ default:
+ return nil, fmt.Errorf("unknown resource type: %s", typ)
+ }
+
+ err = ctx.RegisterResource(typ, name, nil, r, pulumi.URN_(urn))
+ return
+}
+
+type pkg struct {
+ version semver.Version
+}
+
+func (p *pkg) Version() semver.Version {
+ return p.version
+}
+
+func (p *pkg) ConstructProvider(ctx *pulumi.Context, name, typ, urn string) (pulumi.ProviderResource, error) {
+ if typ != "pulumi:providers:example" {
+ return nil, fmt.Errorf("unknown provider type: %s", typ)
+ }
+
+ r := &Provider{}
+ err := ctx.RegisterResource(typ, name, nil, r, pulumi.URN_(urn))
+ return r, err
+}
+
+func init() {
+ version, err := PkgVersion()
+ if err != nil {
+ fmt.Printf("failed to determine package version. defaulting to v1: %v\n", err)
+ }
+ pulumi.RegisterResourceModule(
+ "example",
+ "",
+ &module{version},
+ )
+ pulumi.RegisterResourcePackage(
+ "example",
+ &pkg{version},
+ )
+}
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/provider.go b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/provider.go
new file mode 100644
index 000000000..3d9e18032
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/provider.go
@@ -0,0 +1,142 @@
+// *** WARNING: this file was generated by test. ***
+// *** Do not edit by hand unless you're certain you know what you are doing! ***
+
+package example
+
+import (
+ "context"
+ "reflect"
+
+ "github.com/pulumi/pulumi/sdk/v3/go/pulumi"
+)
+
+type Provider struct {
+ pulumi.ProviderResourceState
+}
+
+// NewProvider registers a new resource with the given unique name, arguments, and options.
+func NewProvider(ctx *pulumi.Context,
+ name string, args *ProviderArgs, opts ...pulumi.ResourceOption) (*Provider, error) {
+ if args == nil {
+ args = &ProviderArgs{}
+ }
+
+ var resource Provider
+ err := ctx.RegisterResource("pulumi:providers:example", name, args, &resource, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return &resource, nil
+}
+
+type providerArgs struct {
+}
+
+// The set of arguments for constructing a Provider resource.
+type ProviderArgs struct {
+}
+
+func (ProviderArgs) ElementType() reflect.Type {
+ return reflect.TypeOf((*providerArgs)(nil)).Elem()
+}
+
+type ProviderInput interface {
+ pulumi.Input
+
+ ToProviderOutput() ProviderOutput
+ ToProviderOutputWithContext(ctx context.Context) ProviderOutput
+}
+
+func (*Provider) ElementType() reflect.Type {
+ return reflect.TypeOf((*Provider)(nil))
+}
+
+func (i *Provider) ToProviderOutput() ProviderOutput {
+ return i.ToProviderOutputWithContext(context.Background())
+}
+
+func (i *Provider) ToProviderOutputWithContext(ctx context.Context) ProviderOutput {
+ return pulumi.ToOutputWithContext(ctx, i).(ProviderOutput)
+}
+
+func (i *Provider) ToProviderPtrOutput() ProviderPtrOutput {
+ return i.ToProviderPtrOutputWithContext(context.Background())
+}
+
+func (i *Provider) ToProviderPtrOutputWithContext(ctx context.Context) ProviderPtrOutput {
+ return pulumi.ToOutputWithContext(ctx, i).(ProviderPtrOutput)
+}
+
+type ProviderPtrInput interface {
+ pulumi.Input
+
+ ToProviderPtrOutput() ProviderPtrOutput
+ ToProviderPtrOutputWithContext(ctx context.Context) ProviderPtrOutput
+}
+
+type providerPtrType ProviderArgs
+
+func (*providerPtrType) ElementType() reflect.Type {
+ return reflect.TypeOf((**Provider)(nil))
+}
+
+func (i *providerPtrType) ToProviderPtrOutput() ProviderPtrOutput {
+ return i.ToProviderPtrOutputWithContext(context.Background())
+}
+
+func (i *providerPtrType) ToProviderPtrOutputWithContext(ctx context.Context) ProviderPtrOutput {
+ return pulumi.ToOutputWithContext(ctx, i).(ProviderPtrOutput)
+}
+
+type ProviderOutput struct{ *pulumi.OutputState }
+
+func (ProviderOutput) ElementType() reflect.Type {
+ return reflect.TypeOf((*Provider)(nil))
+}
+
+func (o ProviderOutput) ToProviderOutput() ProviderOutput {
+ return o
+}
+
+func (o ProviderOutput) ToProviderOutputWithContext(ctx context.Context) ProviderOutput {
+ return o
+}
+
+func (o ProviderOutput) ToProviderPtrOutput() ProviderPtrOutput {
+ return o.ToProviderPtrOutputWithContext(context.Background())
+}
+
+func (o ProviderOutput) ToProviderPtrOutputWithContext(ctx context.Context) ProviderPtrOutput {
+ return o.ApplyTWithContext(ctx, func(_ context.Context, v Provider) *Provider {
+ return &v
+ }).(ProviderPtrOutput)
+}
+
+type ProviderPtrOutput struct{ *pulumi.OutputState }
+
+func (ProviderPtrOutput) ElementType() reflect.Type {
+ return reflect.TypeOf((**Provider)(nil))
+}
+
+func (o ProviderPtrOutput) ToProviderPtrOutput() ProviderPtrOutput {
+ return o
+}
+
+func (o ProviderPtrOutput) ToProviderPtrOutputWithContext(ctx context.Context) ProviderPtrOutput {
+ return o
+}
+
+func (o ProviderPtrOutput) Elem() ProviderOutput {
+ return o.ApplyT(func(v *Provider) Provider {
+ if v != nil {
+ return *v
+ }
+ var ret Provider
+ return ret
+ }).(ProviderOutput)
+}
+
+func init() {
+ pulumi.RegisterOutputType(ProviderOutput{})
+ pulumi.RegisterOutputType(ProviderPtrOutput{})
+}
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/pulumiUtilities.go b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/pulumiUtilities.go
new file mode 100644
index 000000000..61e44b2aa
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/pulumiUtilities.go
@@ -0,0 +1,77 @@
+// *** WARNING: this file was generated by test. ***
+// *** Do not edit by hand unless you're certain you know what you are doing! ***
+
+package example
+
+import (
+ "fmt"
+ "os"
+ "reflect"
+ "regexp"
+ "strconv"
+ "strings"
+
+ "github.com/blang/semver"
+ "github.com/pulumi/pulumi/sdk/v3/go/pulumi"
+)
+
+type envParser func(v string) interface{}
+
+func parseEnvBool(v string) interface{} {
+ b, err := strconv.ParseBool(v)
+ if err != nil {
+ return nil
+ }
+ return b
+}
+
+func parseEnvInt(v string) interface{} {
+ i, err := strconv.ParseInt(v, 0, 0)
+ if err != nil {
+ return nil
+ }
+ return int(i)
+}
+
+func parseEnvFloat(v string) interface{} {
+ f, err := strconv.ParseFloat(v, 64)
+ if err != nil {
+ return nil
+ }
+ return f
+}
+
+func parseEnvStringArray(v string) interface{} {
+ var result pulumi.StringArray
+ for _, item := range strings.Split(v, ";") {
+ result = append(result, pulumi.String(item))
+ }
+ return result
+}
+
+func getEnvOrDefault(def interface{}, parser envParser, vars ...string) interface{} {
+ for _, v := range vars {
+ if value := os.Getenv(v); value != "" {
+ if parser != nil {
+ return parser(value)
+ }
+ return value
+ }
+ }
+ return def
+}
+
+// PkgVersion uses reflection to determine the version of the current package.
+func PkgVersion() (semver.Version, error) {
+ type sentinal struct{}
+ pkgPath := reflect.TypeOf(sentinal{}).PkgPath()
+ re := regexp.MustCompile("^.*/pulumi-example/sdk(/v\\d+)?")
+ if match := re.FindStringSubmatch(pkgPath); match != nil {
+ vStr := match[1]
+ if len(vStr) == 0 { // If the version capture group was empty, default to v1.
+ return semver.Version{Major: 1}, nil
+ }
+ return semver.MustParse(fmt.Sprintf("%s.0.0", vStr[2:])), nil
+ }
+ return semver.Version{}, fmt.Errorf("failed to determine the package version from %s", pkgPath)
+}
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/rec.go b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/rec.go
new file mode 100644
index 000000000..f0fa1cb92
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/go/example/rec.go
@@ -0,0 +1,259 @@
+// *** WARNING: this file was generated by test. ***
+// *** Do not edit by hand unless you're certain you know what you are doing! ***
+
+package example
+
+import (
+ "context"
+ "reflect"
+
+ "github.com/pulumi/pulumi/sdk/v3/go/pulumi"
+)
+
+type Rec struct {
+ pulumi.CustomResourceState
+
+ Rec RecPtrOutput `pulumi:"rec"`
+}
+
+// NewRec registers a new resource with the given unique name, arguments, and options.
+func NewRec(ctx *pulumi.Context,
+ name string, args *RecArgs, opts ...pulumi.ResourceOption) (*Rec, error) {
+ if args == nil {
+ args = &RecArgs{}
+ }
+
+ var resource Rec
+ err := ctx.RegisterResource("example::Rec", name, args, &resource, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return &resource, nil
+}
+
+// GetRec gets an existing Rec 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 GetRec(ctx *pulumi.Context,
+ name string, id pulumi.IDInput, state *RecState, opts ...pulumi.ResourceOption) (*Rec, error) {
+ var resource Rec
+ err := ctx.ReadResource("example::Rec", name, id, state, &resource, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return &resource, nil
+}
+
+// Input properties used for looking up and filtering Rec resources.
+type recState struct {
+}
+
+type RecState struct {
+}
+
+func (RecState) ElementType() reflect.Type {
+ return reflect.TypeOf((*recState)(nil)).Elem()
+}
+
+type recArgs struct {
+}
+
+// The set of arguments for constructing a Rec resource.
+type RecArgs struct {
+}
+
+func (RecArgs) ElementType() reflect.Type {
+ return reflect.TypeOf((*recArgs)(nil)).Elem()
+}
+
+type RecInput interface {
+ pulumi.Input
+
+ ToRecOutput() RecOutput
+ ToRecOutputWithContext(ctx context.Context) RecOutput
+}
+
+func (*Rec) ElementType() reflect.Type {
+ return reflect.TypeOf((*Rec)(nil))
+}
+
+func (i *Rec) ToRecOutput() RecOutput {
+ return i.ToRecOutputWithContext(context.Background())
+}
+
+func (i *Rec) ToRecOutputWithContext(ctx context.Context) RecOutput {
+ return pulumi.ToOutputWithContext(ctx, i).(RecOutput)
+}
+
+func (i *Rec) ToRecPtrOutput() RecPtrOutput {
+ return i.ToRecPtrOutputWithContext(context.Background())
+}
+
+func (i *Rec) ToRecPtrOutputWithContext(ctx context.Context) RecPtrOutput {
+ return pulumi.ToOutputWithContext(ctx, i).(RecPtrOutput)
+}
+
+type RecPtrInput interface {
+ pulumi.Input
+
+ ToRecPtrOutput() RecPtrOutput
+ ToRecPtrOutputWithContext(ctx context.Context) RecPtrOutput
+}
+
+type recPtrType RecArgs
+
+func (*recPtrType) ElementType() reflect.Type {
+ return reflect.TypeOf((**Rec)(nil))
+}
+
+func (i *recPtrType) ToRecPtrOutput() RecPtrOutput {
+ return i.ToRecPtrOutputWithContext(context.Background())
+}
+
+func (i *recPtrType) ToRecPtrOutputWithContext(ctx context.Context) RecPtrOutput {
+ return pulumi.ToOutputWithContext(ctx, i).(RecPtrOutput)
+}
+
+// RecArrayInput is an input type that accepts RecArray and RecArrayOutput values.
+// You can construct a concrete instance of `RecArrayInput` via:
+//
+// RecArray{ RecArgs{...} }
+type RecArrayInput interface {
+ pulumi.Input
+
+ ToRecArrayOutput() RecArrayOutput
+ ToRecArrayOutputWithContext(context.Context) RecArrayOutput
+}
+
+type RecArray []RecInput
+
+func (RecArray) ElementType() reflect.Type {
+ return reflect.TypeOf((*[]*Rec)(nil)).Elem()
+}
+
+func (i RecArray) ToRecArrayOutput() RecArrayOutput {
+ return i.ToRecArrayOutputWithContext(context.Background())
+}
+
+func (i RecArray) ToRecArrayOutputWithContext(ctx context.Context) RecArrayOutput {
+ return pulumi.ToOutputWithContext(ctx, i).(RecArrayOutput)
+}
+
+// RecMapInput is an input type that accepts RecMap and RecMapOutput values.
+// You can construct a concrete instance of `RecMapInput` via:
+//
+// RecMap{ "key": RecArgs{...} }
+type RecMapInput interface {
+ pulumi.Input
+
+ ToRecMapOutput() RecMapOutput
+ ToRecMapOutputWithContext(context.Context) RecMapOutput
+}
+
+type RecMap map[string]RecInput
+
+func (RecMap) ElementType() reflect.Type {
+ return reflect.TypeOf((*map[string]*Rec)(nil)).Elem()
+}
+
+func (i RecMap) ToRecMapOutput() RecMapOutput {
+ return i.ToRecMapOutputWithContext(context.Background())
+}
+
+func (i RecMap) ToRecMapOutputWithContext(ctx context.Context) RecMapOutput {
+ return pulumi.ToOutputWithContext(ctx, i).(RecMapOutput)
+}
+
+type RecOutput struct{ *pulumi.OutputState }
+
+func (RecOutput) ElementType() reflect.Type {
+ return reflect.TypeOf((*Rec)(nil))
+}
+
+func (o RecOutput) ToRecOutput() RecOutput {
+ return o
+}
+
+func (o RecOutput) ToRecOutputWithContext(ctx context.Context) RecOutput {
+ return o
+}
+
+func (o RecOutput) ToRecPtrOutput() RecPtrOutput {
+ return o.ToRecPtrOutputWithContext(context.Background())
+}
+
+func (o RecOutput) ToRecPtrOutputWithContext(ctx context.Context) RecPtrOutput {
+ return o.ApplyTWithContext(ctx, func(_ context.Context, v Rec) *Rec {
+ return &v
+ }).(RecPtrOutput)
+}
+
+type RecPtrOutput struct{ *pulumi.OutputState }
+
+func (RecPtrOutput) ElementType() reflect.Type {
+ return reflect.TypeOf((**Rec)(nil))
+}
+
+func (o RecPtrOutput) ToRecPtrOutput() RecPtrOutput {
+ return o
+}
+
+func (o RecPtrOutput) ToRecPtrOutputWithContext(ctx context.Context) RecPtrOutput {
+ return o
+}
+
+func (o RecPtrOutput) Elem() RecOutput {
+ return o.ApplyT(func(v *Rec) Rec {
+ if v != nil {
+ return *v
+ }
+ var ret Rec
+ return ret
+ }).(RecOutput)
+}
+
+type RecArrayOutput struct{ *pulumi.OutputState }
+
+func (RecArrayOutput) ElementType() reflect.Type {
+ return reflect.TypeOf((*[]Rec)(nil))
+}
+
+func (o RecArrayOutput) ToRecArrayOutput() RecArrayOutput {
+ return o
+}
+
+func (o RecArrayOutput) ToRecArrayOutputWithContext(ctx context.Context) RecArrayOutput {
+ return o
+}
+
+func (o RecArrayOutput) Index(i pulumi.IntInput) RecOutput {
+ return pulumi.All(o, i).ApplyT(func(vs []interface{}) Rec {
+ return vs[0].([]Rec)[vs[1].(int)]
+ }).(RecOutput)
+}
+
+type RecMapOutput struct{ *pulumi.OutputState }
+
+func (RecMapOutput) ElementType() reflect.Type {
+ return reflect.TypeOf((*map[string]Rec)(nil))
+}
+
+func (o RecMapOutput) ToRecMapOutput() RecMapOutput {
+ return o
+}
+
+func (o RecMapOutput) ToRecMapOutputWithContext(ctx context.Context) RecMapOutput {
+ return o
+}
+
+func (o RecMapOutput) MapIndex(k pulumi.StringInput) RecOutput {
+ return pulumi.All(o, k).ApplyT(func(vs []interface{}) Rec {
+ return vs[0].(map[string]Rec)[vs[1].(string)]
+ }).(RecOutput)
+}
+
+func init() {
+ pulumi.RegisterOutputType(RecOutput{})
+ pulumi.RegisterOutputType(RecPtrOutput{})
+ pulumi.RegisterOutputType(RecArrayOutput{})
+ pulumi.RegisterOutputType(RecMapOutput{})
+}
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/README.md b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/README.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/index.ts b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/index.ts
new file mode 100644
index 000000000..421b766ef
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/index.ts
@@ -0,0 +1,37 @@
+// *** WARNING: this file was generated by test. ***
+// *** Do not edit by hand unless you're certain you know what you are doing! ***
+
+import * as pulumi from "@pulumi/pulumi";
+import * as utilities from "./utilities";
+
+// Export members:
+export * from "./provider";
+export * from "./rec";
+
+// Import resources to register:
+import { Rec } from "./rec";
+
+const _module = {
+ version: utilities.getVersion(),
+ construct: (name: string, type: string, urn: string): pulumi.Resource => {
+ switch (type) {
+ case "example::Rec":
+ return new Rec(name, undefined, { urn })
+ default:
+ throw new Error(`unknown resource type ${type}`);
+ }
+ },
+};
+pulumi.runtime.registerResourceModule("example", "", _module)
+
+import { Provider } from "./provider";
+
+pulumi.runtime.registerResourcePackage("example", {
+ version: utilities.getVersion(),
+ constructProvider: (name: string, type: string, urn: string): pulumi.ProviderResource => {
+ if (type !== "pulumi:providers:example") {
+ throw new Error(`unknown provider type ${type}`);
+ }
+ return new Provider(name, undefined, { urn });
+ },
+});
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/package.json b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/package.json
new file mode 100644
index 000000000..9ac06bdfc
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "@pulumi/example",
+ "version": "${VERSION}",
+ "scripts": {
+ "build": "tsc"
+ },
+ "devDependencies": {
+ "typescript": "^4.3.5"
+ },
+ "peerDependencies": {
+ "@pulumi/pulumi": "latest"
+ },
+ "pulumi": {
+ "resource": true
+ }
+}
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/provider.ts b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/provider.ts
new file mode 100644
index 000000000..791f0a3cf
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/provider.ts
@@ -0,0 +1,46 @@
+// *** WARNING: this file was generated by test. ***
+// *** Do not edit by hand unless you're certain you know what you are doing! ***
+
+import * as pulumi from "@pulumi/pulumi";
+import * as utilities from "./utilities";
+
+export class Provider extends pulumi.ProviderResource {
+ /** @internal */
+ public static readonly __pulumiType = 'example';
+
+ /**
+ * Returns true if the given object is an instance of Provider. This is designed to work even
+ * when multiple copies of the Pulumi SDK have been loaded into the same process.
+ */
+ public static isInstance(obj: any): obj is Provider {
+ if (obj === undefined || obj === null) {
+ return false;
+ }
+ return obj['__pulumiType'] === Provider.__pulumiType;
+ }
+
+
+ /**
+ * Create a Provider resource with the given unique name, arguments, and options.
+ *
+ * @param name The _unique_ name of the resource.
+ * @param args The arguments to use to populate this resource's properties.
+ * @param opts A bag of options that control this resource's behavior.
+ */
+ constructor(name: string, args?: ProviderArgs, opts?: pulumi.ResourceOptions) {
+ let inputs: pulumi.Inputs = {};
+ opts = opts || {};
+ {
+ }
+ if (!opts.version) {
+ opts = pulumi.mergeOptions(opts, { version: utilities.getVersion()});
+ }
+ super(Provider.__pulumiType, name, inputs, opts);
+ }
+}
+
+/**
+ * The set of arguments for constructing a Provider resource.
+ */
+export interface ProviderArgs {
+}
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/rec.ts b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/rec.ts
new file mode 100644
index 000000000..6aa2030cd
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/rec.ts
@@ -0,0 +1,64 @@
+// *** WARNING: this file was generated by test. ***
+// *** Do not edit by hand unless you're certain you know what you are doing! ***
+
+import * as pulumi from "@pulumi/pulumi";
+import * as utilities from "./utilities";
+
+import {Rec} from "./index";
+
+export class Rec extends pulumi.CustomResource {
+ /**
+ * Get an existing Rec resource's state with the given name, ID, and optional extra
+ * properties used to qualify the lookup.
+ *
+ * @param name The _unique_ name of the resulting resource.
+ * @param id The _unique_ provider ID of the resource to lookup.
+ * @param opts Optional settings to control the behavior of the CustomResource.
+ */
+ public static get(name: string, id: pulumi.Input, opts?: pulumi.CustomResourceOptions): Rec {
+ return new Rec(name, undefined as any, { ...opts, id: id });
+ }
+
+ /** @internal */
+ public static readonly __pulumiType = 'example::Rec';
+
+ /**
+ * Returns true if the given object is an instance of Rec. This is designed to work even
+ * when multiple copies of the Pulumi SDK have been loaded into the same process.
+ */
+ public static isInstance(obj: any): obj is Rec {
+ if (obj === undefined || obj === null) {
+ return false;
+ }
+ return obj['__pulumiType'] === Rec.__pulumiType;
+ }
+
+ public /*out*/ readonly rec!: pulumi.Output;
+
+ /**
+ * Create a Rec resource with the given unique name, arguments, and options.
+ *
+ * @param name The _unique_ name of the resource.
+ * @param args The arguments to use to populate this resource's properties.
+ * @param opts A bag of options that control this resource's behavior.
+ */
+ constructor(name: string, args?: RecArgs, opts?: pulumi.CustomResourceOptions) {
+ let inputs: pulumi.Inputs = {};
+ opts = opts || {};
+ if (!opts.id) {
+ inputs["rec"] = undefined /*out*/;
+ } else {
+ inputs["rec"] = undefined /*out*/;
+ }
+ if (!opts.version) {
+ opts = pulumi.mergeOptions(opts, { version: utilities.getVersion()});
+ }
+ super(Rec.__pulumiType, name, inputs, opts);
+ }
+}
+
+/**
+ * The set of arguments for constructing a Rec resource.
+ */
+export interface RecArgs {
+}
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/tsconfig.json b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/tsconfig.json
new file mode 100644
index 000000000..e2e0424ca
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/tsconfig.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "target": "es2016",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "declaration": true,
+ "sourceMap": true,
+ "stripInternal": true,
+ "experimentalDecorators": true,
+ "noFallthroughCasesInSwitch": true,
+ "forceConsistentCasingInFileNames": true,
+ "strict": true
+ },
+ "files": [
+ "index.ts",
+ "provider.ts",
+ "rec.ts",
+ "utilities.ts"
+ ]
+}
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/utilities.ts b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/utilities.ts
new file mode 100644
index 000000000..f26ed073c
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/nodejs/utilities.ts
@@ -0,0 +1,49 @@
+// *** WARNING: this file was generated by test. ***
+// *** Do not edit by hand unless you're certain you know what you are doing! ***
+
+
+export function getEnv(...vars: string[]): string | undefined {
+ for (const v of vars) {
+ const value = process.env[v];
+ if (value) {
+ return value;
+ }
+ }
+ return undefined;
+}
+
+export function getEnvBoolean(...vars: string[]): boolean | undefined {
+ const s = getEnv(...vars);
+ if (s !== undefined) {
+ // NOTE: these values are taken from https://golang.org/src/strconv/atob.go?s=351:391#L1, which is what
+ // Terraform uses internally when parsing boolean values.
+ if (["1", "t", "T", "true", "TRUE", "True"].find(v => v === s) !== undefined) {
+ return true;
+ }
+ if (["0", "f", "F", "false", "FALSE", "False"].find(v => v === s) !== undefined) {
+ return false;
+ }
+ }
+ return undefined;
+}
+
+export function getEnvNumber(...vars: string[]): number | undefined {
+ const s = getEnv(...vars);
+ if (s !== undefined) {
+ const f = parseFloat(s);
+ if (!isNaN(f)) {
+ return f;
+ }
+ }
+ return undefined;
+}
+
+export function getVersion(): string {
+ let version = require('./package.json').version;
+ // Node allows for the version to be prefixed by a "v", while semver doesn't.
+ // If there is a v, strip it off.
+ if (version.indexOf('v') === 0) {
+ version = version.slice(1);
+ }
+ return version;
+}
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/README.md b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/README.md
new file mode 100644
index 000000000..e69de29bb
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/__init__.py b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/__init__.py
new file mode 100644
index 000000000..63ca3153b
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/__init__.py
@@ -0,0 +1,33 @@
+# coding=utf-8
+# *** WARNING: this file was generated by test. ***
+# *** Do not edit by hand unless you're certain you know what you are doing! ***
+
+from . import _utilities
+import typing
+# Export this package's modules as members:
+from .provider import *
+from .rec import *
+_utilities.register(
+ resource_modules="""
+[
+ {
+ "pkg": "example",
+ "mod": "",
+ "fqn": "pulumi_example",
+ "classes": {
+ "example::Rec": "Rec"
+ }
+ }
+]
+""",
+ resource_packages="""
+[
+ {
+ "pkg": "example",
+ "token": "pulumi:providers:example",
+ "fqn": "pulumi_example",
+ "class": "Provider"
+ }
+]
+"""
+)
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/_utilities.py b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/_utilities.py
new file mode 100644
index 000000000..df9d60e73
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/_utilities.py
@@ -0,0 +1,235 @@
+# coding=utf-8
+# *** WARNING: this file was generated by test. ***
+# *** Do not edit by hand unless you're certain you know what you are doing! ***
+
+
+import importlib.util
+import inspect
+import json
+import os
+import pkg_resources
+import sys
+import typing
+
+import pulumi
+import pulumi.runtime
+
+from semver import VersionInfo as SemverVersion
+from parver import Version as PEP440Version
+
+
+def get_env(*args):
+ for v in args:
+ value = os.getenv(v)
+ if value is not None:
+ return value
+ return None
+
+
+def get_env_bool(*args):
+ str = get_env(*args)
+ if str is not None:
+ # NOTE: these values are taken from https://golang.org/src/strconv/atob.go?s=351:391#L1, which is what
+ # Terraform uses internally when parsing boolean values.
+ if str in ["1", "t", "T", "true", "TRUE", "True"]:
+ return True
+ if str in ["0", "f", "F", "false", "FALSE", "False"]:
+ return False
+ return None
+
+
+def get_env_int(*args):
+ str = get_env(*args)
+ if str is not None:
+ try:
+ return int(str)
+ except:
+ return None
+ return None
+
+
+def get_env_float(*args):
+ str = get_env(*args)
+ if str is not None:
+ try:
+ return float(str)
+ except:
+ return None
+ return None
+
+
+def _get_semver_version():
+ # __name__ is set to the fully-qualified name of the current module, In our case, it will be
+ # ._utilities. is the module we want to query the version for.
+ root_package, *rest = __name__.split('.')
+
+ # pkg_resources uses setuptools to inspect the set of installed packages. We use it here to ask
+ # for the currently installed version of the root package (i.e. us) and get its version.
+
+ # Unfortunately, PEP440 and semver differ slightly in incompatible ways. The Pulumi engine expects
+ # to receive a valid semver string when receiving requests from the language host, so it's our
+ # responsibility as the library to convert our own PEP440 version into a valid semver string.
+
+ pep440_version_string = pkg_resources.require(root_package)[0].version
+ pep440_version = PEP440Version.parse(pep440_version_string)
+ (major, minor, patch) = pep440_version.release
+ prerelease = None
+ if pep440_version.pre_tag == 'a':
+ prerelease = f"alpha.{pep440_version.pre}"
+ elif pep440_version.pre_tag == 'b':
+ prerelease = f"beta.{pep440_version.pre}"
+ elif pep440_version.pre_tag == 'rc':
+ prerelease = f"rc.{pep440_version.pre}"
+ elif pep440_version.dev is not None:
+ prerelease = f"dev.{pep440_version.dev}"
+
+ # The only significant difference between PEP440 and semver as it pertains to us is that PEP440 has explicit support
+ # for dev builds, while semver encodes them as "prerelease" versions. In order to bridge between the two, we convert
+ # our dev build version into a prerelease tag. This matches what all of our other packages do when constructing
+ # their own semver string.
+ return SemverVersion(major=major, minor=minor, patch=patch, prerelease=prerelease)
+
+
+# Determine the version once and cache the value, which measurably improves program performance.
+_version = _get_semver_version()
+_version_str = str(_version)
+
+
+def get_version():
+ return _version_str
+
+
+def get_resource_args_opts(resource_args_type, resource_options_type, *args, **kwargs):
+ """
+ Return the resource args and options given the *args and **kwargs of a resource's
+ __init__ method.
+ """
+
+ resource_args, opts = None, None
+
+ # If the first item is the resource args type, save it and remove it from the args list.
+ if args and isinstance(args[0], resource_args_type):
+ resource_args, args = args[0], args[1:]
+
+ # Now look at the first item in the args list again.
+ # If the first item is the resource options class, save it.
+ if args and isinstance(args[0], resource_options_type):
+ opts = args[0]
+
+ # If resource_args is None, see if "args" is in kwargs, and, if so, if it's typed as the
+ # the resource args type.
+ if resource_args is None:
+ a = kwargs.get("args")
+ if isinstance(a, resource_args_type):
+ resource_args = a
+
+ # If opts is None, look it up in kwargs.
+ if opts is None:
+ opts = kwargs.get("opts")
+
+ return resource_args, opts
+
+
+# Temporary: just use pulumi._utils.lazy_import once everyone upgrades.
+def lazy_import(fullname):
+
+ import pulumi._utils as u
+ f = getattr(u, 'lazy_import', None)
+ if f is None:
+ f = _lazy_import_temp
+
+ return f(fullname)
+
+
+# Copied from pulumi._utils.lazy_import, see comments there.
+def _lazy_import_temp(fullname):
+ m = sys.modules.get(fullname, None)
+ if m is not None:
+ return m
+
+ spec = importlib.util.find_spec(fullname)
+
+ m = sys.modules.get(fullname, None)
+ if m is not None:
+ return m
+
+ loader = importlib.util.LazyLoader(spec.loader)
+ spec.loader = loader
+ module = importlib.util.module_from_spec(spec)
+
+ m = sys.modules.get(fullname, None)
+ if m is not None:
+ return m
+
+ sys.modules[fullname] = module
+ loader.exec_module(module)
+ return module
+
+
+class Package(pulumi.runtime.ResourcePackage):
+ def __init__(self, pkg_info):
+ super().__init__()
+ self.pkg_info = pkg_info
+
+ def version(self):
+ return _version
+
+ def construct_provider(self, name: str, typ: str, urn: str) -> pulumi.ProviderResource:
+ if typ != self.pkg_info['token']:
+ raise Exception(f"unknown provider type {typ}")
+ Provider = getattr(lazy_import(self.pkg_info['fqn']), self.pkg_info['class'])
+ return Provider(name, pulumi.ResourceOptions(urn=urn))
+
+
+class Module(pulumi.runtime.ResourceModule):
+ def __init__(self, mod_info):
+ super().__init__()
+ self.mod_info = mod_info
+
+ def version(self):
+ return _version
+
+ def construct(self, name: str, typ: str, urn: str) -> pulumi.Resource:
+ class_name = self.mod_info['classes'].get(typ, None)
+
+ if class_name is None:
+ raise Exception(f"unknown resource type {typ}")
+
+ TheClass = getattr(lazy_import(self.mod_info['fqn']), class_name)
+ return TheClass(name, pulumi.ResourceOptions(urn=urn))
+
+
+def register(resource_modules, resource_packages):
+ resource_modules = json.loads(resource_modules)
+ resource_packages = json.loads(resource_packages)
+
+ for pkg_info in resource_packages:
+ pulumi.runtime.register_resource_package(pkg_info['pkg'], Package(pkg_info))
+
+ for mod_info in resource_modules:
+ pulumi.runtime.register_resource_module(
+ mod_info['pkg'],
+ mod_info['mod'],
+ Module(mod_info))
+
+
+_F = typing.TypeVar('_F', bound=typing.Callable[..., typing.Any])
+
+
+def lift_output_func(func: typing.Any) -> typing.Callable[[_F], _F]:
+ """Decorator internally used on {fn}_output lifted function versions
+ to implement them automatically from the un-lifted function."""
+
+ func_sig = inspect.signature(func)
+
+ def lifted_func(*args, opts=None, **kwargs):
+ bound_args = func_sig.bind(*args, **kwargs)
+
+ return pulumi.Output.from_input({
+ 'args': bound_args.args,
+ 'kwargs': bound_args.kwargs
+ }).apply(lambda resolved_args: func(*resolved_args['args'],
+ opts=opts,
+ **resolved_args['kwargs']))
+
+ return (lambda _: lifted_func)
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/provider.py b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/provider.py
new file mode 100644
index 000000000..d6ca5375e
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/provider.py
@@ -0,0 +1,73 @@
+# coding=utf-8
+# *** WARNING: this file was generated by test. ***
+# *** Do not edit by hand unless you're certain you know what you are doing! ***
+
+import warnings
+import pulumi
+import pulumi.runtime
+from typing import Any, Mapping, Optional, Sequence, Union, overload
+from . import _utilities
+
+__all__ = ['ProviderArgs', 'Provider']
+
+@pulumi.input_type
+class ProviderArgs:
+ def __init__(__self__):
+ """
+ The set of arguments for constructing a Provider resource.
+ """
+ pass
+
+
+class Provider(pulumi.ProviderResource):
+ @overload
+ def __init__(__self__,
+ resource_name: str,
+ opts: Optional[pulumi.ResourceOptions] = None,
+ __props__=None):
+ """
+ Create a Example resource with the given unique name, props, and options.
+ :param str resource_name: The name of the resource.
+ :param pulumi.ResourceOptions opts: Options for the resource.
+ """
+ ...
+ @overload
+ def __init__(__self__,
+ resource_name: str,
+ args: Optional[ProviderArgs] = None,
+ opts: Optional[pulumi.ResourceOptions] = None):
+ """
+ Create a Example resource with the given unique name, props, and options.
+ :param str resource_name: The name of the resource.
+ :param ProviderArgs args: The arguments to use to populate this resource's properties.
+ :param pulumi.ResourceOptions opts: Options for the resource.
+ """
+ ...
+ def __init__(__self__, resource_name: str, *args, **kwargs):
+ resource_args, opts = _utilities.get_resource_args_opts(ProviderArgs, pulumi.ResourceOptions, *args, **kwargs)
+ if resource_args is not None:
+ __self__._internal_init(resource_name, opts, **resource_args.__dict__)
+ else:
+ __self__._internal_init(resource_name, *args, **kwargs)
+
+ def _internal_init(__self__,
+ resource_name: str,
+ opts: Optional[pulumi.ResourceOptions] = None,
+ __props__=None):
+ if opts is None:
+ opts = pulumi.ResourceOptions()
+ if not isinstance(opts, pulumi.ResourceOptions):
+ raise TypeError('Expected resource options to be a ResourceOptions instance')
+ if opts.version is None:
+ opts.version = _utilities.get_version()
+ if opts.id is None:
+ if __props__ is not None:
+ raise TypeError('__props__ is only valid when passed in combination with a valid opts.id to get an existing resource')
+ __props__ = ProviderArgs.__new__(ProviderArgs)
+
+ super(Provider, __self__).__init__(
+ 'example',
+ resource_name,
+ __props__,
+ opts)
+
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/py.typed b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/py.typed
new file mode 100644
index 000000000..e69de29bb
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/rec.py b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/rec.py
new file mode 100644
index 000000000..2c71342f1
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/pulumi_example/rec.py
@@ -0,0 +1,98 @@
+# coding=utf-8
+# *** WARNING: this file was generated by test. ***
+# *** Do not edit by hand unless you're certain you know what you are doing! ***
+
+import warnings
+import pulumi
+import pulumi.runtime
+from typing import Any, Mapping, Optional, Sequence, Union, overload
+from . import _utilities
+
+__all__ = ['RecArgs', 'Rec']
+
+@pulumi.input_type
+class RecArgs:
+ def __init__(__self__):
+ """
+ The set of arguments for constructing a Rec resource.
+ """
+ pass
+
+
+class Rec(pulumi.CustomResource):
+ @overload
+ def __init__(__self__,
+ resource_name: str,
+ opts: Optional[pulumi.ResourceOptions] = None,
+ __props__=None):
+ """
+ Create a Rec resource with the given unique name, props, and options.
+ :param str resource_name: The name of the resource.
+ :param pulumi.ResourceOptions opts: Options for the resource.
+ """
+ ...
+ @overload
+ def __init__(__self__,
+ resource_name: str,
+ args: Optional[RecArgs] = None,
+ opts: Optional[pulumi.ResourceOptions] = None):
+ """
+ Create a Rec resource with the given unique name, props, and options.
+ :param str resource_name: The name of the resource.
+ :param RecArgs args: The arguments to use to populate this resource's properties.
+ :param pulumi.ResourceOptions opts: Options for the resource.
+ """
+ ...
+ def __init__(__self__, resource_name: str, *args, **kwargs):
+ resource_args, opts = _utilities.get_resource_args_opts(RecArgs, pulumi.ResourceOptions, *args, **kwargs)
+ if resource_args is not None:
+ __self__._internal_init(resource_name, opts, **resource_args.__dict__)
+ else:
+ __self__._internal_init(resource_name, *args, **kwargs)
+
+ def _internal_init(__self__,
+ resource_name: str,
+ opts: Optional[pulumi.ResourceOptions] = None,
+ __props__=None):
+ if opts is None:
+ opts = pulumi.ResourceOptions()
+ if not isinstance(opts, pulumi.ResourceOptions):
+ raise TypeError('Expected resource options to be a ResourceOptions instance')
+ if opts.version is None:
+ opts.version = _utilities.get_version()
+ if opts.id is None:
+ if __props__ is not None:
+ raise TypeError('__props__ is only valid when passed in combination with a valid opts.id to get an existing resource')
+ __props__ = RecArgs.__new__(RecArgs)
+
+ __props__.__dict__["rec"] = None
+ super(Rec, __self__).__init__(
+ 'example::Rec',
+ resource_name,
+ __props__,
+ opts)
+
+ @staticmethod
+ def get(resource_name: str,
+ id: pulumi.Input[str],
+ opts: Optional[pulumi.ResourceOptions] = None) -> 'Rec':
+ """
+ Get an existing Rec resource's state with the given name, id, and optional extra
+ properties used to qualify the lookup.
+
+ :param str resource_name: The unique name of the resulting resource.
+ :param pulumi.Input[str] id: The unique provider ID of the resource to lookup.
+ :param pulumi.ResourceOptions opts: Options for the resource.
+ """
+ opts = pulumi.ResourceOptions.merge(opts, pulumi.ResourceOptions(id=id))
+
+ __props__ = RecArgs.__new__(RecArgs)
+
+ __props__.__dict__["rec"] = None
+ return Rec(resource_name, opts=opts, __props__=__props__)
+
+ @property
+ @pulumi.getter
+ def rec(self) -> pulumi.Output[Optional[Any]]:
+ return pulumi.get(self, "rec")
+
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/python/setup.py b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/setup.py
new file mode 100644
index 000000000..4550e1ebd
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/python/setup.py
@@ -0,0 +1,58 @@
+# coding=utf-8
+# *** WARNING: this file was generated by test. ***
+# *** Do not edit by hand unless you're certain you know what you are doing! ***
+
+import errno
+from setuptools import setup, find_packages
+from setuptools.command.install import install
+from subprocess import check_call
+
+
+VERSION = "0.0.0"
+PLUGIN_VERSION = "0.0.0"
+
+class InstallPluginCommand(install):
+ def run(self):
+ install.run(self)
+ try:
+ check_call(['pulumi', 'plugin', 'install', 'resource', 'example', PLUGIN_VERSION])
+ except OSError as error:
+ if error.errno == errno.ENOENT:
+ print(f"""
+ There was an error installing the example resource provider plugin.
+ It looks like `pulumi` is not installed on your system.
+ Please visit https://pulumi.com/ to install the Pulumi CLI.
+ You may try manually installing the plugin by running
+ `pulumi plugin install resource example {PLUGIN_VERSION}`
+ """)
+ else:
+ raise
+
+
+def readme():
+ try:
+ with open('README.md', encoding='utf-8') as f:
+ return f.read()
+ except FileNotFoundError:
+ return "example Pulumi Package - Development Version"
+
+
+setup(name='pulumi_example',
+ version=VERSION,
+ long_description=readme(),
+ long_description_content_type='text/markdown',
+ cmdclass={
+ 'install': InstallPluginCommand,
+ },
+ packages=find_packages(),
+ package_data={
+ 'pulumi_example': [
+ 'py.typed',
+ ]
+ },
+ install_requires=[
+ 'parver>=0.2.1',
+ 'pulumi',
+ 'semver>=2.8.1'
+ ],
+ zip_safe=False)
diff --git a/pkg/codegen/internal/test/testdata/resource-property-overlap/schema.json b/pkg/codegen/internal/test/testdata/resource-property-overlap/schema.json
new file mode 100644
index 000000000..2aa83be1d
--- /dev/null
+++ b/pkg/codegen/internal/test/testdata/resource-property-overlap/schema.json
@@ -0,0 +1,25 @@
+{
+ "name": "example",
+ "version": "0.0.1",
+ "resources": {
+ "example::Rec": {
+ "properties": {
+ "rec": {
+ "$ref": "#/types/example::Rec"
+ }
+ }
+ }
+ },
+ "language": {
+ "csharp": {
+ "packageReferences": {
+ "Pulumi": "3.12"
+ }
+ },
+ "go": {
+ "generateResourceContainerTypes": true
+ },
+ "nodejs": {},
+ "python": {}
+ }
+}
diff --git a/pkg/codegen/internal/test/testdata/simple-enum-schema/dotnet/Pulumi.Plant.csproj b/pkg/codegen/internal/test/testdata/simple-enum-schema/dotnet/Pulumi.Plant.csproj
index b172ade5b..6d53245f3 100644
--- a/pkg/codegen/internal/test/testdata/simple-enum-schema/dotnet/Pulumi.Plant.csproj
+++ b/pkg/codegen/internal/test/testdata/simple-enum-schema/dotnet/Pulumi.Plant.csproj
@@ -40,6 +40,7 @@