Fork Me On GitLab

Providence has some extra features that not only does not work in standard thrift, it will break thrift syntax, or the thrift compiler in some way.

Interfaces

Thrift does not have the concept of interfaces, but providences does. Interfaces are declared as any other struct is, but does not support assigning field IDS.

Interfaces has two main uses, being implemented by a struct, and used by a union for generality. E.g.:

```thrift idl interface Person { required string name; }

struct Employee implements Person { 1: required string name; 2: required i32 employee_id; 3: optional double salary; }

struct Customer implements Person { 1: required i32 customer_id; 2: required string name; 3: optional i32 purchases; }

union Entity of Person { 1: optional Employee employee; 2: optional Customer customer; }


This contains two struct each implementing the Person interface.
Note that the two uses a different field ID for the required 'name'
field. The interface type will generate an interface or abstract class
in the languages that support this, and essentially only be validated
as having common fields otherwise. This will generate:

- The `Person` interface with the common `getName()` and `hasName()`
  methods.
- The `Employee` and `Customer` message classes will inherit or extend
  the `Person` interface. This is equivalent to the `java.implements`
  annotation, but is completely encompassed in providence.
- The `Entity` union has more edits. It will have an `asPerson()` method
  that returns the current union field as the `Person` interface. And it
  will mirror all the methods of `Person` (that it itself implements) and
  forward these calls to the current union value. Note that a `union .. of`
  requires that **all** fields implements the given interface.

## Circular Containment

This feature is not explicitly supported or not in thrift, but does not
work well in Apache Thrift, meaning that a single struct may contain a
field of it's own type, but you may not have two structs each containing
the other. This is simply a result of the way Apache Thrift parses the
thrift file.

In `providence` you may have circular containment if (and only if) all
of the types referring to each other is in the same thrift definition
file. E.g.:

- struct A contains struct B contains struct A.

```thrift
namespace java net.morimekta.test.calculator

enum Operator {
    IDENTITY = 1,
    ADD,
    SUBTRACT,
    MULTIPLY,
    DIVIDE
}

union Operand {
    1: Operation operation;
    2: double number;
}

struct Operation {
    1: Operator operator;
    2: list<Operand> operands;
}

This makes model structures like the calculator possible. Since the model objects are immutable and created with builders, it is not possible to create a circular instance containment.

Service Sub Methods

Services also support service stub methods, which are declared in a similar fashion to protobuf, meaning it will only be declared with a request and response struct (both must be structs), and no individual parameter fields.

```thrift idl struct MyRequest { 1: optional string request_field; }

struct MyResponse { 1: optional string response_field; }

service MyService { MyResponse myMethod(MyRequest); }


This is structurally equivalent to declare the request struct's fields
as the method parameters, but may generate different interfaces for
using it:

```thrift idl
struct MyResponse {
    1: optional string response_field;
}

service MyService {
    MyResponse myMethod(1: optional string request_field);
}