def get_schema(message_descriptor):
    """Builds the table schema for a Message.

    Args:
        message_descriptor: google.protobuf.descriptor.Descriptor.

    Returns:
        List of dictionaries containing schema information.

    Raises:
        NotImplementedError: If a FieldDescriptor type is not supported.
    """
    schema = []
    for field in message_descriptor.fields:
        if field.label == field.LABEL_REPEATED:
            mode = 'REPEATED'
        else:
            mode = 'NULLABLE'  # All fields are optional.
        if field.type == field.TYPE_BOOL:
            schema.append({'name': field.name, 'type': 'BOOL', 'mode': mode})
        elif field.type == field.TYPE_FLOAT:
            schema.append({'name': field.name, 'type': 'FLOAT64', 'mode': mode})
        elif field.type in [field.TYPE_INT32, field.TYPE_INT64]:
            schema.append({'name': field.name, 'type': 'INT64', 'mode': mode})
        elif field.type == field.TYPE_STRING:
            schema.append({'name': field.name, 'type': 'STRING', 'mode': mode})
        elif field.type == field.TYPE_BYTES:
            schema.append({'name': field.name, 'type': 'BYTES', 'mode': mode})
        elif field.type == field.TYPE_ENUM:
            schema.append({'name': field.name, 'type': 'STRING', 'mode': mode})
        elif field.type == field.TYPE_MESSAGE:
            schema.append({
                'name': field.name,
                'type': 'RECORD',
                'mode': mode,
                'fields': get_schema(field.message_type)
            })
        else:
            raise NotImplementedError(f'unsupported type: {field.type}')
    return schema