<?hh
/**
 * Autogenerated by Thrift
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */

/**
 * Original thrift struct:-
 * AnnotationStruct
 */
class AnnotationStruct implements \IThriftSyncStruct, \IThriftStructMetadata, \IThriftShapishSyncStruct {
  use \ThriftSerializationTrait;

  const \ThriftStructTypes::TSpec SPEC = dict[
  ];
  const dict<string, int> FIELDMAP = dict[
  ];

  const type TConstructorShape = shape(
  );

  const type TShape = shape(
  );
  const int STRUCTURAL_ID = 957977401221134810;

  public function __construct()[] {
  }

  public static function withDefaultValues()[]: this {
    return new static();
  }

  public static function fromShape(self::TConstructorShape $shape)[]: this {
    return new static(
    );
  }

  public function getName()[]: string {
    return 'AnnotationStruct';
  }

  public function clearTerseFields()[write_props]: void {
  }

  public static function getStructMetadata()[]: \tmeta_ThriftStruct {
    return tmeta_ThriftStruct::fromShape(
      shape(
        "name" => "module.AnnotationStruct",
        "is_union" => false,
      )
    );
  }

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Transitive' => \facebook\thrift\annotation\Transitive::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\hack\FieldWrapper' => \facebook\thrift\annotation\hack\FieldWrapper::fromShape(
          shape(
            "name" => "\\MyFieldWrapper",
          )
        ),
      ],
      'fields' => dict[
      ],
    );
  }

  public static function __stringifyMapKeys<T>(dict<arraykey, T> $m)[]: dict<string, T> {
    return Dict\map_keys($m, $key ==> (string)$key);
  }

  public static function __fromShape(self::TShape $shape)[]: this {
    return new static(
    );
  }

  public function __toShape()[]: self::TShape {
    return shape(
    );
  }
  public function getInstanceKey()[write_props]: string {
    return \TCompactSerializer::serialize($this);
  }

  public function readFromJson(string $jsonText): void {
    $parsed = json_decode($jsonText, true);

    if ($parsed === null || !($parsed is KeyedContainer<_, _>)) {
      throw new \TProtocolException("Cannot parse the given json string.");
    }

  }

}

/**
 * Original thrift struct:-
 * MyStruct
 */
class MyStruct implements \IThriftSyncStruct, \IThriftStructMetadata, \IThriftShapishAsyncStruct {
  use \ThriftSerializationTrait;

  const \ThriftStructTypes::TSpec SPEC = dict[
    1 => shape(
      'var' => 'nested_struct',
      'type' => \TType::STRUCT,
      'class' => MyNestedStruct::class,
    ),
  ];
  const dict<string, int> FIELDMAP = dict[
    'nested_struct' => 1,
  ];

  const type TConstructorShape = shape(
    ?'nested_struct' => ?MyNestedStruct,
  );

  const type TShape = shape(
    ?'nested_struct' => ?MyNestedStruct::TShape,
  );
  const int STRUCTURAL_ID = 6466034702854646588;
  /**
   * Original thrift field:-
   * 1: module.MyNestedStruct nested_struct
   */
  public ?MyNestedStruct $nested_struct;

  public function __construct(?MyNestedStruct $nested_struct = null)[] {
    $this->nested_struct = $nested_struct;
  }

  public static function withDefaultValues()[]: this {
    return new static();
  }

  public static function fromShape(self::TConstructorShape $shape)[]: this {
    return new static(
      Shapes::idx($shape, 'nested_struct'),
    );
  }

  public function getName()[]: string {
    return 'MyStruct';
  }

  public function clearTerseFields()[write_props]: void {
  }

  public static function getStructMetadata()[]: \tmeta_ThriftStruct {
    return tmeta_ThriftStruct::fromShape(
      shape(
        "name" => "module.MyStruct",
        "fields" => vec[
          tmeta_ThriftField::fromShape(
            shape(
              "id" => 1,
              "type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_typedef" => tmeta_ThriftTypedefType::fromShape(
                    shape(
                      "name" => "module.MyNestedStruct",
                      "underlyingType" => tmeta_ThriftType::fromShape(
                        shape(
                          "t_struct" => tmeta_ThriftStructType::fromShape(
                            shape(
                              "name" => "module.MyNestedStruct",
                            )
                          ),
                        )
                      ),
                    )
                  ),
                )
              ),
              "name" => "nested_struct",
            )
          ),
        ],
        "is_union" => false,
      )
    );
  }

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[],
      'fields' => dict[
      ],
    );
  }

  public static function __stringifyMapKeys<T>(dict<arraykey, T> $m)[]: dict<string, T> {
    return Dict\map_keys($m, $key ==> (string)$key);
  }

  public static async function __genFromShape(self::TShape $shape): Awaitable<this> {
    $obj = new static();
    $nested_struct = Shapes::idx($shape, 'nested_struct');
    if ($nested_struct !== null) {
      $obj->nested_struct = await MyNestedStruct::__genFromShape($nested_struct);
    }
    return $obj;
  }

  public async function __genToShape(): Awaitable<self::TShape> {
    return shape(
      'nested_struct' => await ($this->nested_struct === null
        ? null
        : (
        $this->nested_struct->__genToShape()
        )
      ),
    );
  }
  public function getInstanceKey()[write_props]: string {
    return \TCompactSerializer::serialize($this);
  }

  public function readFromJson(string $jsonText): void {
    $parsed = json_decode($jsonText, true);

    if ($parsed === null || !($parsed is KeyedContainer<_, _>)) {
      throw new \TProtocolException("Cannot parse the given json string.");
    }

    if (idx($parsed, 'nested_struct') !== null) {
      $_tmp0 = \json_encode(HH\FIXME\UNSAFE_CAST<mixed, MyNestedStruct>($parsed['nested_struct']));
      $_tmp1 = MyNestedStruct::withDefaultValues();
      $_tmp1->readFromJson($_tmp0);
      $this->nested_struct = $_tmp1;
    }
  }

}

/**
 * Original thrift struct:-
 * MyNestedStruct
 */
class MyNestedStruct implements \IThriftAsyncStruct, \IThriftStructMetadata, \IThriftShapishAsyncStruct {
  use \ThriftSerializationTrait;

  const \ThriftStructTypes::TSpec SPEC = dict[
    1 => shape(
      'var' => 'wrapped_field',
      'is_wrapped' => true,
      'type' => \TType::I64,
    ),
    2 => shape(
      'var' => 'annotated_field',
      'is_wrapped' => true,
      'type' => \TType::I64,
    ),
    3 => shape(
      'var' => 'adapted_type',
      'adapter' => \MyAdapter::class,
      'type' => \TType::I64,
    ),
  ];
  const dict<string, int> FIELDMAP = dict[
    'wrapped_field' => 1,
    'annotated_field' => 2,
    'adapted_type' => 3,
  ];

  const type TConstructorShape = shape(
    ?'wrapped_field' => ?int,
    ?'annotated_field' => ?int,
    ?'adapted_type' => ?\MyAdapter::THackType,
  );

  const type TShape = shape(
    'wrapped_field' => int,
    'annotated_field' => int,
    'adapted_type' => \MyAdapter::THackType,
  );
  const int STRUCTURAL_ID = 3672151039112827748;
  /**
   * Original thrift field:-
   * 1: i64 wrapped_field
   */
  private ?\MyFieldWrapper<int, MyNestedStruct> $wrapped_field;

  public function get_wrapped_field()[]: \MyFieldWrapper<int, MyNestedStruct> {
    return $this->wrapped_field as nonnull;
  }

  /**
   * Original thrift field:-
   * 2: i64 annotated_field
   */
  private ?\MyFieldWrapper<int, MyNestedStruct> $annotated_field;

  public function get_annotated_field()[]: \MyFieldWrapper<int, MyNestedStruct> {
    return $this->annotated_field as nonnull;
  }

  /**
   * Original thrift field:-
   * 3: i64 adapted_type
   */
  public \MyAdapter::THackType $adapted_type;

  public function __construct()[] {
    $this->adapted_type = \MyAdapter::fromThrift(0);
    $this->wrapped_field = \MyFieldWrapper::fromThrift_DO_NOT_USE_THRIFT_INTERNAL<int, MyNestedStruct>(0, 1, $this);
    $this->annotated_field = \MyFieldWrapper::fromThrift_DO_NOT_USE_THRIFT_INTERNAL<int, MyNestedStruct>(0, 2, $this);
  }

  public static function withDefaultValues()[]: this {
    return new static();
  }

  public static async function genFromShape(self::TConstructorShape $shape)[zoned_shallow]: Awaitable<this> {
    $obj = new static();
    $wrapped_field = Shapes::idx($shape, 'wrapped_field');
    if ($wrapped_field !== null) {
      await $obj->get_wrapped_field()->genWrap($wrapped_field);
    }
    $annotated_field = Shapes::idx($shape, 'annotated_field');
    if ($annotated_field !== null) {
      await $obj->get_annotated_field()->genWrap($annotated_field);
    }
    $adapted_type = Shapes::idx($shape, 'adapted_type');
    if ($adapted_type !== null) {
      $obj->adapted_type = $adapted_type;
    }
    return $obj;
  }

  public function getName()[]: string {
    return 'MyNestedStruct';
  }

  public function clearTerseFields()[write_props]: void {
  }

  public static function getStructMetadata()[]: \tmeta_ThriftStruct {
    return tmeta_ThriftStruct::fromShape(
      shape(
        "name" => "module.MyNestedStruct",
        "fields" => vec[
          tmeta_ThriftField::fromShape(
            shape(
              "id" => 1,
              "type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_primitive" => tmeta_ThriftPrimitiveType::THRIFT_I64_TYPE,
                )
              ),
              "name" => "wrapped_field",
            )
          ),
          tmeta_ThriftField::fromShape(
            shape(
              "id" => 2,
              "type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_primitive" => tmeta_ThriftPrimitiveType::THRIFT_I64_TYPE,
                )
              ),
              "name" => "annotated_field",
            )
          ),
          tmeta_ThriftField::fromShape(
            shape(
              "id" => 3,
              "type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_primitive" => tmeta_ThriftPrimitiveType::THRIFT_I64_TYPE,
                )
              ),
              "name" => "adapted_type",
            )
          ),
        ],
        "is_union" => false,
      )
    );
  }

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[],
      'fields' => dict[
        'wrapped_field' => shape(
          'field' => dict[
            '\facebook\thrift\annotation\hack\FieldWrapper' => \facebook\thrift\annotation\hack\FieldWrapper::fromShape(
              shape(
                "name" => "\\MyFieldWrapper",
              )
            ),
          ],
          'type' => dict[],
        ),
        'annotated_field' => shape(
          'field' => dict[
            'AnnotationStruct' => AnnotationStruct::fromShape(
              shape(
              )
            ),
          ],
          'type' => dict[],
        ),
        'adapted_type' => shape(
          'field' => dict[
            '\facebook\thrift\annotation\hack\Adapter' => \facebook\thrift\annotation\hack\Adapter::fromShape(
              shape(
                "name" => "\\MyAdapter",
              )
            ),
          ],
          'type' => dict[],
        ),
      ],
    );
  }

  public static function __stringifyMapKeys<T>(dict<arraykey, T> $m)[]: dict<string, T> {
    return Dict\map_keys($m, $key ==> (string)$key);
  }

  public static async function __genFromShape(self::TShape $shape): Awaitable<this> {
    $obj = new static();
    await $obj->get_wrapped_field()->genWrap($shape['wrapped_field']);
    await $obj->get_annotated_field()->genWrap($shape['annotated_field']);
    $obj->adapted_type = $shape['adapted_type'];
    return $obj;
  }

  public async function __genToShape(): Awaitable<self::TShape> {
    $wrapped_field = await ($this->wrapped_field as nonnull)->genUnwrap();
    $annotated_field = await ($this->annotated_field as nonnull)->genUnwrap();
    return shape(
      'wrapped_field' => $wrapped_field,
      'annotated_field' => $annotated_field,
      'adapted_type' => $this->adapted_type,
    );
  }
  public function getInstanceKey()[write_props]: string {
    return \TCompactSerializer::serialize($this);
  }

  public function readFromJson(string $jsonText): void {
    $parsed = json_decode($jsonText, true);

    if ($parsed === null || !($parsed is KeyedContainer<_, _>)) {
      throw new \TProtocolException("Cannot parse the given json string.");
    }

    if (idx($parsed, 'wrapped_field') !== null) {
      $this->wrapped_field = HH\FIXME\UNSAFE_CAST<mixed, int>($parsed['wrapped_field']);
    }
    if (idx($parsed, 'annotated_field') !== null) {
      $this->annotated_field = HH\FIXME\UNSAFE_CAST<mixed, int>($parsed['annotated_field']);
    }
    if (idx($parsed, 'adapted_type') !== null) {
      $this->adapted_type = HH\FIXME\UNSAFE_CAST<mixed, int>($parsed['adapted_type']);
    }
  }

  private static function __hackAdapterTypeChecks()[]: void {
    \ThriftUtil::requireSameType<\MyAdapter::TThriftType, int>();
  }

}

/**
 * Original thrift struct:-
 * MyComplexStruct
 */
class MyComplexStruct implements \IThriftAsyncStruct, \IThriftStructMetadata, \IThriftShapishAsyncStruct {
  use \ThriftSerializationTrait;

  const \ThriftStructTypes::TSpec SPEC = dict[
    1 => shape(
      'var' => 'map_of_string_to_MyStruct',
      'type' => \TType::MAP,
      'ktype' => \TType::STRING,
      'vtype' => \TType::STRUCT,
      'key' => shape(
        'type' => \TType::STRING,
      ),
      'val' => shape(
        'type' => \TType::STRUCT,
        'class' => MyStruct::class,
      ),
      'format' => 'collection',
    ),
    2 => shape(
      'var' => 'map_of_string_to_list_of_MyStruct',
      'is_wrapped' => true,
      'type' => \TType::MAP,
      'ktype' => \TType::STRING,
      'vtype' => \TType::LST,
      'key' => shape(
        'type' => \TType::STRING,
      ),
      'val' => shape(
        'type' => \TType::LST,
        'etype' => \TType::STRUCT,
        'elem' => shape(
          'type' => \TType::STRUCT,
          'class' => MyStruct::class,
        ),
        'format' => 'collection',
      ),
      'format' => 'collection',
    ),
    3 => shape(
      'var' => 'map_of_string_to_map_of_string_to_i32',
      'type' => \TType::MAP,
      'ktype' => \TType::STRING,
      'vtype' => \TType::MAP,
      'key' => shape(
        'type' => \TType::STRING,
      ),
      'val' => shape(
        'type' => \TType::MAP,
        'ktype' => \TType::STRING,
        'vtype' => \TType::I32,
        'key' => shape(
          'type' => \TType::STRING,
        ),
        'val' => shape(
          'type' => \TType::I32,
        ),
        'format' => 'collection',
      ),
      'format' => 'collection',
    ),
    4 => shape(
      'var' => 'map_of_string_to_map_of_string_to_MyStruct',
      'type' => \TType::MAP,
      'ktype' => \TType::STRING,
      'vtype' => \TType::MAP,
      'key' => shape(
        'type' => \TType::STRING,
      ),
      'val' => shape(
        'type' => \TType::MAP,
        'ktype' => \TType::STRING,
        'vtype' => \TType::STRUCT,
        'key' => shape(
          'type' => \TType::STRING,
        ),
        'val' => shape(
          'type' => \TType::STRUCT,
          'class' => MyStruct::class,
        ),
        'format' => 'collection',
      ),
      'format' => 'collection',
    ),
    5 => shape(
      'var' => 'list_of_map_of_string_to_list_of_MyStruct',
      'type' => \TType::LST,
      'etype' => \TType::MAP,
      'elem' => shape(
        'type' => \TType::MAP,
        'ktype' => \TType::STRING,
        'vtype' => \TType::LST,
        'key' => shape(
          'type' => \TType::STRING,
        ),
        'val' => shape(
          'type' => \TType::LST,
          'etype' => \TType::STRUCT,
          'elem' => shape(
            'type' => \TType::STRUCT,
            'class' => MyStruct::class,
          ),
          'format' => 'collection',
        ),
        'format' => 'collection',
      ),
      'format' => 'collection',
    ),
    6 => shape(
      'var' => 'list_of_map_of_string_to_MyStruct',
      'type' => \TType::LST,
      'etype' => \TType::MAP,
      'elem' => shape(
        'type' => \TType::MAP,
        'ktype' => \TType::STRING,
        'vtype' => \TType::STRUCT,
        'key' => shape(
          'type' => \TType::STRING,
        ),
        'val' => shape(
          'type' => \TType::STRUCT,
          'class' => MyStruct::class,
        ),
        'format' => 'collection',
      ),
      'format' => 'collection',
    ),
  ];
  const dict<string, int> FIELDMAP = dict[
    'map_of_string_to_MyStruct' => 1,
    'map_of_string_to_list_of_MyStruct' => 2,
    'map_of_string_to_map_of_string_to_i32' => 3,
    'map_of_string_to_map_of_string_to_MyStruct' => 4,
    'list_of_map_of_string_to_list_of_MyStruct' => 5,
    'list_of_map_of_string_to_MyStruct' => 6,
  ];

  const type TConstructorShape = shape(
    ?'map_of_string_to_MyStruct' => ?Map<string, MyStruct>,
    ?'map_of_string_to_list_of_MyStruct' => ?Map<string, Vector<MyStruct>>,
    ?'map_of_string_to_map_of_string_to_i32' => ?Map<string, Map<string, int>>,
    ?'map_of_string_to_map_of_string_to_MyStruct' => ?Map<string, Map<string, MyStruct>>,
    ?'list_of_map_of_string_to_list_of_MyStruct' => ?Vector<Map<string, Vector<MyStruct>>>,
    ?'list_of_map_of_string_to_MyStruct' => ?Vector<Map<string, MyStruct>>,
  );

  const type TShape = shape(
    'map_of_string_to_MyStruct' => dict<arraykey, MyStruct::TShape>,
    'map_of_string_to_list_of_MyStruct' => dict<arraykey, vec<MyStruct::TShape>>,
    'map_of_string_to_map_of_string_to_i32' => dict<arraykey, dict<arraykey, int>>,
    'map_of_string_to_map_of_string_to_MyStruct' => dict<arraykey, dict<arraykey, MyStruct::TShape>>,
    'list_of_map_of_string_to_list_of_MyStruct' => vec<dict<arraykey, vec<MyStruct::TShape>>>,
    'list_of_map_of_string_to_MyStruct' => vec<dict<arraykey, MyStruct::TShape>>,
  );
  const int STRUCTURAL_ID = 8703607584527805207;
  /**
   * Original thrift field:-
   * 1: map<string, module.MyStruct> map_of_string_to_MyStruct
   */
  public Map<string, MyStruct> $map_of_string_to_MyStruct;
  /**
   * Original thrift field:-
   * 2: map<string, list<module.MyStruct>> map_of_string_to_list_of_MyStruct
   */
  private ?\MyFieldWrapper<Map<string, Vector<MyStruct>>, MyComplexStruct> $map_of_string_to_list_of_MyStruct;

  public function get_map_of_string_to_list_of_MyStruct()[]: \MyFieldWrapper<Map<string, Vector<MyStruct>>, MyComplexStruct> {
    return $this->map_of_string_to_list_of_MyStruct as nonnull;
  }

  /**
   * Original thrift field:-
   * 3: map<string, map<string, i32>> map_of_string_to_map_of_string_to_i32
   */
  public Map<string, Map<string, int>> $map_of_string_to_map_of_string_to_i32;
  /**
   * Original thrift field:-
   * 4: map<string, map<string, module.MyStruct>> map_of_string_to_map_of_string_to_MyStruct
   */
  public Map<string, Map<string, MyStruct>> $map_of_string_to_map_of_string_to_MyStruct;
  /**
   * Original thrift field:-
   * 5: list<map<string, list<module.MyStruct>>> list_of_map_of_string_to_list_of_MyStruct
   */
  public Vector<Map<string, Vector<MyStruct>>> $list_of_map_of_string_to_list_of_MyStruct;
  /**
   * Original thrift field:-
   * 6: list<map<string, module.MyStruct>> list_of_map_of_string_to_MyStruct
   */
  public Vector<Map<string, MyStruct>> $list_of_map_of_string_to_MyStruct;

  public function __construct()[] {
    $this->map_of_string_to_MyStruct = Map {};
    $this->map_of_string_to_map_of_string_to_i32 = Map {};
    $this->map_of_string_to_map_of_string_to_MyStruct = Map {};
    $this->list_of_map_of_string_to_list_of_MyStruct = Vector {};
    $this->list_of_map_of_string_to_MyStruct = Vector {};
    $this->map_of_string_to_list_of_MyStruct = \MyFieldWrapper::fromThrift_DO_NOT_USE_THRIFT_INTERNAL<Map<string, Vector<MyStruct>>, MyComplexStruct>(Map {}, 2, $this);
  }

  public static function withDefaultValues()[]: this {
    return new static();
  }

  public static async function genFromShape(self::TConstructorShape $shape)[zoned_shallow]: Awaitable<this> {
    $obj = new static();
    $map_of_string_to_MyStruct = Shapes::idx($shape, 'map_of_string_to_MyStruct');
    if ($map_of_string_to_MyStruct !== null) {
      $obj->map_of_string_to_MyStruct = $map_of_string_to_MyStruct;
    }
    $map_of_string_to_list_of_MyStruct = Shapes::idx($shape, 'map_of_string_to_list_of_MyStruct');
    if ($map_of_string_to_list_of_MyStruct !== null) {
      await $obj->get_map_of_string_to_list_of_MyStruct()->genWrap($map_of_string_to_list_of_MyStruct);
    }
    $map_of_string_to_map_of_string_to_i32 = Shapes::idx($shape, 'map_of_string_to_map_of_string_to_i32');
    if ($map_of_string_to_map_of_string_to_i32 !== null) {
      $obj->map_of_string_to_map_of_string_to_i32 = $map_of_string_to_map_of_string_to_i32;
    }
    $map_of_string_to_map_of_string_to_MyStruct = Shapes::idx($shape, 'map_of_string_to_map_of_string_to_MyStruct');
    if ($map_of_string_to_map_of_string_to_MyStruct !== null) {
      $obj->map_of_string_to_map_of_string_to_MyStruct = $map_of_string_to_map_of_string_to_MyStruct;
    }
    $list_of_map_of_string_to_list_of_MyStruct = Shapes::idx($shape, 'list_of_map_of_string_to_list_of_MyStruct');
    if ($list_of_map_of_string_to_list_of_MyStruct !== null) {
      $obj->list_of_map_of_string_to_list_of_MyStruct = $list_of_map_of_string_to_list_of_MyStruct;
    }
    $list_of_map_of_string_to_MyStruct = Shapes::idx($shape, 'list_of_map_of_string_to_MyStruct');
    if ($list_of_map_of_string_to_MyStruct !== null) {
      $obj->list_of_map_of_string_to_MyStruct = $list_of_map_of_string_to_MyStruct;
    }
    return $obj;
  }

  public function getName()[]: string {
    return 'MyComplexStruct';
  }

  public function clearTerseFields()[write_props]: void {
  }

  public static function getStructMetadata()[]: \tmeta_ThriftStruct {
    return tmeta_ThriftStruct::fromShape(
      shape(
        "name" => "module.MyComplexStruct",
        "fields" => vec[
          tmeta_ThriftField::fromShape(
            shape(
              "id" => 1,
              "type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_map" => tmeta_ThriftMapType::fromShape(
                    shape(
                      "keyType" => tmeta_ThriftType::fromShape(
                        shape(
                          "t_primitive" => tmeta_ThriftPrimitiveType::THRIFT_STRING_TYPE,
                        )
                      ),
                      "valueType" => tmeta_ThriftType::fromShape(
                        shape(
                          "t_struct" => tmeta_ThriftStructType::fromShape(
                            shape(
                              "name" => "module.MyStruct",
                            )
                          ),
                        )
                      ),
                    )
                  ),
                )
              ),
              "name" => "map_of_string_to_MyStruct",
            )
          ),
          tmeta_ThriftField::fromShape(
            shape(
              "id" => 2,
              "type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_map" => tmeta_ThriftMapType::fromShape(
                    shape(
                      "keyType" => tmeta_ThriftType::fromShape(
                        shape(
                          "t_primitive" => tmeta_ThriftPrimitiveType::THRIFT_STRING_TYPE,
                        )
                      ),
                      "valueType" => tmeta_ThriftType::fromShape(
                        shape(
                          "t_list" => tmeta_ThriftListType::fromShape(
                            shape(
                              "valueType" => tmeta_ThriftType::fromShape(
                                shape(
                                  "t_struct" => tmeta_ThriftStructType::fromShape(
                                    shape(
                                      "name" => "module.MyStruct",
                                    )
                                  ),
                                )
                              ),
                            )
                          ),
                        )
                      ),
                    )
                  ),
                )
              ),
              "name" => "map_of_string_to_list_of_MyStruct",
            )
          ),
          tmeta_ThriftField::fromShape(
            shape(
              "id" => 3,
              "type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_map" => tmeta_ThriftMapType::fromShape(
                    shape(
                      "keyType" => tmeta_ThriftType::fromShape(
                        shape(
                          "t_primitive" => tmeta_ThriftPrimitiveType::THRIFT_STRING_TYPE,
                        )
                      ),
                      "valueType" => tmeta_ThriftType::fromShape(
                        shape(
                          "t_map" => tmeta_ThriftMapType::fromShape(
                            shape(
                              "keyType" => tmeta_ThriftType::fromShape(
                                shape(
                                  "t_primitive" => tmeta_ThriftPrimitiveType::THRIFT_STRING_TYPE,
                                )
                              ),
                              "valueType" => tmeta_ThriftType::fromShape(
                                shape(
                                  "t_primitive" => tmeta_ThriftPrimitiveType::THRIFT_I32_TYPE,
                                )
                              ),
                            )
                          ),
                        )
                      ),
                    )
                  ),
                )
              ),
              "name" => "map_of_string_to_map_of_string_to_i32",
            )
          ),
          tmeta_ThriftField::fromShape(
            shape(
              "id" => 4,
              "type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_map" => tmeta_ThriftMapType::fromShape(
                    shape(
                      "keyType" => tmeta_ThriftType::fromShape(
                        shape(
                          "t_primitive" => tmeta_ThriftPrimitiveType::THRIFT_STRING_TYPE,
                        )
                      ),
                      "valueType" => tmeta_ThriftType::fromShape(
                        shape(
                          "t_map" => tmeta_ThriftMapType::fromShape(
                            shape(
                              "keyType" => tmeta_ThriftType::fromShape(
                                shape(
                                  "t_primitive" => tmeta_ThriftPrimitiveType::THRIFT_STRING_TYPE,
                                )
                              ),
                              "valueType" => tmeta_ThriftType::fromShape(
                                shape(
                                  "t_struct" => tmeta_ThriftStructType::fromShape(
                                    shape(
                                      "name" => "module.MyStruct",
                                    )
                                  ),
                                )
                              ),
                            )
                          ),
                        )
                      ),
                    )
                  ),
                )
              ),
              "name" => "map_of_string_to_map_of_string_to_MyStruct",
            )
          ),
          tmeta_ThriftField::fromShape(
            shape(
              "id" => 5,
              "type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_list" => tmeta_ThriftListType::fromShape(
                    shape(
                      "valueType" => tmeta_ThriftType::fromShape(
                        shape(
                          "t_map" => tmeta_ThriftMapType::fromShape(
                            shape(
                              "keyType" => tmeta_ThriftType::fromShape(
                                shape(
                                  "t_primitive" => tmeta_ThriftPrimitiveType::THRIFT_STRING_TYPE,
                                )
                              ),
                              "valueType" => tmeta_ThriftType::fromShape(
                                shape(
                                  "t_list" => tmeta_ThriftListType::fromShape(
                                    shape(
                                      "valueType" => tmeta_ThriftType::fromShape(
                                        shape(
                                          "t_struct" => tmeta_ThriftStructType::fromShape(
                                            shape(
                                              "name" => "module.MyStruct",
                                            )
                                          ),
                                        )
                                      ),
                                    )
                                  ),
                                )
                              ),
                            )
                          ),
                        )
                      ),
                    )
                  ),
                )
              ),
              "name" => "list_of_map_of_string_to_list_of_MyStruct",
            )
          ),
          tmeta_ThriftField::fromShape(
            shape(
              "id" => 6,
              "type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_list" => tmeta_ThriftListType::fromShape(
                    shape(
                      "valueType" => tmeta_ThriftType::fromShape(
                        shape(
                          "t_map" => tmeta_ThriftMapType::fromShape(
                            shape(
                              "keyType" => tmeta_ThriftType::fromShape(
                                shape(
                                  "t_primitive" => tmeta_ThriftPrimitiveType::THRIFT_STRING_TYPE,
                                )
                              ),
                              "valueType" => tmeta_ThriftType::fromShape(
                                shape(
                                  "t_struct" => tmeta_ThriftStructType::fromShape(
                                    shape(
                                      "name" => "module.MyStruct",
                                    )
                                  ),
                                )
                              ),
                            )
                          ),
                        )
                      ),
                    )
                  ),
                )
              ),
              "name" => "list_of_map_of_string_to_MyStruct",
            )
          ),
        ],
        "is_union" => false,
      )
    );
  }

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[],
      'fields' => dict[
        'map_of_string_to_list_of_MyStruct' => shape(
          'field' => dict[
            '\facebook\thrift\annotation\hack\FieldWrapper' => \facebook\thrift\annotation\hack\FieldWrapper::fromShape(
              shape(
                "name" => "\\MyFieldWrapper",
              )
            ),
          ],
          'type' => dict[],
        ),
      ],
    );
  }

  public static function __stringifyMapKeys<T>(dict<arraykey, T> $m)[]: dict<string, T> {
    return Dict\map_keys($m, $key ==> (string)$key);
  }

  public static async function __genFromShape(self::TShape $shape): Awaitable<this> {
    $obj = new static();
    $obj->map_of_string_to_MyStruct = self::__stringifyMapKeys(
      new Map(await Dict\map_async(
        $shape['map_of_string_to_MyStruct'],
        async $val0 ==>
          await MyStruct::__genFromShape($val0)
      ))
    );
    $map_of_string_to_list_of_MyStruct = self::__stringifyMapKeys(
      new Map(await Dict\map_async(
        $shape['map_of_string_to_list_of_MyStruct'],
        async $val1 ==>
          new Vector(await Vec\map_async(
            $val1,
            async $val2 ==>
              await MyStruct::__genFromShape($val2)
          ))
      ))
    );
    await $obj->get_map_of_string_to_list_of_MyStruct()->genWrap($map_of_string_to_list_of_MyStruct);
    $obj->map_of_string_to_map_of_string_to_i32 = self::__stringifyMapKeys(
      new Map(Dict\map(
        $shape['map_of_string_to_map_of_string_to_i32'],
        $val3 ==>
          self::__stringifyMapKeys(
            new Map($val3)
          )
      ))
    );
    $obj->map_of_string_to_map_of_string_to_MyStruct = self::__stringifyMapKeys(
      new Map(await Dict\map_async(
        $shape['map_of_string_to_map_of_string_to_MyStruct'],
        async $val4 ==>
          self::__stringifyMapKeys(
            new Map(await Dict\map_async(
              $val4,
              async $val5 ==>
                await MyStruct::__genFromShape($val5)
            ))
          )
      ))
    );
    $obj->list_of_map_of_string_to_list_of_MyStruct = new Vector(await Vec\map_async(
      $shape['list_of_map_of_string_to_list_of_MyStruct'],
      async $val6 ==>
        self::__stringifyMapKeys(
          new Map(await Dict\map_async(
            $val6,
            async $val7 ==>
              new Vector(await Vec\map_async(
                $val7,
                async $val8 ==>
                  await MyStruct::__genFromShape($val8)
              ))
          ))
        )
    ));
    $obj->list_of_map_of_string_to_MyStruct = new Vector(await Vec\map_async(
      $shape['list_of_map_of_string_to_MyStruct'],
      async $val9 ==>
        self::__stringifyMapKeys(
          new Map(await Dict\map_async(
            $val9,
            async $val10 ==>
              await MyStruct::__genFromShape($val10)
          ))
        )
    ));
    return $obj;
  }

  public async function __genToShape(): Awaitable<self::TShape> {
    $map_of_string_to_list_of_MyStruct = await ($this->map_of_string_to_list_of_MyStruct as nonnull)->genUnwrap();
    return shape(
      'map_of_string_to_MyStruct' => await Dict\map_async(
        $this->map_of_string_to_MyStruct,
        async $val0 ==>
          await $val0->__genToShape()
      ),
      'map_of_string_to_list_of_MyStruct' => await Dict\map_async(
        $map_of_string_to_list_of_MyStruct,
        async $val0 ==>
          await Vec\map_async(
            $val0,
            async $val1 ==>
              await $val1->__genToShape()
          )
      ),
      'map_of_string_to_map_of_string_to_i32' => Dict\map(
        $this->map_of_string_to_map_of_string_to_i32,
        $val0 ==>
          dict($val0)
      ),
      'map_of_string_to_map_of_string_to_MyStruct' => await Dict\map_async(
        $this->map_of_string_to_map_of_string_to_MyStruct,
        async $val0 ==>
          await Dict\map_async(
            $val0,
            async $val1 ==>
              await $val1->__genToShape()
          )
      ),
      'list_of_map_of_string_to_list_of_MyStruct' => await Vec\map_async(
        $this->list_of_map_of_string_to_list_of_MyStruct,
        async $val0 ==>
          await Dict\map_async(
            $val0,
            async $val1 ==>
              await Vec\map_async(
                $val1,
                async $val2 ==>
                  await $val2->__genToShape()
              )
          )
      ),
      'list_of_map_of_string_to_MyStruct' => await Vec\map_async(
        $this->list_of_map_of_string_to_MyStruct,
        async $val0 ==>
          await Dict\map_async(
            $val0,
            async $val1 ==>
              await $val1->__genToShape()
          )
      ),
    );
  }
  public function getInstanceKey()[write_props]: string {
    return \TCompactSerializer::serialize($this);
  }

  public function readFromJson(string $jsonText): void {
    $parsed = json_decode($jsonText, true);

    if ($parsed === null || !($parsed is KeyedContainer<_, _>)) {
      throw new \TProtocolException("Cannot parse the given json string.");
    }

    if (idx($parsed, 'map_of_string_to_MyStruct') !== null) {
      $_json3 = HH\FIXME\UNSAFE_CAST<mixed, Map<string, MyStruct>>($parsed['map_of_string_to_MyStruct']);
      $_container4 = Map {};
      foreach($_json3 as $_key1 => $_value2) {
        $_value5 = MyStruct::withDefaultValues();
        $_tmp6 = \json_encode($_value2);
        $_tmp7 = MyStruct::withDefaultValues();
        $_tmp7->readFromJson($_tmp6);
        $_value5 = $_tmp7;
        $_container4[$_key1] = $_value5;
      }
      $this->map_of_string_to_MyStruct = $_container4;
    }
    if (idx($parsed, 'map_of_string_to_list_of_MyStruct') !== null) {
      $_json11 = HH\FIXME\UNSAFE_CAST<mixed, Map<string, Vector<MyStruct>>>($parsed['map_of_string_to_list_of_MyStruct']);
      $_container12 = Map {};
      foreach($_json11 as $_key9 => $_value10) {
        $_value13 = Vector {};
        $_json17 = $_value10;
        $_container18 = Vector {};
        foreach($_json17 as $_key15 => $_value16) {
          $_elem19 = MyStruct::withDefaultValues();
          $_tmp20 = \json_encode($_value16);
          $_tmp21 = MyStruct::withDefaultValues();
          $_tmp21->readFromJson($_tmp20);
          $_elem19 = $_tmp21;
          $_container18 []= $_elem19;
        }
        $_value13 = $_container18;
        $_container12[$_key9] = $_value13;
      }
      $this->map_of_string_to_list_of_MyStruct = $_container12;
    }
    if (idx($parsed, 'map_of_string_to_map_of_string_to_i32') !== null) {
      $_json25 = HH\FIXME\UNSAFE_CAST<mixed, Map<string, Map<string, int>>>($parsed['map_of_string_to_map_of_string_to_i32']);
      $_container26 = Map {};
      foreach($_json25 as $_key23 => $_value24) {
        $_value27 = Map {};
        $_json31 = $_value24;
        $_container32 = Map {};
        foreach($_json31 as $_key29 => $_value30) {
          $_value33 = 0;
          $_tmp34 = (int)$_value30;
          if ($_tmp34 > 0x7fffffff) {
            throw new \TProtocolException("number exceeds limit in field");
          } else {
            $_value33 = (int)$_tmp34;
          }
          $_container32[$_key29] = $_value33;
        }
        $_value27 = $_container32;
        $_container26[$_key23] = $_value27;
      }
      $this->map_of_string_to_map_of_string_to_i32 = $_container26;
    }
    if (idx($parsed, 'map_of_string_to_map_of_string_to_MyStruct') !== null) {
      $_json38 = HH\FIXME\UNSAFE_CAST<mixed, Map<string, Map<string, MyStruct>>>($parsed['map_of_string_to_map_of_string_to_MyStruct']);
      $_container39 = Map {};
      foreach($_json38 as $_key36 => $_value37) {
        $_value40 = Map {};
        $_json44 = $_value37;
        $_container45 = Map {};
        foreach($_json44 as $_key42 => $_value43) {
          $_value46 = MyStruct::withDefaultValues();
          $_tmp47 = \json_encode($_value43);
          $_tmp48 = MyStruct::withDefaultValues();
          $_tmp48->readFromJson($_tmp47);
          $_value46 = $_tmp48;
          $_container45[$_key42] = $_value46;
        }
        $_value40 = $_container45;
        $_container39[$_key36] = $_value40;
      }
      $this->map_of_string_to_map_of_string_to_MyStruct = $_container39;
    }
    if (idx($parsed, 'list_of_map_of_string_to_list_of_MyStruct') !== null) {
      $_json52 = HH\FIXME\UNSAFE_CAST<mixed, Vector<Map<string, Vector<MyStruct>>>>($parsed['list_of_map_of_string_to_list_of_MyStruct']);
      $_container53 = Vector {};
      foreach($_json52 as $_key50 => $_value51) {
        $_elem54 = Map {};
        $_json58 = $_value51;
        $_container59 = Map {};
        foreach($_json58 as $_key56 => $_value57) {
          $_value60 = Vector {};
          $_json64 = $_value57;
          $_container65 = Vector {};
          foreach($_json64 as $_key62 => $_value63) {
            $_elem66 = MyStruct::withDefaultValues();
            $_tmp67 = \json_encode($_value63);
            $_tmp68 = MyStruct::withDefaultValues();
            $_tmp68->readFromJson($_tmp67);
            $_elem66 = $_tmp68;
            $_container65 []= $_elem66;
          }
          $_value60 = $_container65;
          $_container59[$_key56] = $_value60;
        }
        $_elem54 = $_container59;
        $_container53 []= $_elem54;
      }
      $this->list_of_map_of_string_to_list_of_MyStruct = $_container53;
    }
    if (idx($parsed, 'list_of_map_of_string_to_MyStruct') !== null) {
      $_json72 = HH\FIXME\UNSAFE_CAST<mixed, Vector<Map<string, MyStruct>>>($parsed['list_of_map_of_string_to_MyStruct']);
      $_container73 = Vector {};
      foreach($_json72 as $_key70 => $_value71) {
        $_elem74 = Map {};
        $_json78 = $_value71;
        $_container79 = Map {};
        foreach($_json78 as $_key76 => $_value77) {
          $_value80 = MyStruct::withDefaultValues();
          $_tmp81 = \json_encode($_value77);
          $_tmp82 = MyStruct::withDefaultValues();
          $_tmp82->readFromJson($_tmp81);
          $_value80 = $_tmp82;
          $_container79[$_key76] = $_value80;
        }
        $_elem74 = $_container79;
        $_container73 []= $_elem74;
      }
      $this->list_of_map_of_string_to_MyStruct = $_container73;
    }
  }

}


<?hh
/**
 * Autogenerated by Thrift
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */

/**
 * Original thrift service:-
 * MyService
 */
interface MyServiceAsyncIf extends \IThriftAsyncIf {
  /**
   * Original thrift definition:-
   * MyStruct
   *   func(1: string arg1,
   *        2: MyStruct arg2);
   */
  public function func(string $arg1, ?MyStruct $arg2): Awaitable<MyStruct>;

  /**
   * Original thrift definition:-
   * MyStruct
   *   func1(1: string arg1,
   *         2: MyStruct arg2);
   */
  public function func1(string $arg1, ?MyStruct $arg2): Awaitable<MyStruct>;
}

/**
 * Original thrift service:-
 * MyService
 */
interface MyServiceIf extends \IThriftSyncIf {
  /**
   * Original thrift definition:-
   * MyStruct
   *   func(1: string arg1,
   *        2: MyStruct arg2);
   */
  public function func(string $arg1, ?MyStruct $arg2): MyStruct;

  /**
   * Original thrift definition:-
   * MyStruct
   *   func1(1: string arg1,
   *         2: MyStruct arg2);
   */
  public function func1(string $arg1, ?MyStruct $arg2): MyStruct;
}

/**
 * Original thrift service:-
 * MyService
 */
interface MyServiceAsyncClientIf extends MyServiceAsyncIf {
}

/**
 * Original thrift service:-
 * MyService
 */
interface MyServiceClientIf extends \IThriftSyncIf {
  /**
   * Original thrift definition:-
   * MyStruct
   *   func(1: string arg1,
   *        2: MyStruct arg2);
   */
  public function func(string $arg1, ?MyStruct $arg2): Awaitable<MyStruct>;

  /**
   * Original thrift definition:-
   * MyStruct
   *   func1(1: string arg1,
   *         2: MyStruct arg2);
   */
  public function func1(string $arg1, ?MyStruct $arg2): Awaitable<MyStruct>;
}

/**
 * Original thrift service:-
 * MyService
 */
trait MyServiceClientBase {
  require extends \ThriftClientBase;

}

class MyServiceAsyncClient extends \ThriftClientBase implements MyServiceAsyncClientIf {
  use MyServiceClientBase;

  /**
   * Original thrift definition:-
   * MyStruct
   *   func(1: string arg1,
   *        2: MyStruct arg2);
   */
  public async function func(string $arg1, ?MyStruct $arg2): Awaitable<MyStruct> {
    $hh_frame_metadata = $this->getHHFrameMetadata();
    if ($hh_frame_metadata !== null) {
      \HH\set_frame_metadata($hh_frame_metadata);
    }
    $rpc_options = $this->getAndResetOptions() ?? \ThriftClientBase::defaultOptions();
    $args = MyService_func_args::fromShape(shape(
      'arg1' => $arg1,
      'arg2' => $arg2,
    ));
    await $this->asyncHandler_->genBefore("MyService", "func", $args);
    $currentseqid = $this->sendImplHelper($args, "func", false);
    return await $this->genAwaitResponse(MyService_func_result::class, "func", false, $currentseqid, $rpc_options);
  }

  /**
   * Original thrift definition:-
   * MyStruct
   *   func1(1: string arg1,
   *         2: MyStruct arg2);
   */
  public async function func1(string $arg1, ?MyStruct $arg2): Awaitable<MyStruct> {
    $hh_frame_metadata = $this->getHHFrameMetadata();
    if ($hh_frame_metadata !== null) {
      \HH\set_frame_metadata($hh_frame_metadata);
    }
    $rpc_options = $this->getAndResetOptions() ?? \ThriftClientBase::defaultOptions();
    $args = MyService_func1_args::fromShape(shape(
      'arg1' => $arg1,
      'arg2' => $arg2,
    ));
    await $this->asyncHandler_->genBefore("MyService", "func1", $args);
    $currentseqid = $this->sendImplHelper($args, "func1", false);
    return await $this->genAwaitResponse(MyService_func1_result::class, "func1", false, $currentseqid, $rpc_options);
  }

}

class MyServiceClient extends \ThriftClientBase implements MyServiceClientIf {
  use MyServiceClientBase;

  /**
   * Original thrift definition:-
   * MyStruct
   *   func(1: string arg1,
   *        2: MyStruct arg2);
   */
  public async function func(string $arg1, ?MyStruct $arg2): Awaitable<MyStruct> {
    $hh_frame_metadata = $this->getHHFrameMetadata();
    if ($hh_frame_metadata !== null) {
      \HH\set_frame_metadata($hh_frame_metadata);
    }
    $rpc_options = $this->getAndResetOptions() ?? \ThriftClientBase::defaultOptions();
    $args = MyService_func_args::fromShape(shape(
      'arg1' => $arg1,
      'arg2' => $arg2,
    ));
    await $this->asyncHandler_->genBefore("MyService", "func", $args);
    $currentseqid = $this->sendImplHelper($args, "func", false);
    return await $this->genAwaitResponse(MyService_func_result::class, "func", false, $currentseqid, $rpc_options);
  }

  /**
   * Original thrift definition:-
   * MyStruct
   *   func1(1: string arg1,
   *         2: MyStruct arg2);
   */
  public async function func1(string $arg1, ?MyStruct $arg2): Awaitable<MyStruct> {
    $hh_frame_metadata = $this->getHHFrameMetadata();
    if ($hh_frame_metadata !== null) {
      \HH\set_frame_metadata($hh_frame_metadata);
    }
    $rpc_options = $this->getAndResetOptions() ?? \ThriftClientBase::defaultOptions();
    $args = MyService_func1_args::fromShape(shape(
      'arg1' => $arg1,
      'arg2' => $arg2,
    ));
    await $this->asyncHandler_->genBefore("MyService", "func1", $args);
    $currentseqid = $this->sendImplHelper($args, "func1", false);
    return await $this->genAwaitResponse(MyService_func1_result::class, "func1", false, $currentseqid, $rpc_options);
  }

  /* send and recv functions */
  public function send_func(string $arg1, ?MyStruct $arg2): int {
    $args = MyService_func_args::fromShape(shape(
      'arg1' => $arg1,
      'arg2' => $arg2,
    ));
    return $this->sendImplHelper($args, "func", false);
  }
  public function recv_func(?int $expectedsequenceid = null): MyStruct {
    return $this->recvImplHelper(MyService_func_result::class, "func", false, $expectedsequenceid);
  }
  public function send_func1(string $arg1, ?MyStruct $arg2): int {
    $args = MyService_func1_args::fromShape(shape(
      'arg1' => $arg1,
      'arg2' => $arg2,
    ));
    return $this->sendImplHelper($args, "func1", false);
  }
  public function recv_func1(?int $expectedsequenceid = null): MyStruct {
    return $this->recvImplHelper(MyService_func1_result::class, "func1", false, $expectedsequenceid);
  }
}

// HELPER FUNCTIONS AND STRUCTURES

class MyService_func_args implements \IThriftSyncStruct, \IThriftStructMetadata, \IThriftShapishAsyncStruct {
  use \ThriftSerializationTrait;

  const \ThriftStructTypes::TSpec SPEC = dict[
    1 => shape(
      'var' => 'arg1',
      'type' => \TType::STRING,
    ),
    2 => shape(
      'var' => 'arg2',
      'type' => \TType::STRUCT,
      'class' => MyStruct::class,
    ),
  ];
  const dict<string, int> FIELDMAP = dict[
    'arg1' => 1,
    'arg2' => 2,
  ];

  const type TConstructorShape = shape(
    ?'arg1' => ?string,
    ?'arg2' => ?MyStruct,
  );

  const type TShape = shape(
    'arg1' => string,
    ?'arg2' => ?MyStruct::TShape,
  );
  const int STRUCTURAL_ID = 6560600906529955702;
  public string $arg1;
  public ?MyStruct $arg2;

  public function __construct(?string $arg1 = null, ?MyStruct $arg2 = null)[] {
    $this->arg1 = $arg1 ?? '';
    $this->arg2 = $arg2;
  }

  public static function withDefaultValues()[]: this {
    return new static();
  }

  public static function fromShape(self::TConstructorShape $shape)[]: this {
    return new static(
      Shapes::idx($shape, 'arg1'),
      Shapes::idx($shape, 'arg2'),
    );
  }

  public function getName()[]: string {
    return 'MyService_func_args';
  }

  public function clearTerseFields()[write_props]: void {
  }

  public static function getStructMetadata()[]: \tmeta_ThriftStruct {
    return tmeta_ThriftStruct::fromShape(
      shape(
        "name" => "module.func_args",
        "fields" => vec[
          tmeta_ThriftField::fromShape(
            shape(
              "id" => 1,
              "type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_primitive" => tmeta_ThriftPrimitiveType::THRIFT_STRING_TYPE,
                )
              ),
              "name" => "arg1",
            )
          ),
          tmeta_ThriftField::fromShape(
            shape(
              "id" => 2,
              "type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_struct" => tmeta_ThriftStructType::fromShape(
                    shape(
                      "name" => "module.MyStruct",
                    )
                  ),
                )
              ),
              "name" => "arg2",
            )
          ),
        ],
        "is_union" => false,
      )
    );
  }

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[],
      'fields' => dict[
      ],
    );
  }

  public static function __stringifyMapKeys<T>(dict<arraykey, T> $m)[]: dict<string, T> {
    return Dict\map_keys($m, $key ==> (string)$key);
  }

  public static async function __genFromShape(self::TShape $shape): Awaitable<this> {
    $obj = new static();
    $obj->arg1 = $shape['arg1'];
    $arg2 = Shapes::idx($shape, 'arg2');
    if ($arg2 !== null) {
      $obj->arg2 = await MyStruct::__genFromShape($arg2);
    }
    return $obj;
  }

  public async function __genToShape(): Awaitable<self::TShape> {
    return shape(
      'arg1' => $this->arg1,
      'arg2' => await ($this->arg2 === null
        ? null
        : (
        $this->arg2->__genToShape()
        )
      ),
    );
  }
  public function getInstanceKey()[write_props]: string {
    return \TCompactSerializer::serialize($this);
  }

  public function readFromJson(string $jsonText): void {
    $parsed = json_decode($jsonText, true);

    if ($parsed === null || !($parsed is KeyedContainer<_, _>)) {
      throw new \TProtocolException("Cannot parse the given json string.");
    }

    if (idx($parsed, 'arg1') !== null) {
      $this->arg1 = HH\FIXME\UNSAFE_CAST<mixed, string>($parsed['arg1']);
    }
    if (idx($parsed, 'arg2') !== null) {
      $_tmp0 = \json_encode(HH\FIXME\UNSAFE_CAST<mixed, MyStruct>($parsed['arg2']));
      $_tmp1 = MyStruct::withDefaultValues();
      $_tmp1->readFromJson($_tmp0);
      $this->arg2 = $_tmp1;
    }
  }

}

class MyService_func_result extends \ThriftSyncStructWithResult implements \IThriftStructMetadata {
  use \ThriftSerializationTrait;

  const type TResult = MyStruct;

  const \ThriftStructTypes::TSpec SPEC = dict[
    0 => shape(
      'var' => 'success',
      'type' => \TType::STRUCT,
      'class' => MyStruct::class,
    ),
  ];
  const dict<string, int> FIELDMAP = dict[
    'success' => 0,
  ];

  const type TConstructorShape = shape(
    ?'success' => ?this::TResult,
  );

  const int STRUCTURAL_ID = 7307096097859369800;
  public ?this::TResult $success;

  public function __construct(?this::TResult $success = null)[] {
    $this->success = $success;
  }

  public static function withDefaultValues()[]: this {
    return new static();
  }

  public static function fromShape(self::TConstructorShape $shape)[]: this {
    return new static(
      Shapes::idx($shape, 'success'),
    );
  }

  public function getName()[]: string {
    return 'MyService_func_result';
  }

  public function clearTerseFields()[write_props]: void {
  }

  public static function getStructMetadata()[]: \tmeta_ThriftStruct {
    return tmeta_ThriftStruct::fromShape(
      shape(
        "name" => "module.MyService_func_result",
        "fields" => vec[
          tmeta_ThriftField::fromShape(
            shape(
              "id" => 0,
              "type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_struct" => tmeta_ThriftStructType::fromShape(
                    shape(
                      "name" => "module.MyStruct",
                    )
                  ),
                )
              ),
              "name" => "success",
            )
          ),
        ],
        "is_union" => false,
      )
    );
  }

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[],
      'fields' => dict[
      ],
    );
  }

  public function getInstanceKey()[write_props]: string {
    return \TCompactSerializer::serialize($this);
  }

  public function readFromJson(string $jsonText): void {
    $parsed = json_decode($jsonText, true);

    if ($parsed === null || !($parsed is KeyedContainer<_, _>)) {
      throw new \TProtocolException("Cannot parse the given json string.");
    }

    if (idx($parsed, 'success') !== null) {
      $_tmp0 = \json_encode(HH\FIXME\UNSAFE_CAST<mixed, MyStruct>($parsed['success']));
      $_tmp1 = MyStruct::withDefaultValues();
      $_tmp1->readFromJson($_tmp0);
      $this->success = $_tmp1;
    }
  }

}

class MyService_func1_args implements \IThriftSyncStruct, \IThriftStructMetadata, \IThriftShapishAsyncStruct {
  use \ThriftSerializationTrait;

  const \ThriftStructTypes::TSpec SPEC = dict[
    1 => shape(
      'var' => 'arg1',
      'type' => \TType::STRING,
    ),
    2 => shape(
      'var' => 'arg2',
      'type' => \TType::STRUCT,
      'class' => MyStruct::class,
    ),
  ];
  const dict<string, int> FIELDMAP = dict[
    'arg1' => 1,
    'arg2' => 2,
  ];

  const type TConstructorShape = shape(
    ?'arg1' => ?string,
    ?'arg2' => ?MyStruct,
  );

  const type TShape = shape(
    'arg1' => string,
    ?'arg2' => ?MyStruct::TShape,
  );
  const int STRUCTURAL_ID = 6560600906529955702;
  public string $arg1;
  public ?MyStruct $arg2;

  public function __construct(?string $arg1 = null, ?MyStruct $arg2 = null)[] {
    $this->arg1 = $arg1 ?? '';
    $this->arg2 = $arg2;
  }

  public static function withDefaultValues()[]: this {
    return new static();
  }

  public static function fromShape(self::TConstructorShape $shape)[]: this {
    return new static(
      Shapes::idx($shape, 'arg1'),
      Shapes::idx($shape, 'arg2'),
    );
  }

  public function getName()[]: string {
    return 'MyService_func1_args';
  }

  public function clearTerseFields()[write_props]: void {
  }

  public static function getStructMetadata()[]: \tmeta_ThriftStruct {
    return tmeta_ThriftStruct::fromShape(
      shape(
        "name" => "module.func1_args",
        "fields" => vec[
          tmeta_ThriftField::fromShape(
            shape(
              "id" => 1,
              "type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_primitive" => tmeta_ThriftPrimitiveType::THRIFT_STRING_TYPE,
                )
              ),
              "name" => "arg1",
            )
          ),
          tmeta_ThriftField::fromShape(
            shape(
              "id" => 2,
              "type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_struct" => tmeta_ThriftStructType::fromShape(
                    shape(
                      "name" => "module.MyStruct",
                    )
                  ),
                )
              ),
              "name" => "arg2",
            )
          ),
        ],
        "is_union" => false,
      )
    );
  }

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[],
      'fields' => dict[
      ],
    );
  }

  public static function __stringifyMapKeys<T>(dict<arraykey, T> $m)[]: dict<string, T> {
    return Dict\map_keys($m, $key ==> (string)$key);
  }

  public static async function __genFromShape(self::TShape $shape): Awaitable<this> {
    $obj = new static();
    $obj->arg1 = $shape['arg1'];
    $arg2 = Shapes::idx($shape, 'arg2');
    if ($arg2 !== null) {
      $obj->arg2 = await MyStruct::__genFromShape($arg2);
    }
    return $obj;
  }

  public async function __genToShape(): Awaitable<self::TShape> {
    return shape(
      'arg1' => $this->arg1,
      'arg2' => await ($this->arg2 === null
        ? null
        : (
        $this->arg2->__genToShape()
        )
      ),
    );
  }
  public function getInstanceKey()[write_props]: string {
    return \TCompactSerializer::serialize($this);
  }

  public function readFromJson(string $jsonText): void {
    $parsed = json_decode($jsonText, true);

    if ($parsed === null || !($parsed is KeyedContainer<_, _>)) {
      throw new \TProtocolException("Cannot parse the given json string.");
    }

    if (idx($parsed, 'arg1') !== null) {
      $this->arg1 = HH\FIXME\UNSAFE_CAST<mixed, string>($parsed['arg1']);
    }
    if (idx($parsed, 'arg2') !== null) {
      $_tmp0 = \json_encode(HH\FIXME\UNSAFE_CAST<mixed, MyStruct>($parsed['arg2']));
      $_tmp1 = MyStruct::withDefaultValues();
      $_tmp1->readFromJson($_tmp0);
      $this->arg2 = $_tmp1;
    }
  }

}

class MyService_func1_result extends \ThriftSyncStructWithResult implements \IThriftStructMetadata {
  use \ThriftSerializationTrait;

  const type TResult = MyStruct;

  const \ThriftStructTypes::TSpec SPEC = dict[
    0 => shape(
      'var' => 'success',
      'type' => \TType::STRUCT,
      'class' => MyStruct::class,
    ),
  ];
  const dict<string, int> FIELDMAP = dict[
    'success' => 0,
  ];

  const type TConstructorShape = shape(
    ?'success' => ?this::TResult,
  );

  const int STRUCTURAL_ID = 7307096097859369800;
  public ?this::TResult $success;

  public function __construct(?this::TResult $success = null)[] {
    $this->success = $success;
  }

  public static function withDefaultValues()[]: this {
    return new static();
  }

  public static function fromShape(self::TConstructorShape $shape)[]: this {
    return new static(
      Shapes::idx($shape, 'success'),
    );
  }

  public function getName()[]: string {
    return 'MyService_func1_result';
  }

  public function clearTerseFields()[write_props]: void {
  }

  public static function getStructMetadata()[]: \tmeta_ThriftStruct {
    return tmeta_ThriftStruct::fromShape(
      shape(
        "name" => "module.MyService_func1_result",
        "fields" => vec[
          tmeta_ThriftField::fromShape(
            shape(
              "id" => 0,
              "type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_struct" => tmeta_ThriftStructType::fromShape(
                    shape(
                      "name" => "module.MyStruct",
                    )
                  ),
                )
              ),
              "name" => "success",
            )
          ),
        ],
        "is_union" => false,
      )
    );
  }

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[],
      'fields' => dict[
      ],
    );
  }

  public function getInstanceKey()[write_props]: string {
    return \TCompactSerializer::serialize($this);
  }

  public function readFromJson(string $jsonText): void {
    $parsed = json_decode($jsonText, true);

    if ($parsed === null || !($parsed is KeyedContainer<_, _>)) {
      throw new \TProtocolException("Cannot parse the given json string.");
    }

    if (idx($parsed, 'success') !== null) {
      $_tmp0 = \json_encode(HH\FIXME\UNSAFE_CAST<mixed, MyStruct>($parsed['success']));
      $_tmp1 = MyStruct::withDefaultValues();
      $_tmp1->readFromJson($_tmp0);
      $this->success = $_tmp1;
    }
  }

}

class MyServiceStaticMetadata implements \IThriftServiceStaticMetadata {
  public static function getServiceMetadata()[]: \tmeta_ThriftService {
    return tmeta_ThriftService::fromShape(
      shape(
        "name" => "module.MyService",
        "functions" => vec[
          tmeta_ThriftFunction::fromShape(
            shape(
              "name" => "func",
              "return_type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_struct" => tmeta_ThriftStructType::fromShape(
                    shape(
                      "name" => "module.MyStruct",
                    )
                  ),
                )
              ),
              "arguments" => vec[
                tmeta_ThriftField::fromShape(
                  shape(
                    "id" => 1,
                    "type" => tmeta_ThriftType::fromShape(
                      shape(
                        "t_primitive" => tmeta_ThriftPrimitiveType::THRIFT_STRING_TYPE,
                      )
                    ),
                    "name" => "arg1",
                  )
                ),
                tmeta_ThriftField::fromShape(
                  shape(
                    "id" => 2,
                    "type" => tmeta_ThriftType::fromShape(
                      shape(
                        "t_struct" => tmeta_ThriftStructType::fromShape(
                          shape(
                            "name" => "module.MyStruct",
                          )
                        ),
                      )
                    ),
                    "name" => "arg2",
                  )
                ),
              ],
            )
          ),
          tmeta_ThriftFunction::fromShape(
            shape(
              "name" => "func1",
              "return_type" => tmeta_ThriftType::fromShape(
                shape(
                  "t_struct" => tmeta_ThriftStructType::fromShape(
                    shape(
                      "name" => "module.MyStruct",
                    )
                  ),
                )
              ),
              "arguments" => vec[
                tmeta_ThriftField::fromShape(
                  shape(
                    "id" => 1,
                    "type" => tmeta_ThriftType::fromShape(
                      shape(
                        "t_primitive" => tmeta_ThriftPrimitiveType::THRIFT_STRING_TYPE,
                      )
                    ),
                    "name" => "arg1",
                  )
                ),
                tmeta_ThriftField::fromShape(
                  shape(
                    "id" => 2,
                    "type" => tmeta_ThriftType::fromShape(
                      shape(
                        "t_struct" => tmeta_ThriftStructType::fromShape(
                          shape(
                            "name" => "module.MyStruct",
                          )
                        ),
                      )
                    ),
                    "name" => "arg2",
                  )
                ),
              ],
            )
          ),
        ],
      )
    );
  }

  public static function getServiceMetadataResponse()[]: \tmeta_ThriftServiceMetadataResponse {
    return \tmeta_ThriftServiceMetadataResponse::fromShape(
      shape(
        'context' => \tmeta_ThriftServiceContext::fromShape(
          shape(
            'service_info' => self::getServiceMetadata(),
            'module' => \tmeta_ThriftModuleContext::fromShape(
              shape(
                'name' => 'module',
              )
            ),
          )
        ),
        'metadata' => \tmeta_ThriftMetadata::fromShape(
          shape(
            'enums' => dict[
            ],
            'structs' => dict[
              'module.MyStruct' => MyStruct::getStructMetadata(),
              'module.MyNestedStruct' => MyNestedStruct::getStructMetadata(),
            ],
            'exceptions' => dict[
            ],
            'services' => dict[
            ],
          )
        ),
      )
    );
  }

  public static function getAllStructuredAnnotations()[write_props]: \TServiceAnnotations {
    return shape(
      'service' => dict[],
      'functions' => dict[
      ],
    );
  }
}