-
Notifications
You must be signed in to change notification settings - Fork 762
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
Scaffold required resource snippet based on the resourceType & apiVersion #2172
Conversation
using Bicep.LanguageServer.Completions; | ||
|
||
namespace Bicep.LanguageServer.Snippets | ||
{ | ||
public class SnippetsProvider : ISnippetsProvider | ||
{ | ||
private Dictionary<string, string> resourceTypeToBodyMap = new Dictionary<string, string>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resourceTypeToBodyMap [](start = 43, length = 21)
Is it possible for the dictionaries to be modified concurrently?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And could you add comments to these to explain what they are storing and how that's used?
In reply to: 610234912 [](ancestors = 610234912)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comments here:
9b3995e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about the concurrency question? Can multiple threads be modifying the dictionary at the same time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I missed this. I don't see a problem with resourceTypeToBodyMap and resourceTypeToDependentsMap as they are modified during Initialize(..). Should happen only once. I am not entirely sure of resourceBodySnippetsCache. I updated to use ConcurrentDictionary to be safe. Let me know if you see any issues or think we need locking mechanism instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added some comments and questions.
How do I trigger this? I tried the vsix attached to this build and couldn't figure it out. |
I would like to discuss taking this a step further in our next DSL discussion. This PR has the snippet sourced from a static snippet template. How do we make this more dynamic so snippets don't require updating over time with new api-versions and additional resource types? Can the required properties be pulled from the swagger spec to populate this scaffolding? |
100% agree. Even though our swagger info is incomplete when it comes to required properties, it will be a great improvement regardless. (And it will also generate issues that should help us drive improvements to required properties in swaggers.) |
My understanding is that was what #804 was created to address. I'm a bit confused as this PR doesn't seem to be addressing that feature requrest. @bhsubra would you mind adding a description of what this PR is fixing? |
@anthony-c-martin , updated the description. Could you please take a look and let me know what I am missing? Thanks! |
@alex-frankel , updated description and attached an example gif. Could you please take a look? Thanks! |
My understanding is that the feature request is to generate snippets at runtime, purely based off type information (not from user-submitted files). To give a concrete example (cursor is We don't have any user-submitted snippets available for this type, so the best we can offer is However, once I've accepted the completion of So in this case, because we know from the type system that these required fields must be supplied, we could instead dynamically generate a snippet that looks like: {
name: $1
kind: $2
sku: $3
location: $4
$0
} The same applies at different levels of nesting - e.g. if you've got something like: resource storage 'Microsoft.Storage/storageAccounts@2021-02-01' = {
name: 'asdf'
kind: 'BlobStorage'
location: 'West US'
sku: |
} Again, the type system knows that {
name: $1
$0
} |
@anthony-c-martin bingo. I think this PR can be merged as it's a step in the right direction and a new PR can be created for the snippet generation functionality? |
Yup, totally |
e97046a
to
8ce87e0
Compare
src/Bicep.LangServer/Snippets/Templates/res-automation-module.bicep
Outdated
Show resolved
Hide resolved
...rver.IntegrationTests/Completions/SnippetTemplates/res-automation-module/main.combined.bicep
Outdated
Show resolved
Hide resolved
return GetResourceBodyCompletionSnippetFromSwaggerSpec(typeSymbol, label); | ||
} | ||
|
||
private Snippet GetResourceBodyCompletionSnippetFromSwaggerSpec(TypeSymbol typeSymbol, string label) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] GetResourceBodyCompletionSnippetFromAzTypes ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated here:
4fc7f62
|
||
if (typeProperty.TypeReference.Type is ObjectType objectType) | ||
{ | ||
snippetText += "\t" + typeProperty.Name + ": {\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is related to one of the screenshots I posted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed formatting here:
c1e6263
|
||
foreach (KeyValuePair<string, TypeProperty> kvp in objectType.Properties.OrderBy(x => x.Key)) | ||
{ | ||
snippetText = GetSnippetText(kvp.Value, snippetText, ref index); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be +=
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored the code here to use StringBuilder instead:
4fc7f62
|
||
if (typeProperty.TypeReference.Type is ObjectType objectType) | ||
{ | ||
snippetText += "\t" + typeProperty.Name + ": {\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In #2341, I believe @jfleisher has done the work to construct a well-formatted partial document from Bicep syntax nodes. I wonder if it's worth using what he's done - that way there would be no need to manually format the document via text manipulation (which I'm sure has a bunch of edge cases).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have any canonical ordering that we should follow when generating the required property snippets? For example should the |
c9ad548
to
4509dd1
Compare
Not everything is applicable, but we should follow the guidance from the quick start contribution guide: https://github.com/Azure/azure-quickstart-templates/blob/master/1-CONTRIBUTION-GUIDE/best-practices.md#resources |
Yes - I think empty object ( |
721c61c
to
43a0fe1
Compare
I have an idea how we can approach it, but we should discuss with the rest of the team tomorrow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is really cool! Thanks for getting this done!
Fixes #804
Provides resource body snippet completion for static templates and swagger