tree: 4c9fc82af9942f29276c1d83d560355790c843a2 [path history] [tgz]
  1. dart/
  2. fidl/
  3. go/
  4. hlcpp/
  5. llcpp/
  6. rust/
  7. BUILD.gn
  8. README.md
  9. test.json
  10. test_gn_sidecar.json
src/tests/fidl/source_compatibility/bits-strict-flexible/README.md

Change a bits from strict to flexible

Overview

-initstep 1step 2step 3
fidllinklink
dartlink
golink
hlcpplinklinklink
llcpplinklink
rustlinklink

Initial State

FIDL

strict bits Flags {
    OPTION_A = 1;
    OPTION_B = 2;
};

Dart

int useBits(fidllib.Flags bits) {
  if (bits.hasUnknownBits()) {
    return bits.getUnknownBits();
  }

  var result = fidllib.Flags.$none;
  if ((bits & fidllib.Flags.optionA).$value != 0) {
    result |= fidllib.Flags.$mask;
  }
  return result.$value;
}

Go

func useBits(bits lib.Flags) uint32 {
	if bits.HasUnknownBits() {
		return uint32(bits.GetUnknownBits())
	}
	var result lib.Flags = 0
	if bits.HasBits(lib.FlagsOptionA) {
		result |= lib.Flags_Mask
	}
	return uint32(result)
}

HLCPP

template <fidl_test::Flags flag_value>
class BitsTemplate {};

fidl_test::Flags use_bits(fidl_test::Flags bits) {
  fidl_test::Flags result = bits | fidl_test::Flags::OPTION_A;
  result &= fidl_test::FlagsMask;
  return result;
}

LLCPP

uint32_t use_bits(fidl_test::Flags bits) {
  auto result = fidl_test::Flags::TruncatingUnknown(7u);
  if (bits & fidl_test::Flags::OPTION_A) {
    result |= fidl_test::Flags::kMask;
  }
  return uint32_t(result);
}

Rust

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

Update Source Code

HLCPP

  • 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.
- template <fidl_test::Flags flag_value>
- class BitsTemplate {};
- 
  fidl_test::Flags use_bits(fidl_test::Flags bits) {
    fidl_test::Flags result = bits | fidl_test::Flags::OPTION_A;
-   result &= fidl_test::FlagsMask;
+   fidl_test::Flags mask = fidl_test::Flags::OPTION_A | fidl_test::Flags::OPTION_B;
+   result &= mask;
    return result;
  }

Update FIDL Library

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

Update Source Code

HLCPP

  • Use the renamed ::kMask constant
  • You can now use flexible-specific APIs
  fidl_test::Flags use_bits(fidl_test::Flags bits) {
    fidl_test::Flags result = bits | fidl_test::Flags::OPTION_A;
-   fidl_test::Flags mask = fidl_test::Flags::OPTION_A | fidl_test::Flags::OPTION_B;
-   result &= mask;
+   auto truncated = fidl_test::Flags::TruncatingUnknown(uint32_t(result));
+   ZX_ASSERT(!truncated.has_unknown_bits());
+ 
+   result &= fidl_test::Flags::kMask;
+   ZX_ASSERT(truncated == result);
    return result;
  }

LLCPP

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

Rust

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