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

Add deprecation annotations for RPCs marked "deprecated=true" #316

Merged
merged 3 commits into from
Oct 28, 2024

Conversation

eseay
Copy link
Contributor

@eseay eseay commented Oct 24, 2024

This enhances the ConnectClientGenerator to inspect the deprecated option and annotate the generated service functions accordingly.

  • For async/await functions, the existing @available annotation, which only exists for iOS, is adjusted accordingly to introduce and deprecate the function at v13, since that is when concurrency was first made available.
    • @rebello95 should we consider adjusting both my deprecation annotation and the existing annotation to account for the other supported platforms of the library?
  • Since no pattern was established for generated callback functions, I enhanced their generation to include @available annotations for all supported platforms. The "introduced" and "deprecated" versions for those platforms were determined by the minimum supported version of the respective platform defined in Package.swift.

Adding the following RPC...

rpc SayDeprecated(SayRequest) returns (SayResponse) {
  option idempotency_level = NO_SIDE_EFFECTS;
  option deprecated = true;
}

...to the ElizaService defined in the examples-go repository, from which the Eliza sample app sources are generated, and regenerating the Swift service (setting GenerateCallbackMethods=true to also demonstrate callback behavior) yields the following result:

@available(iOS, introduced: 12, deprecated: 12, message: "This function has been marked deprecated.")
@available(macOS, introduced: 10.15, deprecated: 10.15, message: "This function has been marked deprecated.")
@available(tvOS, introduced: 13, deprecated: 13, message: "This function has been marked deprecated.")
@available(watchOS, introduced: 6, deprecated: 6, message: "This function has been marked deprecated.")
@discardableResult
func `sayDeprecated`(request: Connectrpc_Eliza_V1_SayRequest, headers: Connect.Headers, completion: @escaping @Sendable (ResponseMessage<Connectrpc_Eliza_V1_SayResponse>) -> Void) -> Connect.Cancelable

@available(iOS, introduced: 13, deprecated: 13, message: "This function has been marked deprecated.")
func `sayDeprecated`(request: Connectrpc_Eliza_V1_SayRequest, headers: Connect.Headers) async -> ResponseMessage<Connectrpc_Eliza_V1_SayResponse>

The generated code for the existing Say RPC remains unchanged:

/// Say is a unary RPC. Eliza responds to the prompt with a single sentence.
@discardableResult
func `say`(request: Connectrpc_Eliza_V1_SayRequest, headers: Connect.Headers, completion: @escaping @Sendable (ResponseMessage<Connectrpc_Eliza_V1_SayResponse>) -> Void) -> Connect.Cancelable

/// Say is a unary RPC. Eliza responds to the prompt with a single sentence.
@available(iOS 13, *)
func `say`(request: Connectrpc_Eliza_V1_SayRequest, headers: Connect.Headers) async -> ResponseMessage<Connectrpc_Eliza_V1_SayResponse>

The same additions have been made to the ConnectMockGenerator.

Closes #305

@eseay eseay requested a review from rebello95 October 24, 2024 15:34
@eseay eseay force-pushed the eseay/305-deprecation branch from 6be74d8 to 4ee7dcb Compare October 24, 2024 17:36
Copy link
Contributor Author

@eseay eseay left a comment

Choose a reason for hiding this comment

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

A couple in-context notes for y'all to look at as well @rebello95 @jhump. Thanks!


func callbackAvailabilityAnnotation() -> String? {
if self.options.deprecated {
// swiftlint:disable line_length
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rebello95 @jhump Let me know if this is acceptable. I use SwiftLint in my own repos as well, so I know the rules exist for a purpose; however, I may propose disabling this specific rule in this specific context to improve legibility in the editor and to more closely mimic what will actually be output at the time of generation.

Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems fine to me, doing additional gymnastics would be a bit excessive 😉

Comment on lines 243 to 250
func asyncAwaitAvailabilityAnnotation() -> String? {
if self.options.deprecated {
// swiftlint:disable:next line_length
return "@available(iOS, introduced: 13, deprecated: 13, message: \"This function has been marked deprecated.\")"
} else {
return nil
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This function signature and behavior differs from its sibling defined in ConnectClientGenerator since the entire type is already annotated with an @available(iOS 13, *) in the generated mock. Because of that existing annotation, we only need to produce something if in the case that it's more restrictive than the availability rules defined at the higher scope.

@eseay eseay requested a review from jhump October 24, 2024 18:05
@eseay eseay marked this pull request as ready for review October 24, 2024 18:05
@rebello95
Copy link
Collaborator

@rebello95 should we consider adjusting both my deprecation annotation and the existing annotation to account for the other supported platforms of the library?

Yes, I think that would be great 👍🏽 thanks for flagging.

Copy link
Collaborator

@rebello95 rebello95 left a comment

Choose a reason for hiding this comment

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

Thanks for implementing this!


func callbackAvailabilityAnnotation() -> String? {
if self.options.deprecated {
// swiftlint:disable line_length
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems fine to me, doing additional gymnastics would be a bit excessive 😉

if self.options.deprecated {
// swiftlint:disable line_length
return """
@available(iOS, introduced: 12, deprecated: 12, message: "This function has been marked deprecated.")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thoughts on changing these messages to "This RPC has been marked as deprecated in its .proto file."?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Even clearer - a good move in my book!

@@ -201,6 +207,30 @@ private extension MethodDescriptor {
}
}

func callbackAvailabilityAnnotation() -> String? {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think all these helper functions can be private

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I left them without explicit access to align with the functions that were already there; however, I think we're good on not needing to specify access level since the enclosing extension private extension MethodDescriptor is already marked.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah didn't realize these were inside a private extension 👍🏽

@eseay eseay requested a review from rebello95 October 28, 2024 14:27
Signed-off-by: Eddie Seay <[email protected]>
@eseay eseay merged commit cbfac0a into main Oct 28, 2024
15 checks passed
@eseay eseay deleted the eseay/305-deprecation branch October 28, 2024 17:00
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.

Generate @available annotations on deprecated RPCs
2 participants