Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

(go): downcasting support #2819

Closed
MrArnoldPalmer opened this issue May 4, 2021 · 5 comments · Fixed by #3316
Closed

(go): downcasting support #2819

MrArnoldPalmer opened this issue May 4, 2021 · 5 comments · Fixed by #3316
Assignees
Labels
bug This issue is a bug. effort/medium Medium work item – a couple days of effort language/go Regarding GoLang bindings p1

Comments

@MrArnoldPalmer
Copy link
Contributor

Go interface types cannot be downcasted to more specific types using normal go casting functionality. There may be some reflection able to achieve this but its not readily apparent if so and should be documented if it is indeed possible.

Example:

	topic := awssns.NewTopic(stack, jsii.String("MyTopic"), &awssns.TopicProps{
		DisplayName: jsii.String("MyCoolTopic"),
	})

        l1node := topic.Node().DefaultChild()
	l1 := l1node.(awssns.CfnTopic)

error:

panic: interface conversion: *awscdk.jsiiProxy_IConstruct is not awssns.CfnTopic: missing method AddDeletionOverride

goroutine 1 [running]:
main.NewGoDowncastingStack(0x7ff3cf55a0a0, 0xc0000a6420, 0x709ffb, 0x12, 0xc00023ff38, 0xc00007c748, 0x3943d80)
        /home/mvaline/dev/cdk-tests/go-downcasting/go-downcasting.go:31 +0x225
main.main()
        /home/mvaline/dev/cdk-tests/go-downcasting/go-downcasting.go:41 +0xbd
exit status 2
Subprocess exited with error 1

There may be a changes to code generation that would allow the above to work but more investigation is needed.

@MrArnoldPalmer MrArnoldPalmer added bug This issue is a bug. language/go Regarding GoLang bindings effort/medium Medium work item – a couple days of effort p2 labels May 4, 2021
@MrArnoldPalmer MrArnoldPalmer added this to Backlog in Go General Availability via automation May 4, 2021
@xrn
Copy link

xrn commented May 4, 2021

Hi, am I right that my issue #2798 is related to this?

@chlunde
Copy link

chlunde commented Jun 15, 2021

A quick chain of hacks :)

I did not want to understand/look at castAndSetToPtr (or any of the other code), so this is just a POC:

func (c *Client) CastAndSetToPtr(ptr interface{}, data interface{}) {
	ptrVal := reflect.ValueOf(ptr).Elem()
	dataVal := reflect.ValueOf(data)

	if data, ok := data.(map[string]interface{}); ok {
		if ref, ok := data["$jsii.byref"]; ok { // uhm
			typRef := strings.Split(ref.(string), "@")[0] // oof
			typ, ok := c.Types().FindType(api.FQN(typRef))

			if ok && typRef == "aws-cdk-lib.aws_ec2.CfnLaunchTemplate" {
				fmt.Println(typ, typRef)
				n := reflect.New(typ)
				c.castAndSetToPtr(n.Elem(), dataVal)
				fmt.Println(n)
				ptrVal.Set(n.Elem())
				return
			}
		}
	}

	c.castAndSetToPtr(ptrVal, dataVal)
}

CDK use case which is now possible:

	launchTemplate := awsec2.NewLaunchTemplate(stack, aws.String("lt"), &awsec2.LaunchTemplateProps{})
	fmt.Println("Calling .DefaultChild")

	cfnlt := launchTemplate.Node().DefaultChild().(awsec2.CfnLaunchTemplate)
	// https://docs.aws.amazon.com/eks/latest/userguide/best-practices-security.html
	cfnlt.AddPropertyOverride(aws.String("LaunchTemplateData.MetadataOptions.HttpTokens"), aws.String("required"))

@gottschalkj-fmr
Copy link

I was able to workaround this way for now:

dist := awscloudfront.NewDistribution(...)
...
var cfnDist awscloudfront.CfnDistribution
//lint:ignore SA1019 to use JSII to perform unsafe cast to cloudfront.CfnDistribution for us
jsii.Get(dist.Node(), "defaultChild", &cfnDist)
cfnDist.AddPropertyDeletionOverride(...)

@MrArnoldPalmer MrArnoldPalmer added p1 and removed p2 labels Dec 14, 2021
@MrArnoldPalmer MrArnoldPalmer removed this from Backlog in Go General Availability Dec 21, 2021
@RomainMuller RomainMuller self-assigned this Jan 4, 2022
@mergify mergify bot closed this as completed in #3316 Jan 12, 2022
mergify bot pushed a commit that referenced this issue Jan 12, 2022
The `UnsafeCast` function can be used to forcefully convert from one
type of jsii proxy value (including `interface{}`) to another jsii
interface (i.e: a class or interface instance).

If performs a "clean" cast when possible, and creates a new, aliased
proxy otherwise. It is the user's responsibility to ensure they are
passing the correct arguments into the function.

Fixes #2819

---

By submitting this pull request, I confirm that my contribution is made under the terms of the [Apache 2.0 license].

[Apache 2.0 license]: https://www.apache.org/licenses/LICENSE-2.0
@github-actions
Copy link
Contributor

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

@ThomasP1988
Copy link

It's closed but it's still a bug, spent my afternoon trying to override a property, I had to use @krautbax (thanks) even if jsii.Get is deprecated.

RomainMuller pushed a commit that referenced this issue Feb 3, 2022
…Proxy (#3354)

With this PR, the type that is instantiated as JSII Proxy is looked up from the type registry using the TypeFQDN in the ref. If that type is registered in the type registry AND that type is assignable to the targeted value type, than that type is used to instantiate the JSII proxy. 

Fixes #3353 and relates to #2819.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. effort/medium Medium work item – a couple days of effort language/go Regarding GoLang bindings p1
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

6 participants