Skip to content

Conversation

@tsanders-rh
Copy link
Owner

Summary

Fixes konveyor#973 by adding automatic conversion of typed slices (e.g., []string, []int) to []interface{} for protobuf compatibility in the gRPC provider.

Problem

The gRPC provider failed when processing provider configurations with typed slices because structpb.NewStruct() only accepts []interface{}. This forced callers to manually convert slices, which:

  • Exposed protobuf marshaling internals to users
  • Created error-prone manual type juggling
  • Impacted multiple projects (kantra, Kai, other analyzer-lsp consumers)

Example that previously failed:

config := map[string]interface{}{
    "includedPaths": []string{"/path1", "/path2"},  // Error!
}

Solution

Added reflection-based conversion logic that:

  • Automatically converts typed slices to []interface{} before marshaling
  • Handles nested maps and slices recursively
  • Optimizes to avoid unnecessary allocations (3.4x faster for already-correct types)
  • Maintains full backward compatibility

Changes

  1. provider/grpc/provider.go - Added conversion functions and applied in Init() method
  2. provider/grpc/dependency_resolver_client.go - Applied conversion in GetLocation() method
  3. provider/grpc/provider_test.go - Added 57 comprehensive test cases

Testing

  • ✅ All 57 new tests pass
  • ✅ Existing tests continue to pass
  • ✅ Integration tests verify structpb.NewStruct() compatibility
  • ✅ Optimization tests confirm performance improvements

Performance

  • Impact: Negligible (<1 microsecond per conversion)
  • Frequency: Once per provider initialization (not in hot path)
  • Memory: <8KB even for large configs (100+ paths)
  • Optimization: 3.4x faster when no conversion needed

Benefits

  • Users can use natural Go types without manual conversion
  • Cleaner, more maintainable code
  • Reduced error potential
  • Better developer experience

…aling

The gRPC provider previously failed when processing configurations with
typed slices (e.g., []string) because structpb.NewStruct() only accepts
[]interface{}. This forced callers to manually convert slices, exposing
protobuf marshaling internals.

This commit adds automatic conversion logic that:
- Recursively converts typed slices to []interface{} before marshaling
- Handles nested maps and slices transparently
- Optimizes to avoid unnecessary allocations for already-correct types
- Maintains backward compatibility with existing []interface{} usage

The conversion is applied in two locations:
- provider.go:256 - Provider initialization configurations
- dependency_resolver_client.go:19 - Dependency extras processing

Performance impact is negligible (<1 microsecond per conversion) as this
only runs once during provider initialization, not in any hot path.

Fixes konveyor#973

Signed-off-by: tsanders <[email protected]>
@tsanders-rh
Copy link
Owner Author

Closing - will create PR on upstream konveyor/analyzer-lsp instead

tsanders-rh added a commit that referenced this pull request Nov 20, 2025
Extends import detection to handle all valid JavaScript/TypeScript patterns:
- Namespace imports: import * as Pattern from "package"
- Mixed default + named: import React, { useState } from "react"
- Mixed default + namespace: import React, * as All from "react"
- TypeScript type imports: import type { Card } from "package"

Updated regex pattern with 5 capture groups:
1. Default import (when mixed with named/namespace)
2. Named imports (braced list)
3. Default import (when standalone)
4. Namespace import
5. Package name

The regex now includes optional "type" keyword support for TypeScript
type-only imports, ensuring comprehensive coverage of modern JavaScript
and TypeScript import patterns.

Pattern matching logic updated to:
- Check all three import types (default, named, namespace)
- Use exact match for single identifiers (default, namespace)
- Use substring match for comma-separated lists (named imports)
- Added inline comments explaining matching strategy

Test coverage (25 test cases):
- Namespace imports (single line, multiline, multiple per file)
- Mixed default + named imports (both parts searchable, multiline)
- Mixed default + namespace imports (rare but valid)
- TypeScript type imports (named, default, namespace, multiline)
- Side-effect imports (correctly ignored)
- Word boundaries (avoid partial matches like "Card" vs "CardHelper")
- Special characters in package names (@scoped/packages)
- Stress test with 20 named imports in single statement
- Pattern not found scenarios

All 25 tests passing. Build successful.

Addresses code review feedback item #1.

Signed-off-by: tsanders <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gRPC provider should handle typed slice conversion for protobuf marshaling

2 participants