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

namespace facebook\thrift\annotation;

/**
 * Indicates a definition/feature may change in incompatible ways.
 *
 * Original thrift struct:-
 * Beta
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/Beta'))>>
class Beta implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'Beta';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Program' => \facebook\thrift\annotation\Program::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Definition' => \facebook\thrift\annotation\Definition::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Indicates a definition/feature should only be used with permission, may
 * only work in specific contexts, and may change in incompatible ways without
 * notice.
 *
 * Original thrift struct:-
 * Experimental
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/Experimental'))>>
class Experimental implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'Experimental';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Program' => \facebook\thrift\annotation\Program::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Definition' => \facebook\thrift\annotation\Definition::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Indicates a definition/feature should only be used in an ephemeral testing
 * enviornment.
 *
 * Such enviornments only store serialized values temporarly and strictly
 * control which versions of Thrift definitions are used, so 'compatibility'
 * is not a concern.
 *
 * Original thrift struct:-
 * Testing
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/Testing'))>>
class Testing implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'Testing';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Program' => \facebook\thrift\annotation\Program::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Definition' => \facebook\thrift\annotation\Definition::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Indicates a definition/feature should no longer be used.
 *
 * Original thrift struct:-
 * Deprecated
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/Deprecated'))>>
class Deprecated implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = shape(
    ?'message' => ?string,
  );

  const int STRUCTURAL_ID = 2427562471238739676;
  /**
   * Original thrift field:-
   * 1: string message
   */
  public string $message;

  public function __construct(?string $message = null)[] {
    $this->message = $message ?? '';
  }

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

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

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

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

  public static function getStructMetadata()[]: \tmeta_ThriftStruct {
    return \tmeta_ThriftStruct::fromShape(
      shape(
        "name" => "thrift.Deprecated",
        "fields" => vec[
          \tmeta_ThriftField::fromShape(
            shape(
              "id" => 1,
              "type" => \tmeta_ThriftType::fromShape(
                shape(
                  "t_primitive" => \tmeta_ThriftPrimitiveType::THRIFT_STRING_TYPE,
                )
              ),
              "name" => "message",
            )
          ),
        ],
        "is_union" => false,
      )
    );
  }

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Beta' => \facebook\thrift\annotation\Beta::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Program' => \facebook\thrift\annotation\Program::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Definition' => \facebook\thrift\annotation\Definition::fromShape(
          shape(
          )
        ),
      ],
      '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, 'message') !== null) {
      $this->message = HH\FIXME\UNSAFE_CAST<mixed, string>($parsed['message']);
    }
  }

}

/**
 * Annotate a thrift structured or enum to indicate if ids or values should not
 * be used.
 *
 * For example, you may want to mark ids as deprecated, or these ids
 * might be reserved for other use cases or annotations.
 *
 * The resolved set of disallowed ids is the union of the values in `ids` and
 * the range of values represented in `id_ranges`. Example:
 *
 *  // These ids are not allowed: 3, 8, half-open ranges [10, 15), [20, 30)
 *  @thrift.ReserveIds{ids = [3, 8], id_ranges = {10: 15, 20: 30}}
 *  struct Foo {
 *    ...
 *    3: i64 f; // Build failure: 3 cannot be used
 *  }
 *
 * Original thrift struct:-
 * ReserveIds
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/ReserveIds'))>>
class ReserveIds implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

  const \ThriftStructTypes::TSpec SPEC = dict[
    1 => shape(
      'var' => 'ids',
      'type' => \TType::LST,
      'etype' => \TType::I32,
      'elem' => shape(
        'type' => \TType::I32,
      ),
      'format' => 'collection',
    ),
    2 => shape(
      'var' => 'id_ranges',
      'type' => \TType::MAP,
      'ktype' => \TType::I32,
      'vtype' => \TType::I32,
      'key' => shape(
        'type' => \TType::I32,
      ),
      'val' => shape(
        'type' => \TType::I32,
      ),
      'format' => 'collection',
    ),
  ];
  const dict<string, int> FIELDMAP = dict[
    'ids' => 1,
    'id_ranges' => 2,
  ];

  const type TConstructorShape = shape(
    ?'ids' => ?Vector<int>,
    ?'id_ranges' => ?Map<int, int>,
  );

  const int STRUCTURAL_ID = 4105998268635615653;
  /**
   * Individual ids that cannot be used.
   *
   * Original thrift field:-
   * 1: list<i32> ids
   */
  public Vector<int> $ids;
  /**
   * Represents ranges of ids that cannot be used.
   *
   * Each (key: value) pair represents the half-open range `[key, value)`,
   * where `key` is included and `value` is not. For example, the map
   * `{10: 15, 20: 30}` represents the union of id/value ranges `[10, 15)` and
   * `[20, 30)`.
   *
   * Original thrift field:-
   * 2: map<i32, i32> id_ranges
   */
  public Map<int, int> $id_ranges;

  public function __construct(?Vector<int> $ids = null, ?Map<int, int> $id_ranges = null)[] {
    $this->ids = $ids ?? Vector {};
    $this->id_ranges = $id_ranges ?? Map {};
  }

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

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

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

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

  public static function getStructMetadata()[]: \tmeta_ThriftStruct {
    return \tmeta_ThriftStruct::fromShape(
      shape(
        "name" => "thrift.ReserveIds",
        "fields" => vec[
          \tmeta_ThriftField::fromShape(
            shape(
              "id" => 1,
              "type" => \tmeta_ThriftType::fromShape(
                shape(
                  "t_list" => \tmeta_ThriftListType::fromShape(
                    shape(
                      "valueType" => \tmeta_ThriftType::fromShape(
                        shape(
                          "t_primitive" => \tmeta_ThriftPrimitiveType::THRIFT_I32_TYPE,
                        )
                      ),
                    )
                  ),
                )
              ),
              "name" => "ids",
            )
          ),
          \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_I32_TYPE,
                        )
                      ),
                      "valueType" => \tmeta_ThriftType::fromShape(
                        shape(
                          "t_primitive" => \tmeta_ThriftPrimitiveType::THRIFT_I32_TYPE,
                        )
                      ),
                    )
                  ),
                )
              ),
              "name" => "id_ranges",
            )
          ),
        ],
        "is_union" => false,
      )
    );
  }

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Structured' => \facebook\thrift\annotation\Structured::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Enum' => \facebook\thrift\annotation\Enum::fromShape(
          shape(
          )
        ),
      ],
      '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, 'ids') !== null) {
      $_json3 = HH\FIXME\UNSAFE_CAST<mixed, Vector<int>>($parsed['ids']);
      $_container4 = Vector {};
      foreach($_json3 as $_key1 => $_value2) {
        $_elem5 = 0;
        $_tmp6 = (int)$_value2;
        if ($_tmp6 > 0x7fffffff) {
          throw new \TProtocolException("number exceeds limit in field");
        } else {
          $_elem5 = (int)$_tmp6;
        }
        $_container4 []= $_elem5;
      }
      $this->ids = $_container4;
    }
    if (idx($parsed, 'id_ranges') !== null) {
      $_json10 = HH\FIXME\UNSAFE_CAST<mixed, Map<int, int>>($parsed['id_ranges']);
      $_container11 = Map {};
      foreach($_json10 as $_key8 => $_value9) {
        $_value12 = 0;
        $_tmp13 = (int)$_value9;
        if ($_tmp13 > 0x7fffffff) {
          throw new \TProtocolException("number exceeds limit in field");
        } else {
          $_value12 = (int)$_tmp13;
        }
        $_container11[$_key8] = $_value12;
      }
      $this->id_ranges = $_container11;
    }
  }

}

/**
 * Indicates additional backward compatibility restrictions, beyond the
 * standard Thrift required 'wire' compatibility.
 *
 * Original thrift struct:-
 * RequiresBackwardCompatibility
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/RequiresBackwardCompatibility'))>>
class RequiresBackwardCompatibility implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = shape(
    ?'field_name' => ?bool,
  );

  const int STRUCTURAL_ID = 4755373036761315562;
  /**
   * Original thrift field:-
   * 1: bool field_name
   */
  public bool $field_name;

  public function __construct(?bool $field_name = null)[] {
    $this->field_name = $field_name ?? false;
  }

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

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

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

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

  public static function getStructMetadata()[]: \tmeta_ThriftStruct {
    return \tmeta_ThriftStruct::fromShape(
      shape(
        "name" => "thrift.RequiresBackwardCompatibility",
        "fields" => vec[
          \tmeta_ThriftField::fromShape(
            shape(
              "id" => 1,
              "type" => \tmeta_ThriftType::fromShape(
                shape(
                  "t_primitive" => \tmeta_ThriftPrimitiveType::THRIFT_BOOL_TYPE,
                )
              ),
              "name" => "field_name",
            )
          ),
        ],
        "is_union" => false,
      )
    );
  }

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Structured' => \facebook\thrift\annotation\Structured::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Experimental' => \facebook\thrift\annotation\Experimental::fromShape(
          shape(
          )
        ),
      ],
      '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, 'field_name') !== null) {
      $this->field_name = HH\FIXME\UNSAFE_CAST<mixed, bool>($parsed['field_name']);
    }
  }

}

/**
 * Disables testing features.
 *
 * Original thrift struct:-
 * NoTesting
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/NoTesting'))>>
class NoTesting implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'NoTesting';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Program' => \facebook\thrift\annotation\Program::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Definition' => \facebook\thrift\annotation\Definition::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Disables experimental features.
 *
 * Original thrift struct:-
 * NoExperimental
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/NoExperimental'))>>
class NoExperimental implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'NoExperimental';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Program' => \facebook\thrift\annotation\Program::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Definition' => \facebook\thrift\annotation\Definition::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Disables @Beta features.
 *
 * Original thrift struct:-
 * NoBeta
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/NoBeta'))>>
class NoBeta implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'NoBeta';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\NoExperimental' => \facebook\thrift\annotation\NoExperimental::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Transitive' => \facebook\thrift\annotation\Transitive::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Indicates a definition/feature must not depend directly on an unreleased
 * or testing definition/feature.
 *
 * Original thrift struct:-
 * Released
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/Released'))>>
class Released implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'Released';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\NoBeta' => \facebook\thrift\annotation\NoBeta::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\NoTesting' => \facebook\thrift\annotation\NoTesting::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Transitive' => \facebook\thrift\annotation\Transitive::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Disables legacy features.
 *
 * Original thrift struct:-
 * NoLegacy
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/NoLegacy'))>>
class NoLegacy implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'NoLegacy';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Program' => \facebook\thrift\annotation\Program::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Definition' => \facebook\thrift\annotation\Definition::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Experimental' => \facebook\thrift\annotation\Experimental::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Disables @Deprecated features.
 *
 * Should only be enabled in `test` versions, as deprecated implies removing
 * the feature will break current usage (otherwise it would be legacy or
 * deleted).
 *
 * Original thrift struct:-
 * NoDeprecated
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/NoDeprecated'))>>
class NoDeprecated implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'NoDeprecated';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\NoLegacy' => \facebook\thrift\annotation\NoLegacy::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Beta' => \facebook\thrift\annotation\Beta::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Transitive' => \facebook\thrift\annotation\Transitive::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * An annotation that changes the field qualifier from 'none' to 'terse'.
 * A terse field is eligible to skip serialization, when it equals to the
 * intrinsic default value. It also clears to the intrinsic default value
 * before deserialization to distinguish between if a terse field was skipped
 * or missing during serialization. This is different from an unqualified
 * field, as an unqualified field is always serialized regardless of its value,
 * and it is not cleared before deserialization.
 *
 * The annotation can be only used to annotate an unqualified field, and when
 * it is annotating a struct or exception, it changes all unqualified fields to
 * terse fields. Note, the annotation can not be used for union.
 *
 * Original thrift struct:-
 * TerseWrite
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/TerseWrite'))>>
class TerseWrite implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'TerseWrite';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Program' => \facebook\thrift\annotation\Program::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Struct' => \facebook\thrift\annotation\Struct::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Exception' => \facebook\thrift\annotation\Exception::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Field' => \facebook\thrift\annotation\Field::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Experimental' => \facebook\thrift\annotation\Experimental::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Indicates that a field's value should never be stored on the stack.
 *
 * Original thrift struct:-
 * Box
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/Box'))>>
class Box implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'Box';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Field' => \facebook\thrift\annotation\Field::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Beta' => \facebook\thrift\annotation\Beta::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Original thrift struct:-
 * Mixin
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/Mixin'))>>
class Mixin implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'Mixin';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Field' => \facebook\thrift\annotation\Field::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Beta' => \facebook\thrift\annotation\Beta::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Option to serialize thrift struct in ascending field id order.
 *
 * This can potentially make serialized data size smaller in compact protocol,
 * since compact protocol can write deltas between subsequent field ids.
 *
 * Original thrift struct:-
 * SerializeInFieldIdOrder
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/SerializeInFieldIdOrder'))>>
class SerializeInFieldIdOrder implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'SerializeInFieldIdOrder';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Struct' => \facebook\thrift\annotation\Struct::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Experimental' => \facebook\thrift\annotation\Experimental::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Indicates an enum is a bitmask and should support bit-wise operators.
 *
 * Original thrift struct:-
 * BitmaskEnum
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/BitmaskEnum'))>>
class BitmaskEnum implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'BitmaskEnum';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Enum' => \facebook\thrift\annotation\Enum::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Experimental' => \facebook\thrift\annotation\Experimental::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Enables all released v1 features.
 *
 * Original thrift struct:-
 * v1
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/v1'))>>
class v1 implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'v1';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Transitive' => \facebook\thrift\annotation\Transitive::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Enables all beta v1 features.
 *
 * Beta features are guaranteed to *not* break unrelated Thrift features
 * so they should be relatively safe to test alongside other beta or
 * released Thrift features.
 *
 * Original thrift struct:-
 * v1beta
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/v1beta'))>>
class v1beta implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'v1beta';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\v1' => \facebook\thrift\annotation\v1::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Beta' => \facebook\thrift\annotation\Beta::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Transitive' => \facebook\thrift\annotation\Transitive::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Enables all experimental v1 features.
 *
 * Use with *caution* and only with explicit permission. This may enable
 * features may change significantly without notice or not work correctly
 * in all contexts.
 *
 * Original thrift struct:-
 * v1alpha
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/v1alpha'))>>
class v1alpha implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'v1alpha';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\v1beta' => \facebook\thrift\annotation\v1beta::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\SerializeInFieldIdOrder' => \facebook\thrift\annotation\SerializeInFieldIdOrder::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Experimental' => \facebook\thrift\annotation\Experimental::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Transitive' => \facebook\thrift\annotation\Transitive::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Enables experimental features, even those that are known to break common
 * use cases.
 *
 * Original thrift struct:-
 * v1test
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/v1test'))>>
class v1test implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'v1test';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\NoDeprecated' => \facebook\thrift\annotation\NoDeprecated::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\v1alpha' => \facebook\thrift\annotation\v1alpha::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Testing' => \facebook\thrift\annotation\Testing::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Transitive' => \facebook\thrift\annotation\Transitive::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}

/**
 * Specifies the field where the exception message is stored. The field
 * is used to generate an additional method to get it.
 *
 * Original thrift struct:-
 * ExceptionMessage
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/ExceptionMessage'))>>
class ExceptionMessage implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = shape(
    ?'field' => ?string,
  );

  const int STRUCTURAL_ID = 6158382972310209096;
  /**
   * Original thrift field:-
   * 1: string field
   */
  public string $field;

  public function __construct(?string $field = null)[] {
    $this->field = $field ?? '';
  }

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

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

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

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

  public static function getStructMetadata()[]: \tmeta_ThriftStruct {
    return \tmeta_ThriftStruct::fromShape(
      shape(
        "name" => "thrift.ExceptionMessage",
        "fields" => vec[
          \tmeta_ThriftField::fromShape(
            shape(
              "id" => 1,
              "type" => \tmeta_ThriftType::fromShape(
                shape(
                  "t_primitive" => \tmeta_ThriftPrimitiveType::THRIFT_STRING_TYPE,
                )
              ),
              "name" => "field",
            )
          ),
        ],
        "is_union" => false,
      )
    );
  }

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Exception' => \facebook\thrift\annotation\Exception::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Experimental' => \facebook\thrift\annotation\Experimental::fromShape(
          shape(
          )
        ),
      ],
      '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, 'field') !== null) {
      $this->field = HH\FIXME\UNSAFE_CAST<mixed, string>($parsed['field']);
    }
  }

}

/**
 * Generates a const of type schema. Struct containing the schema of the
 * annotated type. Optionally specify name to override default
 * schema<structName>.
 *
 * Original thrift struct:-
 * GenerateRuntimeSchema
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/GenerateRuntimeSchema'))>>
class GenerateRuntimeSchema implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = shape(
    ?'name' => ?string,
  );

  const int STRUCTURAL_ID = 2593878277785201336;
  /**
   * Original thrift field:-
   * 1: string name
   */
  public string $name;

  public function __construct(?string $name = null)[] {
    $this->name = $name ?? '';
  }

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

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

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

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

  public static function getStructMetadata()[]: \tmeta_ThriftStruct {
    return \tmeta_ThriftStruct::fromShape(
      shape(
        "name" => "thrift.GenerateRuntimeSchema",
        "fields" => vec[
          \tmeta_ThriftField::fromShape(
            shape(
              "id" => 1,
              "type" => \tmeta_ThriftType::fromShape(
                shape(
                  "t_primitive" => \tmeta_ThriftPrimitiveType::THRIFT_STRING_TYPE,
                )
              ),
              "name" => "name",
            )
          ),
        ],
        "is_union" => false,
      )
    );
  }

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Structured' => \facebook\thrift\annotation\Structured::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Service' => \facebook\thrift\annotation\Service::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\TConst' => \facebook\thrift\annotation\TConst::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Enum' => \facebook\thrift\annotation\Enum::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Typedef' => \facebook\thrift\annotation\Typedef::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Experimental' => \facebook\thrift\annotation\Experimental::fromShape(
          shape(
          )
        ),
      ],
      '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, 'name') !== null) {
      $this->name = HH\FIXME\UNSAFE_CAST<mixed, string>($parsed['name']);
    }
  }

}

/**
 * Indicates that a field's value should never be stored on the stack, and that
 * identical values can be shared in immutable contexts.
 *
 * Original thrift struct:-
 * InternBox
 */
<<\ThriftTypeInfo(shape('uri' => 'facebook.com/thrift/annotation/InternBox'))>>
class InternBox implements \IThriftSyncStruct, \IThriftStructMetadata {
  use \ThriftSerializationTrait;

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

  const type TConstructorShape = 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 'InternBox';
  }

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

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

  public static function getAllStructuredAnnotations()[write_props]: \TStructAnnotations {
    return shape(
      'struct' => dict[
        '\facebook\thrift\annotation\Field' => \facebook\thrift\annotation\Field::fromShape(
          shape(
          )
        ),
        '\facebook\thrift\annotation\Experimental' => \facebook\thrift\annotation\Experimental::fromShape(
          shape(
          )
        ),
      ],
      '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.");
    }

  }

}


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

class ImportThriftLibFromWWW {
  public static function run(array<string> $argv): void {
    invariant(count($argv) >= 2, 'Need to specify path to www');
    self::importHackLib($argv[1]);
    self::transpileHack();
  }

  protected static function importHackLib(string $www_path): void {
    self::walkPHPFiles(
      $www_path.'/flib/thrift/core',
      array(''),
      function (string $root, string $path, string $file) {
        if (strpos($path, '__tests__') !== false) {
          echo "Skipping $path/$file\n";
          return;
        }

        $contents = file_get_contents($root.$path.'/'.$file);
        $contents = preg_replace(
          '#/\* BEGIN_STRIP \*/.*?/\* END_STRIP \*/#s',
          '',
          $contents,
        );
        $contents = preg_replace(
          '#/\* INSERT (.*?) END_INSERT \*/#s',
          '\\1',
          $contents,
        );

        $license = array(
          '/**',
          '* Copyright (c) 2006- Facebook',
          '* Distributed under the Thrift Software License',
          '*',
          '* See accompanying file LICENSE or visit the Thrift site at:',
          '* http://developers.facebook.com/thrift/',
          '*',
          '* @package '.str_replace('/', '.',dirname('thrift'.$path.'/'.$file)),
          '*/',
        );
        $replacement = "\\1\n".implode("\n", $license)."\n";
        $contents = preg_replace(
          '#^(<\?hh(?: +// +[a-z]+)?\n)//.*\n#',
          $replacement,
          $contents,
        );

        if (!file_exists(__DIR__.'/src/'.$path)) {
          mkdir(__DIR__.'/src/'.$path, 0755, true);
        }
        file_put_contents(__DIR__.'/src/'.$path.'/'.$file, $contents);
        echo "Imported $path/$file\n";
      }
    );
  }

  protected static function transpileHack(): void {
    $transpiler = realpath(__DIR__.'/../../../_bin/hphp/hack/src/h2tp/h2tp');
    $source = realpath(__DIR__.'/src');
    $dest = realpath(__DIR__.'/../php/src');

    system('rm -rf '.$dest);
    system($transpiler.' '.$source.' '.$dest);

    file_put_contents($dest.'/Thrift.php', implode("\n", array(
      '<?php',
      'if (!isset($GLOBALS[\'THRIFT_ROOT\'])) {',
      '  $GLOBALS[\'THRIFT_ROOT\'] = __DIR__;',
      '}',
      '',
      '// This file was split into several separate files',
      '// Now we can just require_once all of them',
      '',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/TType.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/TMessageType.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/TException.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/TBase.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/IThriftClient.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/IThriftProcessor.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/IThriftStruct.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/TProcessorEventHandler.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/TClientEventHandler.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/TApplicationException.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/protocol/TProtocol.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/transport/TTransport.php\';',
      '',
    )));

    file_put_contents($dest.'/autoload.php', implode("\n", array(
      '<?php',
      '// Thrift autoload support is deprecated.',
      '// Instead, use the Composer autoloader or another',
      '// autoloader implementation.',
      '',
    )));

    $nonclass_files = ImmSet {
      '/Thrift.php',
      '/autoload.php',
    };
    $classes = Map {};

    self::walkPHPFiles(
      $dest,
      array(''),
      function (string $root, string $path, string $file) use ($classes, $nonclass_files) {
        if (strpos($path, '__tests__') !== false) {
          echo "Skipping $path/$file\n";
          return;
        }

        if (!$nonclass_files->contains($path.'/'.$file)) {
          $classes[basename($file, '.php')] = $path.'/'.$file;
        }

        $contents = file_get_contents($root.$path.'/'.$file);

        $header = array(
          '<?php',
          '',
          '/**',
          '* Copyright (c) 2006- Facebook',
          '* Distributed under the Thrift Software License',
          '*',
          '* See accompanying file LICENSE or visit the Thrift site at:',
          '* http://developers.facebook.com/thrift/',
          '*',
          '* @package '.str_replace('/', '.', dirname('thrift'.$path.'/'.$file)),
          '*/',
          '',
          '',
        );

        $contents = preg_replace('#<\?php\n#', implode("\n", $header), $contents);

        file_put_contents($root.$path.'/'.$file, $contents);

        echo "Added header to $path/$file\n";
      }
    );

    self::walkPHPFiles(
      $dest,
      array(''),
      function (string $root, string $path, string $file) use ($classes, $nonclass_files) {
        if (strpos($path, '__tests__') !== false) {
          echo "Skipping $path/$file\n";
          return;
        }

        if ($nonclass_files->contains($path.'/'.$file)) {
          return;
        }

        $contents = file_get_contents($root.$path.'/'.$file);

        $includes = Vector {};
        $skip_includes = ImmMap {
          'TProtocol.php' => ImmSet {
            'TBinaryProtocolAccelerated',
            'TBinaryProtocolUnaccelerated',
            'TCompactProtocolAccelerated',
            'TCompactProtocolUnaccelerated',
          },
        };
        foreach ($classes as $class => $classpath) {
          if ($file === $class.'.php') {
            continue;
          }
          if ($skip_includes->containsKey($file)) {
            if ($skip_includes->at($file)->contains($class)) {
              continue;
            }
          }
          if (preg_match('/'.$class.'[^a-zA-Z]/', $contents)) {
            $includes[] = $classpath;
          }
        }

        if (!$includes->isEmpty()) {
          sort($includes);
          $hacklib = 'require_once ($GLOBALS["HACKLIB_ROOT"]);';
          $thrift_root_path = '__DIR__';

          $subdirs = substr_count($path, '/');
          if ($subdirs > 0) {
            $thrift_root_path = '__DIR__.\''.str_repeat('/..', $subdirs).'\'';
          }

          $thrift_root = implode("\n", array(
            'if (!isset($GLOBALS[\'THRIFT_ROOT\'])) {',
            '  $GLOBALS[\'THRIFT_ROOT\'] = '.$thrift_root_path.';',
            '}',
          ));

          $replacement = "$hacklib\n$thrift_root\n".implode("\n", $includes->map(function ($path): string {
            return 'require_once $GLOBALS[\'THRIFT_ROOT\'].\''.$path.'\';';
          }));

          $contents = str_replace(
            $hacklib,
            $replacement,
            $contents,
          );

          file_put_contents($root.$path.'/'.$file, $contents);

          echo "Added includes to $path/$file\n";
        }
      }
    );
  }

  protected static function walkPHPFiles(
    string $root,
    array<string> $paths,
    (function (string, string, string): void) $cb,
  ): void {
    for ($i = 0; $i < count($paths); $i++) {
      $path = $paths[$i];
      $full_path = $root.$path;

      $files = scandir($full_path);
      foreach ($files as $file) {
        if ($file === '.' || $file === '..') {
          continue;
        }

        if (is_dir($full_path.'/'.$file)) {
          $paths[] = $path.'/'.$file;
        }

        if (!preg_match('/\.php$/', $file)) {
          continue;
        }

        $cb($root, $path, $file);
      }
    }
  }
}

ImportThriftLibFromWWW::run($argv);


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package thrift
 */

interface IThriftAsyncIf extends IThriftIf {
}


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package thrift
 */

interface IThriftAsyncProcessor extends IThriftProcessor {
  public function processAsync(
    TProtocol $input,
    TProtocol $output,
  ): Awaitable<bool>;
}


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package thrift
 */

interface IThriftAsyncRpcOptionsIf extends IThriftIf {
}


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package thrift
 */

/**
 * Base interface for Thrift clients
 */
interface IThriftClient {
  public function getEventHandler(): TClientEventHandler;
  public function setEventHandler(TClientEventHandler $handler): this;
  public function getAsyncHandler(): TClientAsyncHandler;
  public function setAsyncHandler(TClientAsyncHandler $handler): this;
}


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package thrift
 */

/**
 * Base interface for Thrift service handlers/clients
 */
interface IThriftIf {
}


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package thrift
 */

/**
 * Base interface for Thrift processors
 */
interface IThriftProcessor {
  public function getEventHandler(): TProcessorEventHandler;
  public function setEventHandler(TProcessorEventHandler $handler): this;
  public function process(TProtocol $input, TProtocol $output): bool;
}


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package thrift
 */

/**
 * Interface for Thrift structs that support conversions to shapes
 */
interface IThriftShapishStruct extends IThriftStruct {
  abstract const type TShape;

  public function __toShape(): this::TShape;
  public static function __fromShape(this::TShape $shape): this;

  public static function __jsonArrayToShape(
    array<arraykey, mixed> $json_data,
  ): ?this::TShape;
}


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package thrift
 */

/**
 * Base interface for Thrift structs
 */
<<__ConsistentConstruct>>
interface IThriftStruct extends \HH\IMemoizeParam {
  const type TFieldSpec = \ThriftStructTypes::TFieldSpec;
  const type TElemSpec = \ThriftStructTypes::TElemSpec;
  const type TGenericSpec = \ThriftStructTypes::TGenericSpec;

  abstract const dict<int, this::TFieldSpec> SPEC;
  abstract const dict<string, int> FIELDMAP;
  abstract const varray<IThriftStruct> ANNOTATIONS;
  abstract const int STRUCTURAL_ID;

  <<__Rx>>
  public function __construct();
  <<__Rx>>
  public function fromShape();
  public function getName(): string;
  public function read(TProtocol $input): int;
  public function write(TProtocol $input): int;
  public static function getAllStructuredAnnotations(): \TStructAnnotations;
}


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package thrift
 */

interface IThriftSyncIf extends IThriftIf {
}


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package thrift
 */

/**
 * Base interface for Thrift unions
 */
interface IThriftUnion<T> extends IThriftStruct {
  public function getType(): T;
}


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package thrift
 */

type TStructFieldAnnotations = shape(
  'field' => dict<string, \IThriftStruct>,
  'type' => dict<string, \IThriftStruct>,
);

type TStructAnnotations = shape(
  'struct' => dict<string, \IThriftStruct>,
  'fields' => dict<string, TStructFieldAnnotations>,
);

type TServiceAnnotations = shape(
  'service' => dict<string, \IThriftStruct>,
  'functions' => dict<string, dict<string, \IThriftStruct>>,
);

type TEnumAnnotations = shape(
  'enum' => dict<string, \IThriftStruct>,
  'constants' => dict<string, dict<string, \IThriftStruct>>,
);

interface IThriftServiceStaticMetadata {
  public static function getAllStructuredAnnotations(): \TServiceAnnotations;
}

interface IThriftEnumStaticMetadata {
  public static function getAllStructuredAnnotations(): \TEnumAnnotations;
}

interface IThriftConstants {
  public static function getAllStructuredAnnotations(
  ): dict<string, dict<string, \IThriftStruct>>;
}

interface IThriftExceptionMetadata {
  public static function getExceptionMetadata()[]: \tmeta_ThriftException;
}

interface IThriftStructMetadata {
  public static function getStructMetadata()[]: \tmeta_ThriftStruct;
}


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package thrift
 */

class TApplicationException extends TException {
  static array<int, array<string, mixed>>
    $_TSPEC = array(
      1 => array('var' => 'message', 'type' => TType::STRING),
      2 => array('var' => 'code', 'type' => TType::I32),
    );

  const UNKNOWN = 0;
  const UNKNOWN_METHOD = 1;
  const INVALID_MESSAGE_TYPE = 2;
  const WRONG_METHOD_NAME = 3;
  const BAD_SEQUENCE_ID = 4;
  const MISSING_RESULT = 5;
  const INVALID_TRANSFORM = 6;

  public function __construct(?string $message = null, int $code = 0) {
    parent::__construct($message, $code);
  }

  public function read(TProtocol $output) {
    return $this->_read('TApplicationException', self::$_TSPEC, $output);
  }

  public function write(TProtocol $output): int {
    $xfer = 0;
    $xfer += $output->writeStructBegin('TApplicationException');
    if ($message = $this->getMessage()) {
      $xfer += $output->writeFieldBegin('message', TType::STRING, 1);
      $xfer += $output->writeString($message);
      $xfer += $output->writeFieldEnd();
    }
    if ($code = $this->getCode()) {
      $xfer += $output->writeFieldBegin('type', TType::I32, 2);
      $xfer += $output->writeI32($code);
      $xfer += $output->writeFieldEnd();
    }
    $xfer += $output->writeFieldStop();
    $xfer += $output->writeStructEnd();
    return $xfer;
  }
}


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package thrift
 */

/**
 * Base class from which other Thrift structs extend. This is so that we can
 * cut back on the size of the generated code which is turning out to have a
 * nontrivial cost just to load thanks to the wondrously abysmal implementation
 * of PHP. Note that code is intentionally duplicated in here to avoid making
 * function calls for every field or member of a container.
 */
abstract class TBase {

  static
    $tmethod = array(
      TType::BOOL => 'Bool',
      TType::BYTE => 'Byte',
      TType::I16 => 'I16',
      TType::I32 => 'I32',
      TType::I64 => 'I64',
      TType::DOUBLE => 'Double',
      TType::STRING => 'String',
      TType::FLOAT => 'Float',
    );

  public abstract function read(TProtocol $input);

  public abstract function write(TProtocol $output);

  public function __construct($spec = null, $vals = null) {
    if (is_array($spec) && is_array($vals)) {
      foreach ($spec as $fid => $fspec) {
        $var = $fspec['var'];
        if (isset($vals[$var])) {
          $this->$var = $vals[$var];
        }
      }
    }
  }

  private function _readMap(&$var, $spec, $input) {
    $xfer = 0;
    $ktype = $spec['ktype'];
    $vtype = $spec['vtype'];
    $kread = $vread = null;
    $kspec = array();
    $vspec = array();
    if (isset(TBase::$tmethod[$ktype])) {
      $kread = 'read'.TBase::$tmethod[$ktype];
    } else {
      $kspec = $spec['key'];
    }
    if (isset(TBase::$tmethod[$vtype])) {
      $vread = 'read'.TBase::$tmethod[$vtype];
    } else {
      $vspec = $spec['val'];
    }
    $var = array();
    $_ktype = 0;
    $_vtype = 0;
    $size = 0;
    $xfer += $input->readMapBegin(inout $_ktype, inout $_vtype, inout $size);
    for ($i = 0; $i < $size; ++$i) {
      $key = $val = null;
      if ($kread !== null) {
        $xfer += $input->$kread($key);
      } else {
        switch ($ktype) {
          case TType::STRUCT:
            $class = $kspec['class'];
            $key = new $class();
            $xfer += $key->read($input);
            break;
          case TType::MAP:
            $xfer += $this->_readMap($key, $kspec, $input);
            break;
          case TType::LST:
            $xfer += $this->_readList($key, $kspec, $input, false);
            break;
          case TType::SET:
            $xfer += $this->_readList($key, $kspec, $input, true);
            break;
        }
      }
      if ($vread !== null) {
        $xfer += $input->$vread($val);
      } else {
        switch ($vtype) {
          case TType::STRUCT:
            $class = $vspec['class'];
            $val = new $class();
            $xfer += $val->read($input);
            break;
          case TType::MAP:
            $xfer += $this->_readMap($val, $vspec, $input);
            break;
          case TType::LST:
            $xfer += $this->_readList($val, $vspec, $input, false);
            break;
          case TType::SET:
            $xfer += $this->_readList($val, $vspec, $input, true);
            break;
        }
      }
      $var[$key] = $val;
    }
    $xfer += $input->readMapEnd();
    return $xfer;
  }

  private function _readList(&$var, $spec, $input, $set = false) {
    $xfer = 0;
    $etype = $spec['etype'];
    $eread = $vread = null;
    if (isset(TBase::$tmethod[$etype])) {
      $eread = 'read'.TBase::$tmethod[$etype];
    } else {
      $espec = $spec['elem'];
    }
    /* UNSAFE_EXPR - this array is used both as vector and a map */
    $var = array();
    $_etype = $size = 0;
    if ($set) {
      $xfer += $input->readSetBegin($_etype, $size);
    } else {
      $xfer += $input->readListBegin($_etype, $size);
    }
    for ($i = 0; $i < $size; ++$i) {
      $elem = null;
      if ($eread !== null) {
        $xfer += $input->$eread($elem);
      } else {
        $espec = $spec['elem'];
        switch ($etype) {
          case TType::STRUCT:
            $class = $espec['class'];
            $elem = new $class();
            $xfer += $elem->read($input);
            break;
          case TType::MAP:
            $xfer += $this->_readMap($elem, $espec, $input);
            break;
          case TType::LST:
            $xfer += $this->_readList($elem, $espec, $input, false);
            break;
          case TType::SET:
            $xfer += $this->_readList($elem, $espec, $input, true);
            break;
        }
      }
      if ($set) {
        $var[$elem] = true;
      } else {
        $var[] = $elem;
      }
    }
    if ($set) {
      $xfer += $input->readSetEnd();
    } else {
      $xfer += $input->readListEnd();
    }
    return $xfer;
  }

  protected function _read($class, $spec, $input) {
    $xfer = 0;
    $fname = null;
    $ftype = 0;
    $fid = 0;
    $xfer += $input->readStructBegin(inout $fname);
    while (true) {
      $xfer += $input->readFieldBegin(inout $fname, inout $ftype, inout $fid);
      if ($ftype == TType::STOP) {
        break;
      }
      if (isset($spec[$fid])) {
        $fspec = $spec[$fid];
        $var = $fspec['var'];
        if ($ftype == $fspec['type']) {
          $xfer = 0;
          if (isset(TBase::$tmethod[$ftype])) {
            $func = 'read'.TBase::$tmethod[$ftype];
            $xfer += $input->$func($this->$var);
          } else {
            switch ($ftype) {
              case TType::STRUCT:
                $class = $fspec['class'];
                $this->$var = new $class();
                $xfer += $this->$var->read($input);
                break;
              case TType::MAP:
                $xfer += $this->_readMap($this->$var, $fspec, $input);
                break;
              case TType::LST:
                $xfer +=
                  $this->_readList($this->$var, $fspec, $input, false);
                break;
              case TType::SET:
                $xfer +=
                  $this->_readList($this->$var, $fspec, $input, true);
                break;
            }
          }
        } else {
          $xfer += $input->skip($ftype);
        }
      } else {
        $xfer += $input->skip($ftype);
      }
      $xfer += $input->readFieldEnd();
    }
    $xfer += $input->readStructEnd();
    return $xfer;
  }

  private function _writeMap($var, $spec, $output) {
    $xfer = 0;
    $ktype = $spec['ktype'];
    $vtype = $spec['vtype'];
    $kwrite = $vwrite = null;
    $kspec = null;
    $vspec = null;
    if (isset(TBase::$tmethod[$ktype])) {
      $kwrite = 'write'.TBase::$tmethod[$ktype];
    } else {
      $kspec = $spec['key'];
    }
    if (isset(TBase::$tmethod[$vtype])) {
      $vwrite = 'write'.TBase::$tmethod[$vtype];
    } else {
      $vspec = $spec['val'];
    }
    $xfer += $output->writeMapBegin($ktype, $vtype, count($var));
    foreach ($var as $key => $val) {
      if (isset($kwrite)) {
        $xfer += $output->$kwrite($key);
      } else {
        switch ($ktype) {
          case TType::STRUCT:
            $xfer += $key->write($output);
            break;
          case TType::MAP:
            $xfer += $this->_writeMap($key, $kspec, $output);
            break;
          case TType::LST:
            $xfer += $this->_writeList($key, $kspec, $output, false);
            break;
          case TType::SET:
            $xfer += $this->_writeList($key, $kspec, $output, true);
            break;
        }
      }
      if (isset($vwrite)) {
        $xfer += $output->$vwrite($val);
      } else {
        switch ($vtype) {
          case TType::STRUCT:
            $xfer += $val->write($output);
            break;
          case TType::MAP:
            $xfer += $this->_writeMap($val, $vspec, $output);
            break;
          case TType::LST:
            $xfer += $this->_writeList($val, $vspec, $output, false);
            break;
          case TType::SET:
            $xfer += $this->_writeList($val, $vspec, $output, true);
            break;
        }
      }
    }
    $xfer += $output->writeMapEnd();
    return $xfer;
  }

  private function _writeList($var, $spec, $output, $set = false) {
    $xfer = 0;
    $etype = $spec['etype'];
    $ewrite = null;
    $espec = null;
    if (isset(TBase::$tmethod[$etype])) {
      $ewrite = 'write'.TBase::$tmethod[$etype];
    } else {
      $espec = $spec['elem'];
    }
    if ($set) {
      $xfer += $output->writeSetBegin($etype, count($var));
    } else {
      $xfer += $output->writeListBegin($etype, count($var));
    }
    foreach ($var as $key => $val) {
      $elem = $set ? $key : $val;
      if (isset($ewrite)) {
        $xfer += $output->$ewrite($elem);
      } else {
        switch ($etype) {
          case TType::STRUCT:
            $xfer += $elem->write($output);
            break;
          case TType::MAP:
            $xfer += $this->_writeMap($elem, $espec, $output);
            break;
          case TType::LST:
            $xfer += $this->_writeList($elem, $espec, $output, false);
            break;
          case TType::SET:
            $xfer += $this->_writeList($elem, $espec, $output, true);
            break;
        }
      }
    }
    if ($set) {
      $xfer += $output->writeSetEnd();
    } else {
      $xfer += $output->writeListEnd();
    }
    return $xfer;
  }

  protected function _write($class, $spec, $output) {
    $xfer = 0;
    $xfer += $output->writeStructBegin($class);
    foreach ($spec as $fid => $fspec) {
      $var = $fspec['var'];
      if ($this->$var !== null) {
        $ftype = $fspec['type'];
        $xfer += $output->writeFieldBegin($var, $ftype, $fid);
        if (isset(TBase::$tmethod[$ftype])) {
          $func = 'write'.TBase::$tmethod[$ftype];
          $xfer += $output->$func($this->$var);
        } else {
          switch ($ftype) {
            case TType::STRUCT:
              $xfer += $this->$var->write($output);
              break;
            case TType::MAP:
              $xfer += $this->_writeMap($this->$var, $fspec, $output);
              break;
            case TType::LST:
              $xfer +=
                $this->_writeList($this->$var, $fspec, $output, false);
              break;
            case TType::SET:
              $xfer +=
                $this->_writeList($this->$var, $fspec, $output, true);
              break;
          }
        }
        $xfer += $output->writeFieldEnd();
      }
    }
    $xfer += $output->writeFieldStop();
    $xfer += $output->writeStructEnd();
    return $xfer;
  }
}


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package thrift
 */

/**
 * This allows clients to perform calls as generators
 */
class TClientAsyncHandler {
  // Called before send in gen_methodName() calls
  public async function genBefore(): Awaitable<void> {
    // Do nothing
  }

  // Called between the send and recv for gen_methodName() calls
  public async function genWait(int $sequence_id): Awaitable<void> {
    // Do nothing
  }

  // Called after recv in gen_methodName() calls
  public async function genAfter(): Awaitable<void> {
    // Do nothing
  }
}


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package thrift
 */

/**
 * Event handler for thrift clients
 */
class TClientEventHandler {
  public function setClient(IThriftClient $client): void {}
  // Called before the request is sent to the server
  public function preSend(
    string $fn_name,
    mixed $args,
    int $sequence_id,
  ): void {}

  // Called after the request is sent to the server
  public function postSend(
    string $fn_name,
    mixed $args,
    int $sequence_id,
  ): void {}

  // Called if there is an exception writing the data
  public function sendError(
    string $fn_name,
    mixed $args,
    int $sequence_id,
    Exception $ex,
  ): void {}

  // Called before the response is read from the server
  // Exceptions thrown here are caught by clientException and clientError.
  public function preRecv(string $fn_name, ?int $ex_sequence_id): void {}

  // Called after the response is read from the server
  public function postRecv(
    string $fn_name,
    ?int $ex_sequence_id,
    mixed $result,
  ): void {}

  // Called if (and only if) the client threw an expected $exception.
  public function recvException(
    string $fn_name,
    ?int $ex_sequence_id,
    TException $exception,
  ): void {}

  // Called if (and only if) the client threw an unexpected $exception.
  public function recvError(
    string $fn_name,
    ?int $ex_sequence_id,
    Exception $exception,
  ): void {}
}


<?hh
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package thrift
 */

final class TClientMultiEventHandler extends TClientEventHandler {
  private Map<string, TClientEventHandler> $handlers;

  public function __construct() {
    $this->handlers = Map {};
  }

  public function addHandler(string $key, TClientEventHandler $handler): this {
    $this->handlers[$key] = $handler;
    return $this;
  }

  public function getHandler(string $key): TClientEventHandler {
    return $this->handlers[$key];
  }

  public function removeHandler(string $key): TClientEventHandler {
    $handler = $this->getHandler($key);
    $this->handlers->remove($key);
    return $handler;
  }

  public function preSend(
    string $fn_name,
    mixed $args,
    int $sequence_id,
  ): void {
    foreach ($this->handlers as $handler) {
      $handler->preSend($fn_name, $args, $sequence_id);
    }
  }

  public function postSend(
    string $fn_name,
    mixed $args,
    int $sequence_id,
  ): void {
    foreach ($this->handlers as $handler) {
      $handler->postSend($fn_name, $args, $sequence_id);
    }
  }

  public function sendError(
    string $fn_name,
    mixed $args,
    int $sequence_id,
    Exception $ex,
  ): void {
    foreach ($this->handlers as $handler) {
      $handler->sendError($fn_name, $args, $sequence_id, $ex);
    }
  }

  public function preRecv(string $fn_name, ?int $ex_sequence_id): void {
    foreach ($this->handlers as $handler) {
      $handler->preRecv($fn_name, $ex_sequence_id);
    }
  }

  public function postRecv(
    string $fn_name,
    ?int $ex_sequence_id,
    mixed $result,
  ): void {
    foreach ($this->handlers as $handler) {
      $handler->postRecv($fn_name, $ex_sequence_id, $result);
    }
  }

  public function recvException(
    string $fn_name,
    ?int $ex_sequence_id,
    TException $exception,
  ): void {
    foreach ($this->handlers as $handler) {
      $handler->recvException($fn_name, $ex_sequence_id, $exception);
    }
  }

  public function recvError(
    string $fn_name,
    ?int $ex_sequence_id,
    Exception $exception,
  ): void {
    foreach ($this->handlers as $handler) {
      $handler->recvError($fn_name, $ex_sequence_id, $exception);
    }
  }
}