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

[tcgc] client initialization and accessor enhancement #2027

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

tadelesh
Copy link
Member

@tadelesh tadelesh commented Dec 26, 2024

  1. Change @clientInitialization decorator's options parameter to ClientInitializationOptions type. The options now could set the client initialization method's access and client accessor's access. This is a behavior breaking change for this decorator. All specs that use this decorator should change from @clientInitialization(CustomizedOption) to `@clientInitialization({parameters: CustomizedOption})
  2. getClientInitialization now return ClientInitializationOptions types. It includes the info of the client initialization parameter list, the client initialization access value and the client accessor access value.
  3. Add clientInitialization property to SdkClientType. It indicate the initialization method's signature, including the parameter list and access, etc.

Related design could be seen in this gist: https://gist.github.com/tadelesh/bb1b04501d25dd1f19bc5b164fb79810.

Also resolve: #1696, #1702, #1707, #1715, #1518

@azure-sdk
Copy link
Collaborator

azure-sdk commented Dec 26, 2024

All changed packages have been documented.

  • @azure-tools/typespec-client-generator-core
Show changes

@azure-tools/typespec-client-generator-core - breaking ✏️

Change @clientInitialization decorator's options parameter to ClientInitializationOptions type. The options now could set the client initialization method's access and client accessor's access. This is a behavior breaking change for this decorator. All specs that use this decorator should change from @clientInitialization(CustomizedOption) to @clientInitialization({parameters: CustomizedOption}).

@azure-tools/typespec-client-generator-core - breaking ✏️

getClientInitialization now return ClientInitializationOptions types. It includes the info of the client initialization parameter list, the client initialization access value and the client accessor access value.

@azure-tools/typespec-client-generator-core - feature ✏️

Add clientInitialization property to SdkClientType. It indicate the initialization method's signature, including the parameter list and access, etc.

@tadelesh tadelesh changed the title [tcgc] client initialization and accessor refactor [tcgc] client initialization and accessor enhancement Dec 26, 2024
@azure-sdk
Copy link
Collaborator

You can try these changes here

🛝 Playground 🌐 Website 📚 Next docs

initialization: SdkInitializationType;
clientInitialization: SdkClientInitializationMethod;
Copy link
Member

@weidongxu-microsoft weidongxu-microsoft Dec 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a bit strange that SdkClientInitializationMethod is here, while SdkClientAccessor<> appears in methods?

If this SdkClientInitializationMethod is something very special, do we need a method type?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i also want to move client assessor method out of the method list. just tbd.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we doing the breaking change for initialization -> clientInitialization so we are the same as the decorator? I'm not 100% sure we need to make this change, but it's not a hill I'm going to die on

@tadelesh tadelesh force-pushed the client-initialization branch from c37f03e to cc35540 Compare January 6, 2025 05:54
@tadelesh
Copy link
Member Author

tadelesh commented Jan 6, 2025

two things to be discussed:

  1. shall we put initialization method into methods list or move client accessor method out of methods list to keep consistency?
  2. if client access is public, shall we put it to be the top-level client?

| ------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| options | `Model` | |
| scope | `valueof string` | The language scope you want this decorator to apply to. If not specified, will apply to all language emitters.<br />You can use "!" to specify negation such as "!(java, python)" or "!java, !python". |
| Name | Type | Description |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tadelesh for this design have other redmond folks signed off on it? I think it would be great to get others to look at the doc. I'll send it to DPG redmond sync to see what people think of the changes to the @clientInitialization decorator

/**
* Determines the accessibility of the client accessor method. `Access.public` means client could be got from parent client.
*/
accessorAccess?: EnumMember;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think this name is very clear, but I don't have a great suggestion. Accessible from parent? I'm just not sure that a spec author will have an understanding of "accessor" like us tcgc authors do

})
: undefined,
access: options.properties.get("access")
? options.properties.get("access").type.value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think you can do options.properties.get('access')?.type?.value || undefined, or maybe you don't even need || undefined

initialization: SdkInitializationType;
clientInitialization: SdkClientInitializationMethod;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we doing the breaking change for initialization -> clientInitialization so we are the same as the decorator? I'm not 100% sure we need to make this change, but it's not a hill I'm going to die on

clientParams.push(param);
}
}
const name = `init${client.kind === "SdkClient" ? client.name : getLibraryName(context, client.type)}`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the name doesn't super matter, should we just call it "init"? I think in terms of conflicts, since each one will be for a separate client, it should be fine

}
return diagnostics.wrap(retval);
}

function createClientAccessorMethod<TServiceOperation extends SdkServiceOperation>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just to clarify, we still have client accessor methods, denoting the relationship between a parent and child client. At the same time, instead of treating the initialization information in tcgc as a pure model, we are looking at it more like another operation. I like this way of thinking, I'm just trying to make sure I'm reading this correctly

1. Change `@clientInitialization` decorator and add `clientInitialization` property to `SdkClientType`
- Change `@clientInitialization` decorator's `options` parameter to `ClientInitializationOptions` type to accept `access` and `accessorAccess` setting.
- Add `clientInitialization` property to `SdkClientType`. It indicate the initialization method's signature, including the parameter list and access.
- When `access` set to `Access.public`, it means this client could be initialized separately, while `Access.internal` could not. Default to `Access.public` for client and `Access.internal` for sub client.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you make clear that this is the access for the initialization property?

With this design, there seem to be 3 accesses associated with a client.

  1. The access of the client itself. This can't be toggled rn, it's always public
  2. The access of the client's init. If public, can directly init, else you can not
  3. The access of the client's accessor. If public, you can create this client from its parent. Else, not

The `InnerGroup`'s `initialization` model's properties contains a property named `blobName`. The method is `public`.
The method `upload` no longer has `blobName` parameter, its corresponding operation's parameter `blobName` is mapped to the `blobName` property of `InnerGroup`'s `initialization` model.

2. Move client accessor method out of the normal methods list of client and add a new `clientAccessor` property to put it.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will the clientAccessor be on the parent client or the child client? Off the top of my head, we want to know a client's subclients, so I think it would be better to have this on the parent


3. Consolidate `@client` and `@operationGroup`
- Deprecate decorator `@operationGroup` and `SdkOperationGroup` type.
- Current explicitly `@operationGroup` could be migrated to `@client`. If `@client` is nested, then it is a sub-client, will follow previous operation group default logic.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when we move @operationGroup to @client, we will move them to a client with init access internal and accessor access public, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[tcgc] have @clientInitialization decorator take in optional access input
5 participants