// This schema defines objects that represent a parsed schema, like
// the binary version of a .fbs file.
// This could be used to operate on unknown FlatBuffers at runtime.
// It can even ... represent itself (!)

namespace reflection;

// These must correspond to the enum in idl.h.
enum BaseType : byte {
    None,
    UType,
    Bool,
    Byte,
    UByte,
    Short,
    UShort,
    Int,
    UInt,
    Long,
    ULong,
    Float,
    Double,
    String,
    Vector,
    Obj,     // Used for tables & structs.
    Union,
    Array
}

table Type {
    base_type:BaseType;
    element:BaseType = None;  // Only if base_type == Vector 
                              // or base_type == Array.
    index:int = -1;  // If base_type == Object, index into "objects" below.
                     // If base_type == Union, UnionType, or integral derived
                     // from an enum, index into "enums" below.
    fixed_length:uint16 = 0;  // Only if base_type == Array.
}

table KeyValue {
    key:string (required, key);
    value:string;
}

table EnumVal {
    name:string (required);
    value:long (key);
    object:Object;  // Will be deprecated in favor of union_type in the future.
    union_type:Type;
    documentation:[string];
}

table Enum {
    name:string (required, key);
    values:[EnumVal] (required);  // In order of their values.
    is_union:bool = false;
    underlying_type:Type (required);
    attributes:[KeyValue];
    documentation:[string];
}

table Field {
    name:string (required, key);
    type:Type (required);
    id:ushort;
    offset:ushort;  // Offset into the vtable for tables, or into the struct.
    default_integer:long = 0;
    default_real:double = 0.0;
    deprecated:bool = false;
    required:bool = false;
    key:bool = false;
    attributes:[KeyValue];
    documentation:[string];
}

table Object {  // Used for both tables and structs.
    name:string (required, key);
    fields:[Field] (required);  // Sorted.
    is_struct:bool = false;
    minalign:int;
    bytesize:int;  // For structs.
    attributes:[KeyValue];
    documentation:[string];
}

table RPCCall {
    name:string (required, key);
    request:Object (required);      // must be a table (not a struct)
    response:Object (required);     // must be a table (not a struct)
    attributes:[KeyValue];
    documentation:[string];
}

table Service {
    name:string (required, key);
    calls:[RPCCall];
    attributes:[KeyValue];
    documentation:[string];
}

table Schema {
    objects:[Object] (required);    // Sorted.
    enums:[Enum] (required);        // Sorted.
    file_ident:string;
    file_ext:string;
    root_table:Object;
    services:[Service];             // Sorted.
}

root_type Schema;

file_identifier "BFBS";
file_extension "bfbs";
