chromium/content/web_test/common/mojo_optional_numerics_unittest.mojom

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module content.optional_numerics_unittest.mojom;

enum RegularEnum {
  kFoo = 1,
  kBar = 2,
};

// Struct made out of optional numerics.
struct OptionalNumericsStruct {
  bool? optional_bool;
  uint8? optional_uint8;
  int8? optional_int8;
  uint16? optional_uint16;
  int16? optional_int16;
  uint32? optional_uint32;
  int32? optional_int32;
  uint64? optional_uint64;
  int64? optional_int64;
  float? optional_float;
  double? optional_double;
  RegularEnum? optional_enum;
};

// There are two implementations of this interface: a C++ one to test
// JS correctly encodes optional numerics in function params and a JS one to
// test JS correctly decodes optional numerics in function params.
interface Params {
  // The following methods help test that JS correctly handles null optional
  // numerics.
  //
  // Runs the empty callback. CHECKs if `optional_bool` is not null.
  SendNullBool(bool? optional_bool) => ();
  // Runs the empty callback. CHECKs if `optional_uint8` is not null.
  SendNullUint8(uint8? optional_uint8) => ();
  // Runs the empty callback. CHECKs if `optional_int8` is not null.
  SendNullInt8(int8? optional_int8) => ();
  // Runs the empty callback. CHECKs if `optional_uint16` is not null.
  SendNullUint16(uint16? optional_uint16) => ();
  // Runs the empty callback. CHECKs if `optional_int16` is not null.
  SendNullInt16(int16? optional_int16) => ();
  // Runs the empty callback. CHECKs if `optional_uint32` is not null.
  SendNullUint32(uint32? optional_uint32) => ();
  // Runs the empty callback. CHECKs if `optional_int32` is not null.
  SendNullInt32(int32? optional_int32) => ();
  // Runs the empty callback. CHECKs if `optional_uint64` is not null.
  SendNullUint64(uint64? optional_uint64) => ();
  // Runs the empty callback. CHECKs if `optional_int64` is not null.
  SendNullInt64(int64? optional_int64) => ();
  // Runs the empty callback. CHECKs if `optional_float` is not null.
  SendNullFloat(float? optional_float) => ();
  // Runs the empty callback. CHECKs if `optional_double` is not null.
  SendNullDouble(double? optional_double) => ();
  // Runs the empty callback. CHECKs if `optional_enum` is not null.
  SendNullEnum(RegularEnum? optional_enum) => ();

  // Runs the empty callback. CHECKs if `optional_bools` is not null.
  SendNullBools(array<bool?> optional_bools) => ();
  // Runs the empty callback. CHECKs if `optional_int16s` is not null.
  SendNullInt16s(array<int16?> optional_int16s) => ();
  // Runs the empty callback. CHECKs if `optional_uint32s` is not null.
  SendNullUint32s(array<uint32?> optional_uint32s) => ();
  // Runs the empty callback. CHECKs if `optional_doubles` is not null.
  SendNullDoubles(array<double?> optional_doubles) => ();
  // Runs the empty callback. CHECKs if `optional_enums` is not null.
  SendNullEnums(array<RegularEnum?> optional_enums) => ();

  // Runs the empty callback. CHECKs if `optional_bools` is not null.
  SendNullBoolMap(map<int32, bool?> values) => ();
  // Runs the empty callback. CHECKs if `optional_bools` is not null.
  SendNullDoubleMap(map<int32, double?> values) => ();
  // Runs the empty callback. CHECKs if `optional_bools` is not null.
  SendNullEnumMap(map<int32, RegularEnum?> values) => ();

  // The following methods help test that JS correctly handles optional
  // numerics with a value.
  //
  // Runs callback with `optional_bool`.
  SendOptionalBool(bool? optional_bool) => (bool value);
  // Runs callback with `optional_uint8`.
  SendOptionalUint8(uint8? optional_uint8) => (uint8 value);
  // Runs callback with `optional_int8`.
  SendOptionalInt8(int8? optional_int8) => (int8 value);
  // Runs callback with `optional_uint16`.
  SendOptionalUint16(uint16? optional_uint16) => (uint16 value);
  // Runs callback with `optional_int16`.
  SendOptionalInt16(int16? optional_int16) => (int16 value);
  // Runs callback with `optional_uint32`.
  SendOptionalUint32(uint32? optional_uint32) => (uint32 value);
  // Runs callback with `optional_int32`.
  SendOptionalInt32(int32? optional_int32) => (int32 value);
  // Runs callback with `optional_uint64`.
  SendOptionalUint64(uint64? optional_uint64) => (uint64 value);
  // Runs callback with `optional_int64`.
  SendOptionalInt64(int64? optional_int64) => (int64 value);
  // Runs callback with `optional_float`.
  SendOptionalFloat(float? optional_float) => (float value);
  // Runs callback with `optional_double`.
  SendOptionalDouble(double? optional_double) => (double value);
  // Runs callback with `optional_enum`.
  SendOptionalEnum(RegularEnum? optional_enum) => (RegularEnum value);

  // Runs callback with `optional_enum`.
  SendOptionalBools(array<bool?> optional_enums) => (array<bool> values);
  // Runs callback with `optional_int16`.
  SendOptionalInt16s(array<int16?> optional_int16s) => (array<int16> values);
  // Runs callback with `optional_uint32`.
  SendOptionalUint32s(array<uint32?> optional_uint32s)
        => (array<uint32> values);
  // Runs callback with `optional_double`.
  SendOptionalDoubles(array<double?> optional_doubles)
        => (array<double> values);
  // Runs callback with `optional_enum`.
  SendOptionalEnums(array<RegularEnum?> optional_enums)
        => (array<RegularEnum> values);

  // Runs callback by unwrapping all null values.
  SendOptionalBoolMap(map<int32, bool?> values)
        => (map<int32, bool> values);
  // Runs callback by unwrapping all null values.
  SendOptionalDoubleMap(map<int32, double?> values)
        => (map<int32, double> values);
  // Runs callback by unwrapping all null values.
  SendOptionalEnumMap(map<int32, RegularEnum?> values)
        => (map<int32, RegularEnum> values);

  // Runs a callback with null. Helps test that JS can correctly handle null
  // structs with optional numerics.
  SendNullStructWithOptionalNumerics(OptionalNumericsStruct? s) => ();

  // Helps test that JS can correctly handle a struct with null optional
  // numerics.
  // Runs the empty callback. CHECKs if the values in the struct are not null.
  SendStructWithNullOptionalNumerics(OptionalNumericsStruct s) => ();

  // Runs callback the values in the struct. Helps test that JS can correctly
  // handle a struct with optional numerics.
  SendStructWithOptionalNumerics(OptionalNumericsStruct s) => (
    bool bool_value,
    uint8 uint8_value,
    int8 int8_value,
    uint16 uint16_value,
    int16 int16_value,
    uint32 uint32_value,
    int32 int32_value,
    uint64 uint64_value,
    int64 int64_value,
    float float_value,
    double double_value,
    RegularEnum enum_value);
};

// There are two implementations of this interface: a C++ one to test
// JS correctly decodes optional numerics in response params and a JS one to
// test JS correctly encodes optional numerics in response params.
interface ResponseParams {
  // The following methods help test that JS can correctly handle null optional
  // numerics in response params.
  //
  // Returns a null optional bool.
  GetNullBool() => (bool? optional_value);
  // Returns a null optional uint8.
  GetNullUint8() => (uint8? optional_value);
  // Returns a null optional int8.
  GetNullInt8() => (int8? optional_value);
  // // Returns a null optional uint16.
  GetNullUint16() => (uint16? optional_value);
  // // Returns a null optional int16.
  GetNullInt16() => (int16? optional_value);
  // // Returns a null optional uint32.
  GetNullUint32() => (uint32? optional_value);
  // // Returns a null optional int32.
  GetNullInt32() => (int32? optional_value);
  // Returns a null optional uint64.
  GetNullUint64() => (uint64? optional_value);
  // Returns a null optional int64.
  GetNullInt64() => (int64? optional_value);
  // Returns a null optional float.
  GetNullFloat() => (float? optional_value);
  // Returns a null optional double.
  GetNullDouble() => (double? optional_value);
  // Returns a null optional enum.
  GetNullEnum() => (RegularEnum? optional_value);

  // Returns a list of optional bools.
  GetNullBools() => (array<bool?> optional_values);
  // Returns a list of optional int16s.
  GetNullInt16s() => (array<int16?> optional_values);
  // Returns a list of optional uint32s.
  GetNullUint32s() => (array<uint32?> optional_values);
  // Returns a list of optional doubles.
  GetNullDoubles() => (array<double?> optional_values);
  // Returns a list of optional enums.
  GetNullEnums() => (array<RegularEnum?> optional_values);

  // Returns a simple map with a single {0, null} entry.
  GetNullBoolMap() => (map<int16, bool?> optional_values);
  // Returns a simple map with a single {0, null} entry.
  GetNullInt32Map() => (map<int16, int32?> optional_values);
  // Returns a simple map with a single {0, null} entry.
  GetNullEnumMap() => (map<int16, RegularEnum?> optional_values);

  // The following methods help test that JS can correctly handle optional
  // numerics in response params.
  //
  // Returns |value| in an optional bool.
  GetOptionalBool(bool value) => (bool? optional_value);
  // Returns |value| in an optional unit8.
  GetOptionalUint8(uint8 value) => (uint8? optional_value);
  // Returns |value| in an optional int8.
  GetOptionalInt8(int8 value) => (int8? optional_value);
  // Returns |value| in an optional uint16.
  GetOptionalUint16(uint16 value) => (uint16? optional_value);
  // Returns |value| in an optional int16.
  GetOptionalInt16(int16 value) => (int16? optional_value);
  // Returns |value| in an optional uint32.
  GetOptionalUint32(uint32 value) => (uint32? optional_value);
  // Returns |value| in an optional int32.
  GetOptionalInt32(int32 value) => (int32? optional_value);
  // Returns |value| in an optional uint64.
  GetOptionalUint64(uint64 value) => (uint64? optional_value);
  // Returns |value| in an optional int64.
  GetOptionalInt64(int64 value) => (int64? optional_value);
  // Returns |value| in an optional float.
  GetOptionalFloat(float value) => (float? optional_value);
  // Returns |value| in an optional double.
  GetOptionalDouble(double value) => (double? optional_value);
  // Returns |value| in an optional enum.
  GetOptionalEnum(RegularEnum value) => (RegularEnum? optional_value);

  // Returns |value| sandwiched between two null values. E.g.:
  // [null, |value|, null].
  GetOptionalBools(bool value) => (array<bool?> optional_values);
  // Returns |value| sandwiched between two null values. E.g.:
  // [null, |value|, null].
  GetOptionalInt16s(int16 value) => (array<int16?> optional_values);
  // Returns |value| sandwiched between two null values. E.g.:
  // [null, |value|, null].
  GetOptionalUint32s(uint32 value) => (array<uint32?> optional_values);
  // Returns |value| sandwiched between two null values. E.g.:
  // [null, |value|, null].
  GetOptionalDoubles(double value) => (array<double?> optional_values);
  // Returns |value| sandwiched between two null values. E.g.:
  // [null, |value|, null].
  GetOptionalEnums(RegularEnum value) => (array<RegularEnum?> optional_values);

  // Returns {|key|, |value|} sandwiched between two null values. E.g.:
  // {
  //   [key - 1]: null,
  //   [key]: value,
  //   [key +1]: value,
  // }
  GetOptionalBoolMap(int16 key, bool value)
        => (map<int16, bool?> optional_values);
  // Same as above.
  GetOptionalFloatMap(int16 key, float value)
        => (map<int16, float?> optional_values);
  // Same as above.
  GetOptionalEnumMap(int16 key, RegularEnum value)
        => (map<int16, RegularEnum?> optional_values);

  // Runs a callback with null. Helps test that JS can correctly handle null
  // structs with optional numerics.
  GetNullStructWithOptionalNumerics() => (OptionalNumericsStruct? s);

  // Returns a struct with null optional numerics. Helps test that JS can
  // correctly handle structs with null optional numerics.
  GetStructWithNullOptionalNumerics() => (OptionalNumericsStruct s);

  // Returns a struct with values as optional numerics. Helps test that JS can
  // correctly handle struct with optional numerics.
  GetStructWithOptionalNumerics(
    bool bool_value,
    uint8 uint8_value,
    int8 int8_value,
    uint16 uint16_value,
    int16 int16_value,
    uint32 uint32_value,
    int32 int32_value,
    uint64 uint64_value,
    int64 int64_value,
    float float_value,
    double double_value,
    RegularEnum enum_value) => (OptionalNumericsStruct s);
};

struct VersionedStructV0 {
};

struct VersionedStructV2 {
  [MinVersion=2] bool? bool_value;
  [MinVersion=2] uint8? uint8_value;
  [MinVersion=2] int8? int8_value;
  [MinVersion=2] uint16? uint16_value;
  [MinVersion=2] int16? int16_value;
  [MinVersion=2] uint32? uint32_value;
  [MinVersion=2] int32? int32_value;
  [MinVersion=2] uint64? uint64_value;
  [MinVersion=2] int64? int64_value;
  [MinVersion=2] float? float_value;
  [MinVersion=2] double? double_value;
  [MinVersion=2] RegularEnum? enum_value;
};

// Implemented in JS to test that optional numerics in versioned interfaces
// work.
interface InterfaceV0 {
  // V2 of this method has optional numeric params and response params.
  MethodWithVersionedParams@1() => ();

  // V2 of this method uses VersionedStructV2.
  MethodWithVersionedStruct@2(VersionedStructV0 s) => (VersionedStructV0 s);
};

// Implemented in JS to test that optional numerics in versioned interfaces
// work.
interface InterfaceV2 {
  // Returns the optional numerics it was sent but with some transformations
  // i.e. !bool_value, integers get multiplied by 2, float and double get
  // multiplied by 3.
  MethodWithVersionedParams@1(
    [MinVersion=2] bool? bool_value,
    [MinVersion=2] uint8? uint8_value,
    [MinVersion=2] int8? int8_value,
    [MinVersion=2] uint16? uint16_value,
    [MinVersion=2] int16? int16_value,
    [MinVersion=2] uint32? uint32_value,
    [MinVersion=2] int32? int32_value,
    [MinVersion=2] uint64? uint64_value,
    [MinVersion=2] int64? int64_value,
    [MinVersion=2] float? float_value,
    [MinVersion=2] double? double_value,
    [MinVersion=2] RegularEnum? enum_value
  ) => (
    [MinVersion=2] bool? bool_value,
    [MinVersion=2] uint8? uint8_value,
    [MinVersion=2] int8? int8_value,
    [MinVersion=2] uint16? uint16_value,
    [MinVersion=2] int16? int16_value,
    [MinVersion=2] uint32? uint32_value,
    [MinVersion=2] int32? int32_value,
    [MinVersion=2] uint64? uint64_value,
    [MinVersion=2] int64? int64_value,
    [MinVersion=2] float? float_value,
    [MinVersion=2] double? double_value,
    [MinVersion=2] RegularEnum? enum_value
  );

  // Returns the optional numerics in `s` it was sent but with some
  // transformations i.e. !bool_value, integers get multiplied by 2, float and
  // double get multiplied by 3.
  MethodWithVersionedStruct@2(VersionedStructV2 s) => (VersionedStructV2 s);
};