Skip to content

Dynamic schema loading via loadSchemaHandler callback #95

Description

@ekrich

EXIP supports dynamic loading of schema imports/includes through an optional callback. We could add a function to utils.

Default behavior (exipd/exipe/exipg): All schemas must be listed on command line with -schema=. The loadSchemaHandler parameter is NULL, so any import/include not already loaded returns the error above.

Callback signature:

errorCode loadSchemaHandler(String* namespace, 
                            String* schemaLocation,
                            BinaryBuffer** buffers,
                            unsigned int* bufCount,
                            SchemaFormat* schemaFormat,
                            EXIOptions** opt);

How it works:

Library parses schema, encounters or
Checks if schema already loaded (by namespace)
If not found and callback provided, calls it with namespace/schemaLocation
Callback must allocate BinaryBuffer array, load file(s), return buffers and count
Library recursively processes newly loaded schemas
Example implementation using existing schemaLoader utilities:

errorCode dynamicSchemaLoader(String* ns, String* location, 
                              BinaryBuffer** buffers, unsigned int* bufCount,
                              SchemaFormat* format, EXIOptions** opt) {
    // Convert String to C string
    char filename[FILENAME_MAX];
    memcpy(filename, location->str, location->length);
    filename[location->length] = '\0';
    
    // Allocate buffer array
    *buffers = malloc(sizeof(BinaryBuffer));
    if (!*buffers) return EXIP_MEMORY_ALLOCATION_ERROR;
    *bufCount = 1;
    
    // Use existing schemaLoader function
    errorCode err = loadSchemaFile(filename, &(*buffers)[0]);
    
    // Set format and options
    *format = SCHEMA_FORMAT_XSD_EXI;
    *opt = NULL;
    
    return err;
}

// Use in exipd:
generateSchemaInformedGrammars(buffer, count, SCHEMA_FORMAT_XSD_EXI, 
                               NULL, schema, dynamicSchemaLoader);

Use case: Load only main schema upfront, dynamically discover and load dependencies as referenced. Enables "lazy loading" of schema files.

Note: API Improvement: Pass parent format/options to callback

Current issue: The loadSchemaHandler callback must output schemaFormat and opt but has no visibility into what format/options the parent schemas used. Callbacks currently hardcode SCHEMA_FORMAT_XSD_EXI and NULL.

Root cause: generateOptimizedTreeTable receives schemaFormat and opt parameters but doesn't pass them to resolveIncludeImportReferences, so they're unavailable when the callback is invoked.

Suggested fix: Thread format/options through the call chain:

// Add to resolveIncludeImportReferences signature
errorCode resolveIncludeImportReferences(EXIPSchema* schema, TreeTable** treeT, 
                                         unsigned int* count,
                                         SchemaFormat parentFormat,    // ← ADD
                                         EXIOptions* parentOpt,        // ← ADD
                                         errorCode (*loadSchemaHandler)(...));

// Callback can then use parent values as defaults
errorCode dynamicSchemaLoader(...) {
    // ... load file ...
    *format = parentFormat;  // Use same format as parent
    *opt = parentOpt;        // Use same options as parent
    return err;
}

Benefit: Callbacks don't need to guess or hardcode format/options; they inherit from parent context.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions