Note: This document covers API impact only. For more details, see the ABI compatibility page

Add a protocol method

Overview

- init step 1 step 2 step 3 step 4
fidl link link link
dart link link
go link link link
hlcpp link link
llcpp link link
rust link link link

Initial State {#init}

FIDL {#fidl-init}

  1. protocol Example {
  2. ExistingMethod();
  3. };

Dart {#dart-init}

  1. class Server extends fidllib.Example {
  2. @override
  3. Future<void> existingMethod() async {}
  4. }
  5. void client(fidllib.ExampleProxy client) async {
  6. await client.existingMethod();
  7. }

Go {#go-init}

  1. type client struct {
  2. addMethod *lib.ExampleWithCtxInterface
  3. }
  4. func (c client) test() {
  5. c.addMethod.ExistingMethod(context.Background())
  6. }
  7. type server struct{}
  8. // Assert that server implements the Example interface
  9. var _ lib.ExampleWithCtx = &server{}
  10. func (*server) ExistingMethod(fidl.Context) error {
  11. return nil
  12. }

HLCPP {#hlcpp-init}

  1. class Server : public fidl_test::Example {
  2. void ExistingMethod() final {}
  3. };
  4. void client(fidl_test::ExamplePtr client) { client->ExistingMethod(); }

LLCPP {#llcpp-init}

  1. class Server final : public fidl_test::Example::Interface {
  2. public:
  3. void ExistingMethod(ExistingMethodCompleter::Sync& completer) final {}
  4. };
  5. void client(fidl::Client<fidl_test::Example> client) { client->ExistingMethod(); }

Rust {#rust-init}

  1. struct ExampleFakeProxy;
  2. impl fidl_lib::ExampleProxyInterface for ExampleFakeProxy {
  3. fn existing_method(&self) -> Result<(), fidl::Error> {
  4. Ok(())
  5. }
  6. }
  7. async fn example_service(chan: fasync::Channel) -> Result<(), fidl::Error> {
  8. let mut stream = fidl_lib::ExampleRequestStream::from_channel(chan);
  9. while let Some(req) = stream.try_next().await? {
  10. match req {
  11. fidl_lib::ExampleRequest::ExistingMethod { .. } => {}
  12. }
  13. }
  14. Ok(())
  15. }

Update Source Code {#step-1}

Go {#go-1}

  • Embed the protocol’s WithCtxTransitionBase struct into the server type.
  1. type client struct {
  2. addMethod *lib.ExampleWithCtxInterface
  3. }
  4. func (c client) test() {
  5. c.addMethod.ExistingMethod(context.Background())
  6. }
  7. - type server struct{}
  8. + type server struct {
  9. + lib.ExampleWithCtxTransitionalBase
  10. + }
  11. // Assert that server implements the Example interface
  12. var _ lib.ExampleWithCtx = &server{}
  13. func (*server) ExistingMethod(fidl.Context) error {
  14. return nil
  15. }

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.
  1. struct ExampleFakeProxy;
  2. impl fidl_lib::ExampleProxyInterface for ExampleFakeProxy {
  3. fn existing_method(&self) -> Result<(), fidl::Error> {
  4. Ok(())
  5. }
  6. }
  7. async fn example_service(chan: fasync::Channel) -> Result<(), fidl::Error> {
  8. let mut stream = fidl_lib::ExampleRequestStream::from_channel(chan);
  9. while let Some(req) = stream.try_next().await? {
  10. + #[allow(unreachable_patterns)]
  11. match req {
  12. fidl_lib::ExampleRequest::ExistingMethod { .. } => {}
  13. + _ => {}
  14. }
  15. }
  16. Ok(())
  17. }

Update FIDL Library {#step-2}

  • Add the new method and mark it with the [Transitional] attribute.
  1. protocol Example {
  2. ExistingMethod();
  3. + [Transitional]
  4. + NewMethod();
  5. };

Update Source Code {#step-3}

Dart {#dart-3}

  • Add the new method to protocol implementations.
  • Start using the new method in client code.
  1. class Server extends fidllib.Example {
  2. @override
  3. Future<void> existingMethod() async {}
  4. +
  5. + @override
  6. + Future<void> newMethod() async {}
  7. }
  8. void client(fidllib.ExampleProxy client) async {
  9. await client.existingMethod();
  10. + await client.newMethod();
  11. }

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.
  1. type client struct {
  2. addMethod *lib.ExampleWithCtxInterface
  3. }
  4. func (c client) test() {
  5. c.addMethod.ExistingMethod(context.Background())
  6. + c.addMethod.NewMethod(context.Background())
  7. }
  8. - type server struct {
  9. - lib.ExampleWithCtxTransitionalBase
  10. - }
  11. + type server struct{}
  12. // Assert that server implements the Example interface
  13. var _ lib.ExampleWithCtx = &server{}
  14. func (*server) ExistingMethod(fidl.Context) error {
  15. return nil
  16. }
  17. + func (*server) NewMethod(fidl.Context) error {
  18. + return nil
  19. + }
  20. +

HLCPP {#hlcpp-3}

  • Add the new method to protocol implementations.
  • Start using the new method in client code.
  1. class Server : public fidl_test::Example {
  2. void ExistingMethod() final {}
  3. + void NewMethod() final {}
  4. };
  5. - void client(fidl_test::ExamplePtr client) { client->ExistingMethod(); }
  6. + void client(fidl_test::ExamplePtr client) {
  7. + client->ExistingMethod();
  8. + client->NewMethod();
  9. + }

LLCPP {#llcpp-3}

  • Add the new method to protocol implementations.
  • Start using the new method in client code.
  1. class Server final : public fidl_test::Example::Interface {
  2. public:
  3. void ExistingMethod(ExistingMethodCompleter::Sync& completer) final {}
  4. + void NewMethod(NewMethodCompleter::Sync& completer) final {}
  5. };
  6. - void client(fidl::Client<fidl_test::Example> client) { client->ExistingMethod(); }
  7. + void client(fidl::Client<fidl_test::Example> client) {
  8. + client->ExistingMethod();
  9. + client->NewMethod();
  10. + }

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.
  1. struct ExampleFakeProxy;
  2. impl fidl_lib::ExampleProxyInterface for ExampleFakeProxy {
  3. fn existing_method(&self) -> Result<(), fidl::Error> {
  4. + Ok(())
  5. + }
  6. + fn new_method(&self) -> Result<(), fidl::Error> {
  7. Ok(())
  8. }
  9. }
  10. async fn example_service(chan: fasync::Channel) -> Result<(), fidl::Error> {
  11. let mut stream = fidl_lib::ExampleRequestStream::from_channel(chan);
  12. while let Some(req) = stream.try_next().await? {
  13. - #[allow(unreachable_patterns)]
  14. match req {
  15. fidl_lib::ExampleRequest::ExistingMethod { .. } => {}
  16. - _ => {}
  17. + fidl_lib::ExampleRequest::NewMethod { .. } => {}
  18. }
  19. }
  20. Ok(())
  21. }

Update FIDL Library {#step-4}

  • Remove the [Transitional] attribute from the new method.
  1. protocol Example {
  2. ExistingMethod();
  3. - [Transitional]
  4. NewMethod();
  5. };