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

Change a bits from strict to flexible

Overview

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

Initial State {#init}

FIDL {#fidl-init}

  1. strict bits Flags {
  2. OPTION_A = 1;
  3. OPTION_B = 2;
  4. };

Dart {#dart-init}

  1. int useBits(fidllib.Flags bits) {
  2. if (bits.hasUnknownBits()) {
  3. return bits.getUnknownBits();
  4. }
  5. var result = fidllib.Flags.$none;
  6. if ((bits & fidllib.Flags.optionA).$value != 0) {
  7. result |= fidllib.Flags.$mask;
  8. }
  9. return result.$value;
  10. }

Go {#go-init}

  1. func useBits(bits lib.Flags) uint32 {
  2. if bits.HasUnknownBits() {
  3. return uint32(bits.GetUnknownBits())
  4. }
  5. var result lib.Flags = 0
  6. if bits.HasBits(lib.FlagsOptionA) {
  7. result |= lib.Flags_Mask
  8. }
  9. return uint32(result)
  10. }

HLCPP {#hlcpp-init}

  1. template <fidl_test::Flags flag_value>
  2. class BitsTemplate {};
  3. fidl_test::Flags use_bits(fidl_test::Flags bits) {
  4. fidl_test::Flags result = bits | fidl_test::Flags::OPTION_A;
  5. result &= fidl_test::FlagsMask;
  6. return result;
  7. }

LLCPP {#llcpp-init}

  1. uint32_t use_bits(fidl_test::Flags bits) {
  2. auto result = fidl_test::Flags::TruncatingUnknown(7u);
  3. if (bits & fidl_test::Flags::OPTION_A) {
  4. result |= fidl_test::Flags::kMask;
  5. }
  6. return uint32_t(result);
  7. }

Rust {#rust-init}

  1. fn use_bits(bits: &fidl_lib::Flags) -> fidl_lib::Flags {
  2. let mut result = fidl_lib::Flags::empty();
  3. if bits.contains(fidl_lib::Flags::OptionA) {
  4. result.set(fidl_lib::Flags::all(), true);
  5. }
  6. return result;
  7. }

Update Source Code {#step-1}

HLCPP {#hlcpp-1}

  • Remove any usages of the bits type as a non-type template parameter. This is not supported for flexible bits since they are implemented as a regular class, which cannot be used as a non-type template parameter.
  • Remove any usages of the bits mask member. This generated value is renamed for flexible bits, so it must be temporarily hardcoded.
  1. - template <fidl_test::Flags flag_value>
  2. - class BitsTemplate {};
  3. -
  4. fidl_test::Flags use_bits(fidl_test::Flags bits) {
  5. fidl_test::Flags result = bits | fidl_test::Flags::OPTION_A;
  6. - result &= fidl_test::FlagsMask;
  7. + fidl_test::Flags mask = fidl_test::Flags::OPTION_A | fidl_test::Flags::OPTION_B;
  8. + result &= mask;
  9. return result;
  10. }

Update FIDL Library {#step-2}

  • Switch from strict to flexible
  1. - strict bits Flags {
  2. + flexible bits Flags {
  3. OPTION_A = 1;
  4. OPTION_B = 2;
  5. };

Update Source Code {#step-3}

HLCPP {#hlcpp-3}

  • Use the renamed ::kMask constant
  • You can now use flexible-specific APIs
  1. fidl_test::Flags use_bits(fidl_test::Flags bits) {
  2. fidl_test::Flags result = bits | fidl_test::Flags::OPTION_A;
  3. - fidl_test::Flags mask = fidl_test::Flags::OPTION_A | fidl_test::Flags::OPTION_B;
  4. - result &= mask;
  5. + auto truncated = fidl_test::Flags::TruncatingUnknown(uint32_t(result));
  6. + ZX_ASSERT(!truncated.has_unknown_bits());
  7. +
  8. + result &= fidl_test::Flags::kMask;
  9. + ZX_ASSERT(truncated == result);
  10. return result;
  11. }

LLCPP {#llcpp-3}

  • You can now use flexible-specific APIs
  1. uint32_t use_bits(fidl_test::Flags bits) {
  2. auto result = fidl_test::Flags::TruncatingUnknown(7u);
  3. if (bits & fidl_test::Flags::OPTION_A) {
  4. result |= fidl_test::Flags::kMask;
  5. + printf("%d\n", uint32_t(result.unknown_bits()));
  6. }
  7. return uint32_t(result);
  8. }

Rust {#rust-3}

  • You can now use flexible-specific APIs
  1. fn use_bits(bits: &fidl_lib::Flags) -> fidl_lib::Flags {
  2. let mut result = fidl_lib::Flags::empty();
  3. if bits.contains(fidl_lib::Flags::OptionA) {
  4. result.set(fidl_lib::Flags::all(), true);
  5. + println!("{}", result.get_unknown_bits());
  6. }
  7. return result;
  8. }