Skip to content

Migrate Avro integration to IR extension architecture#680

Merged
wilmveel merged 3 commits into
masterfrom
claude/laughing-tesla-lqcoug
Jun 20, 2026
Merged

Migrate Avro integration to IR extension architecture#680
wilmveel merged 3 commits into
masterfrom
claude/laughing-tesla-lqcoug

Conversation

@wilmveel

Copy link
Copy Markdown
Contributor

Description

Refactors the Avro integration from standalone emitters (AvroJavaEmitter, AvroKotlinEmitter) to a unified IrExtension that works with both Java and Kotlin IR emitters. This aligns with the Wirespec IR pipeline architecture and simplifies configuration.

Key Changes

  • Removed: Language-specific emitter classes

    • src/integration/avro/src/jvmMain/kotlin/community/flock/wirespec/integration/avro/java/emit/AvroEmitter.kt
    • src/integration/avro/src/jvmMain/kotlin/community/flock/wirespec/integration/avro/kotlin/emit/AvroEmitter.kt
    • Associated test files (AvroJavaEmitterTest.kt, AvroKotlinEmitterTest.kt)
  • Added: Unified IR extension

    • AvroExtension class that implements IrExtension and detects the target language (Java/Kotlin) from the IR
    • Language-specific Avro source generators (JavaAvroSource, KotlinAvroSource) that produce <Type>Avro converter classes
    • AvroExtensionTest with comprehensive test coverage for both Java and Kotlin output
  • Updated: Documentation and examples

    • Updated Maven and Gradle plugin configuration examples to use IR mode with extensionClasses
    • Updated maven-spring-avro example to demonstrate the new IR-based approach
    • Updated architecture documentation to reflect the extension pattern

How It Works

The AvroExtension registers on a Java or Kotlin IrEmitter running in IR mode. It:

  1. Detects the target language by inspecting the IR for language-specific package imports
  2. For each Type and Enum definition, generates a corresponding <Type>Avro class in the <package>.avro sub-package
  3. Produces Avro schema parsing and conversion methods (record ↔ model, enum ↔ model)

This approach eliminates the need for separate emitter classes and allows a single extension to support multiple languages through language detection.

Type of Change

  • Refactoring
  • Feature (IR extension architecture)

Checklist

  • I have followed the contribution guidelines
  • I have written tests for my changes (AvroExtensionTest covers Java and Kotlin)
  • I have updated the documentation (Maven/Gradle examples and architecture docs)
  • I have written code in a functional style using Arrow where appropriate

Breaking Changes

Configuration Migration Required: Projects using the old Avro emitters must update their plugin configuration:

Before (Maven):

<emitterClass>community.flock.wirespec.integration.avro.java.emit.AvroJavaEmitter</emitterClass>

After (Maven):

<languages>
    <language>Java</language>
</languages>
<ir>true</ir>
<extensionClasses>
    <extensionClass>community.flock.wirespec.integration.avro.extension.AvroExtension</extensionClass>
</extensionClasses>

Similar changes apply to Gradle configurations (see updated examples).

https://claude.ai/code/session_01SsK267uB3Ybm7UNXLT4aLs

claude added 3 commits June 19, 2026 20:45
…e (IR mode)

Replace the Java/Kotlin Avro LanguageEmitters with one AvroExtension
(IrExtension) that appends an <Type>Avro schema/converter file per record
and enum. It detects the target language from the IR and renders Java or
Kotlin source accordingly, reusing the existing emitter rendering helpers.

Wire the maven-spring-avro example to run the Java IR emitter in IR mode
with the extension (languages/ir/extensionClasses), and update the example
service/test to the new Sender channel API. Update the Avro integration and
plugin-architecture docs to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SsK267uB3Ybm7UNXLT4aLs
… templates

Replace the per-language multi-line code templates in AvroExtension with the IR
DSL: the file/package/import/namespace and from/to method structure is now built
from IR nodes (file, namespace, function, ConstructorStatement, assign, returns)
and rendered idiomatically by the Java and Kotlin generators (Java interface with
static methods; Kotlin object). Only the irreducibly language-specific leaves stay
as code strings: the SCHEMA field initializer, the record constructor, and the
per-field conversion expressions (casts, streams vs map, byte handling).

Update the extension unit-test fixtures to the regenerated output.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SsK267uB3Ybm7UNXLT4aLs
…Listener

- JavaIrTransformer: keep the fully-qualified channel reference as a single Name
  part so `Name.of` no longer splits it on dots and pascalCases the segments
  (com.example.model.Foo -> ComExampleModelFoo), which broke the generated channel
  Sender/Listener signatures and the maven-spring-avro example compile.
- AvroExtension: select the Java/Kotlin source from a `language: FileExtension`
  constructor parameter (mirrors SpringNativeHintsExtension) instead of sniffing
  the IR. Maven and Gradle plugins inject the emitter's FileExtension per language.
- maven-spring-avro example: AvroExampleService now implements both
  TestAvroRecord.Sender and TestAvroRecord.Listener.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SsK267uB3Ybm7UNXLT4aLs
@wilmveel wilmveel merged commit decac52 into master Jun 20, 2026
34 checks passed
@wilmveel wilmveel deleted the claude/laughing-tesla-lqcoug branch June 20, 2026 09:29
@sonarqubecloud

Copy link
Copy Markdown

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.

2 participants