| <!-- WARNING: This file is machine generated by //src/tests/fidl/source_compatibility/gen, do not edit. --> |
| |
| Note: This document covers API impact only. For more details, see the |
| [ABI compatibility page](/docs/development/languages/fidl/guides/compatibility/README.md) |
| |
| # Add a protocol method |
| |
| ## Overview |
| |
| -|[init](#init)|[step 1](#step-1)|[step 2](#step-2)|[step 3](#step-3)|[step 4](#step-4) |
| ---|---|---|---|---|--- |
| fidl|[link](#fidl-init)||[link](#fidl-2)||[link](#fidl-4) |
| dart|[link](#dart-init)|||[link](#dart-3)| |
| go|[link](#go-init)|[link](#go-1)||[link](#go-3)| |
| hlcpp|[link](#hlcpp-init)|||[link](#hlcpp-3)| |
| llcpp|[link](#llcpp-init)|||[link](#llcpp-3)| |
| rust|[link](#rust-init)|[link](#rust-1)||[link](#rust-3)| |
| |
| ## Initial State {#init} |
| |
| ### FIDL {#fidl-init} |
| |
| ```fidl |
| protocol Example { |
| ExistingMethod(); |
| }; |
| ``` |
| |
| ### Dart {#dart-init} |
| |
| ```dart |
| class Server extends fidllib.Example { |
| @override |
| Future<void> existingMethod() async {} |
| } |
| |
| void client(fidllib.ExampleProxy client) async { |
| await client.existingMethod(); |
| } |
| ``` |
| |
| ### Go {#go-init} |
| |
| ```go |
| type client struct { |
| addMethod *lib.ExampleWithCtxInterface |
| } |
| |
| func (c client) test() { |
| c.addMethod.ExistingMethod(context.Background()) |
| } |
| |
| type server struct{} |
| |
| // Assert that server implements the Example interface |
| var _ lib.ExampleWithCtx = &server{} |
| |
| func (*server) ExistingMethod(fidl.Context) error { |
| return nil |
| } |
| |
| ``` |
| |
| ### HLCPP {#hlcpp-init} |
| |
| ```cpp |
| class Server : public fidl_test::Example { |
| void ExistingMethod() final {} |
| }; |
| |
| void client(fidl_test::ExamplePtr client) { client->ExistingMethod(); } |
| ``` |
| |
| ### LLCPP {#llcpp-init} |
| |
| ```cpp |
| class Server final : public fidl::WireServer<fidl_test::Example> { |
| public: |
| void ExistingMethod(ExistingMethodRequestView request, |
| ExistingMethodCompleter::Sync& completer) final {} |
| }; |
| |
| void client(fidl::WireClient<fidl_test::Example> client) { client->ExistingMethod(); } |
| ``` |
| |
| ### Rust {#rust-init} |
| |
| ```rust |
| struct ExampleFakeProxy; |
| |
| impl fidl_lib::ExampleProxyInterface for ExampleFakeProxy { |
| fn existing_method(&self) -> Result<(), fidl::Error> { |
| Ok(()) |
| } |
| } |
| |
| async fn example_service(chan: fasync::Channel) -> Result<(), fidl::Error> { |
| let mut stream = fidl_lib::ExampleRequestStream::from_channel(chan); |
| while let Some(req) = stream.try_next().await? { |
| match req { |
| fidl_lib::ExampleRequest::ExistingMethod { .. } => {} |
| } |
| } |
| Ok(()) |
| } |
| ``` |
| |
| ## Update Source Code {#step-1} |
| |
| ### Go {#go-1} |
| |
| - Embed the protocol's `WithCtxTransitionBase` struct into the server type. |
| |
| ```diff |
| type client struct { |
| addMethod *lib.ExampleWithCtxInterface |
| } |
| |
| func (c client) test() { |
| c.addMethod.ExistingMethod(context.Background()) |
| } |
| |
| - type server struct{} |
| + type server struct { |
| + lib.ExampleWithCtxTransitionalBase |
| + } |
| |
| // Assert that server implements the Example interface |
| var _ lib.ExampleWithCtx = &server{} |
| |
| func (*server) ExistingMethod(fidl.Context) error { |
| return nil |
| } |
| |
| |
| ``` |
| |
| ### Rust {#rust-1} |
| |
| - Add `#[allow(unreachable_patterns)]` to the server's request stream match. |
| - Add an underscore arm to the server's request stream match. |
| |
| ```diff |
| struct ExampleFakeProxy; |
| |
| impl fidl_lib::ExampleProxyInterface for ExampleFakeProxy { |
| fn existing_method(&self) -> Result<(), fidl::Error> { |
| Ok(()) |
| } |
| } |
| |
| async fn example_service(chan: fasync::Channel) -> Result<(), fidl::Error> { |
| let mut stream = fidl_lib::ExampleRequestStream::from_channel(chan); |
| while let Some(req) = stream.try_next().await? { |
| + #[allow(unreachable_patterns)] |
| match req { |
| fidl_lib::ExampleRequest::ExistingMethod { .. } => {} |
| + _ => {} |
| } |
| } |
| Ok(()) |
| } |
| |
| ``` |
| |
| ## Update FIDL Library {#step-2} |
| |
| - Add the new method and mark it with the `[Transitional]` attribute. |
| |
| ```diff |
| protocol Example { |
| ExistingMethod(); |
| + @transitional |
| + NewMethod(); |
| }; |
| |
| ``` |
| |
| ## Update Source Code {#step-3} |
| |
| ### Dart {#dart-3} |
| |
| - Add the new method to protocol implementations. |
| - Start using the new method in client code. |
| |
| ```diff |
| class Server extends fidllib.Example { |
| @override |
| Future<void> existingMethod() async {} |
| + |
| + @override |
| + Future<void> newMethod() async {} |
| } |
| |
| void client(fidllib.ExampleProxy client) async { |
| await client.existingMethod(); |
| + await client.newMethod(); |
| } |
| |
| ``` |
| |
| ### Go {#go-3} |
| |
| - Implement the new method for the server type. |
| - Remove the protocol's `WithCtxTransitionBase` struct from the server type. |
| - Start using the new method in client code. |
| |
| ```diff |
| type client struct { |
| addMethod *lib.ExampleWithCtxInterface |
| } |
| |
| func (c client) test() { |
| c.addMethod.ExistingMethod(context.Background()) |
| + c.addMethod.NewMethod(context.Background()) |
| } |
| |
| - type server struct { |
| - lib.ExampleWithCtxTransitionalBase |
| - } |
| + type server struct{} |
| |
| // Assert that server implements the Example interface |
| var _ lib.ExampleWithCtx = &server{} |
| |
| func (*server) ExistingMethod(fidl.Context) error { |
| return nil |
| } |
| |
| + func (*server) NewMethod(fidl.Context) error { |
| + return nil |
| + } |
| + |
| |
| ``` |
| |
| ### HLCPP {#hlcpp-3} |
| |
| - Add the new method to protocol implementations. |
| - Start using the new method in client code. |
| |
| ```diff |
| class Server : public fidl_test::Example { |
| void ExistingMethod() final {} |
| + void NewMethod() final {} |
| }; |
| |
| - void client(fidl_test::ExamplePtr client) { client->ExistingMethod(); } |
| + void client(fidl_test::ExamplePtr client) { |
| + client->ExistingMethod(); |
| + client->NewMethod(); |
| + } |
| |
| ``` |
| |
| ### LLCPP {#llcpp-3} |
| |
| - Add the new method to protocol implementations. |
| - Start using the new method in client code. |
| |
| ```diff |
| class Server final : public fidl::WireServer<fidl_test::Example> { |
| public: |
| void ExistingMethod(ExistingMethodRequestView request, |
| ExistingMethodCompleter::Sync& completer) final {} |
| + void NewMethod(NewMethodRequestView request, NewMethodCompleter::Sync& completer) final {} |
| }; |
| |
| - void client(fidl::WireClient<fidl_test::Example> client) { client->ExistingMethod(); } |
| + void client(fidl::WireClient<fidl_test::Example> client) { |
| + client->ExistingMethod(); |
| + client->NewMethod(); |
| + } |
| |
| ``` |
| |
| ### Rust {#rust-3} |
| |
| - Add the new method to the protocol's `ProxyInterface` implementation. |
| - Remove `#[allow(unreachable_patterns)]` from the server's request stream match. |
| - Replace the underscore arm in the server's request stream match with one that handles the new method. |
| |
| ```diff |
| struct ExampleFakeProxy; |
| |
| impl fidl_lib::ExampleProxyInterface for ExampleFakeProxy { |
| fn existing_method(&self) -> Result<(), fidl::Error> { |
| + Ok(()) |
| + } |
| + fn new_method(&self) -> Result<(), fidl::Error> { |
| Ok(()) |
| } |
| } |
| |
| async fn example_service(chan: fasync::Channel) -> Result<(), fidl::Error> { |
| let mut stream = fidl_lib::ExampleRequestStream::from_channel(chan); |
| while let Some(req) = stream.try_next().await? { |
| - #[allow(unreachable_patterns)] |
| match req { |
| fidl_lib::ExampleRequest::ExistingMethod { .. } => {} |
| - _ => {} |
| + fidl_lib::ExampleRequest::NewMethod { .. } => {} |
| } |
| } |
| Ok(()) |
| } |
| |
| ``` |
| |
| ## Update FIDL Library {#step-4} |
| |
| - Remove the `[Transitional]` attribute from the new method. |
| |
| ```diff |
| protocol Example { |
| ExistingMethod(); |
| - @transitional |
| NewMethod(); |
| }; |
| |
| ``` |
| |