vlingo / xoom-schemata

The VLINGO XOOM Schema Registry.
https://vlingo.io
Mozilla Public License 2.0
17 stars 9 forks source link

Fix schema definitons with complex type references #192

Closed jakzal closed 3 years ago

jakzal commented 3 years ago

Re #183 Replaces #191

jakzal commented 3 years ago

The added test case is an updated example that reproduces the problem reported in #183, but matches schemata docs:

https://github.com/vlingo/xoom-schemata/blob/d457d9a4c9f414cdf6100efeb8361477344049e0/src/test/java/io/vlingo/xoom/schemata/codegen/specs/CodeGenSpecs.java#L101-L113

https://github.com/vlingo/xoom-schemata/blob/d457d9a4c9f414cdf6100efeb8361477344049e0/src/test/resources/io/vlingo/xoom/schemata/codegen/vss/veterinarian-registered.vss#L1-L7

https://github.com/vlingo/xoom-schemata/blob/d457d9a4c9f414cdf6100efeb8361477344049e0/src/test/resources/text-expectations/java/veterinarian-registered.text#L7-L25

The test is failing with:

Parsing failed for schema: xoom:apps:io.vlingo.xoom.examples.petclinic:VeterinarianRegistered
Error [4,2]: mismatched input 'data' expecting {'boolean', 'byte', 'char', 'double', 'float', 'int', 'long', 'short', 'string', 'timestamp', 'type', 'version', '=', '}', TYPE_IDENTIFIER}null

org.antlr.v4.runtime.DefaultErrorStrategy.recoverInline(DefaultErrorStrategy.java:485)
org.antlr.v4.runtime.Parser.match(Parser.java:206)
io.vlingo.xoom.schemata.codegen.antlr.SchemaVersionDefinitionParser.typeBody(SchemaVersionDefinitionParser.java:276)
io.vlingo.xoom.schemata.codegen.antlr.SchemaVersionDefinitionParser.typeDeclaration(SchemaVersionDefinitionParser.java:140)
io.vlingo.xoom.schemata.codegen.parser.AntlrTypeParser.parseTypeDefinition(AntlrTypeParser.java:60)
io.vlingo.xoom.schemata.codegen.TypeDefinitionCompilerActor.compile(TypeDefinitionCompilerActor.java:36)
io.vlingo.xoom.schemata.codegen.CodeGenTests.compileSpecAndUnwrap(CodeGenTests.java:88)
io.vlingo.xoom.schemata.codegen.CodeGenTests.compileSpecAndUnwrap(CodeGenTests.java:81)
io.vlingo.xoom.schemata.codegen.specs.CodeGenSpecs.testThatGeneratesTypeWithReferencesToComplexTypes(CodeGenSpecs.java:110)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
org.junit.runners.ParentRunner.run(ParentRunner.java:413)
org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:365)
org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:273)
org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:159)
org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:379)
org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:340)
org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:125)
org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:413)
jakzal commented 3 years ago

I updated the parser to handle category type references in complex types:

https://github.com/vlingo/xoom-schemata/blob/e0423f9a446444c25ad672255f27e8ab5e770ebc/src/main/antlr4/io/vlingo/xoom/schemata/codegen/antlr/SchemaVersionDefinitionParser.g4#L33-L35

https://github.com/vlingo/xoom-schemata/blob/e0423f9a446444c25ad672255f27e8ab5e770ebc/src/main/antlr4/io/vlingo/xoom/schemata/codegen/antlr/SchemaVersionDefinitionParser.g4#L68-L71

The test is now failing with an expectation failure:

Expected:

package io.vlingo.xoom.examples.petclinic.event;

import io.vlingo.xoom.lattice.model.DomainEvent;
import java.lang.Object;
import java.lang.String;

public final class VeterinarianRegistered extends DomainEvent {
  public final int semanticVersion;

  public final String id;

  public final FullName name;

  public final ContactInformation contactInformation;

  public final Speciality specialty;

  public VeterinarianRegistered(final String id, final FullName name, final ContactInformation contactInformation, final Speciality specialty) {
    this.semanticVersion = io.vlingo.xoom.common.version.SemanticVersion.toValue("1.0.0");
    this.id = id;
    this.name = name;
    this.contactInformation = contactInformation;
    this.specialty = specialty;
  }
}

Actual:

package io.vlingo.xoom.examples.petclinic.event;

import io.vlingo.xoom.lattice.model.DomainEvent;
import java.lang.String;

public final class VeterinarianRegistered extends DomainEvent {
  public final int semanticVersion;

  public final String id;

  public final Object name;

  public final Object contactInformation;

  public final Object specialty;

  public VeterinarianRegistered(final String id, final Object name, final Object contactInformation, final Object specialty) {
    this.semanticVersion = io.vlingo.xoom.common.version.SemanticVersion.toValue("1.0.0");
    this.id = id;
    this.name = name;
    this.contactInformation = contactInformation;
    this.specialty = specialty;
  }
}

We need to convert category type references to fully qualified type references.

jakzal commented 3 years ago

Currently the TYPE_IDENTIFIER includes the version:

https://github.com/vlingo/xoom-schemata/blob/e0423f9a446444c25ad672255f27e8ab5e770ebc/src/main/antlr4/io/vlingo/xoom/schemata/codegen/antlr/SchemaVersionDefinitionLexer.g4#L128-L130

While it's fine in attribute definitions, I guess the following shouldn't be allowed?

event VeterinarianRegistered:1.0.0 {
  version semanticVersion
  string id
}
VaughnVernon commented 3 years ago

@jakzal True.

jakzal commented 3 years ago

I have now updated the type identifier to only allow for letters and digits:

https://github.com/vlingo/xoom-schemata/blob/e8d14bdd08e66456a4d75e16354a8cfd1bbb0bf8/src/main/antlr4/io/vlingo/xoom/schemata/codegen/antlr/SchemaVersionDefinitionLexer.g4#L128-L130

The complex type attributes can only be made of category type references:

https://github.com/vlingo/xoom-schemata/blob/e8d14bdd08e66456a4d75e16354a8cfd1bbb0bf8/src/main/antlr4/io/vlingo/xoom/schemata/codegen/antlr/SchemaVersionDefinitionParser.g4#L68-L71

Category type references are made of the category and type name:

https://github.com/vlingo/xoom-schemata/blob/e8d14bdd08e66456a4d75e16354a8cfd1bbb0bf8/src/main/antlr4/io/vlingo/xoom/schemata/codegen/antlr/SchemaVersionDefinitionParser.g4#L33-L35

I have changed the test example to use the category type reference instead of the fully qualified type reference:

https://github.com/vlingo/xoom-schemata/blob/e8d14bdd08e66456a4d75e16354a8cfd1bbb0bf8/src/test/resources/io/vlingo/xoom/schemata/codegen/vss/price-changed.vss#L4-L5

Fully qualified type references are no longer supported (support was broken anyway).

danilo-ambrosio commented 3 years ago

@jakzal I tested the schema pull with complex types and noticed that the import statement is not being generated so I got the following compilation failure:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:compile (default-compile) on project game-store: Compilation failure: Compilation failure:
[ERROR] /D:/perfect-game-store/target/generated-sources/vlingo/io/vlingo/gamestore/event/GameRenamed.java:[11,16] cannot find symbol
[ERROR]   symbol:   class Name
[ERROR]   location: class io.vlingo.gamestore.event.GameRenamed
[ERROR] /D:/perfect-game-store/target/generated-sources/vlingo/io/vlingo/gamestore/event/GameRenamed.java:[13,45] cannot find symbol
[ERROR]   symbol:   class Name
[ERROR]   location: class io.vlingo.gamestore.event.GameRenamed

Here's the generated event class that causes the compilation problem once there's no import for io.vlingo.gamestore.data.Name :

package io.vlingo.gamestore.event;

import io.vlingo.xoom.lattice.model.DomainEvent;
import java.lang.String;

public final class GameRenamed extends DomainEvent {
  public final int semanticVersion;

  public final String id;

  public final Name name;

  public GameRenamed(final String id, final Name name) {
    this.semanticVersion = io.vlingo.xoom.common.version.SemanticVersion.toValue("1.0.0");
    this.id = id;
    this.name = name;
  }
}
jakzal commented 3 years ago

Thanks for giving it a try @danilo-ambrosio! I think it's more than a missing import. I'll need to add support for generating classes other than events :)