// 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,

    // Add any new type above this value.
    MaxBaseType
}

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];
    optional:bool = false;
}

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];
}

// New schema language features that are not supported by old code generators.
enum AdvancedFeatures : ulong (bit_flags) {
    AdvancedArrayFeatures,
    AdvancedUnionFeatures,
    OptionalScalars,
    DefaultVectorsAndStrings,
}

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

root_type Schema;

file_identifier "BFBS";
file_extension "bfbs";
