Skip to content

mc-java fails to compile messages that have fields named after Java keywords #19

@yevhenii-nadtochii

Description

@yevhenii-nadtochii

The following message doesn't compile:

message NumericBound {
    oneof value {
        float float = 1;
        double double = 2;
    }
}

float, double and probably other Java keywords are valid Protobuf identifiers. But a Java method cannot be named after a Java keyword (in this example, public io.spine.base.EventMessageField float() is generated). So, the compilation fails.

Log from `lauchProtoData` task
> Task :proto:context:launchProtoData
Mar 18, 2025 3:56:22 PM io.spine.protodata.java.render.MessageAction render
SEVERE:                 Caught exception while applying `CreateNestedClass(type=name {
  simple_name: "RangeFieldDiscovered"
  package_name: "spine.validation"
  type_url_prefix: "type.spine.io"
}
file {
  path: "/Users/yevhenii/Projects/Spine/validation-master/proto/context/src/main/proto/spine/validation/events.proto"
}
field {
  name {
    value: "id"
  }
  type {
    message {
      simple_name: "FieldRef"
      package_name: "spine.protodata"
      type_url_prefix: "type.spine.io"
    }
  }
  declaring_type {
    simple_name: "RangeFieldDiscovered"
    package_name: "spine.validation"
    type_url_prefix: "type.spine.io"
  }
  number: 1
  doc {
  }
  span {
    start_line: 144
    start_column: 5
    end_line: 144
    end_column: 31
  }
}
field {
  name {
    value: "subject"
  }
  type {
    message {
      simple_name: "Field"
      package_name: "spine.protodata"
      type_url_prefix: "type.spine.io"
    }
  }
  declaring_type {
    simple_name: "RangeFieldDiscovered"
    package_name: "spine.validation"
    type_url_prefix: "type.spine.io"
  }
  number: 2
  order_of_declaration: 1
  doc {
    leading_comment: "The field in which the option was discovered."
  }
  span {
    start_line: 147
    start_column: 5
    end_line: 147
    end_column: 33
  }
}
field {
  name {
    value: "error_message"
  }
  type {
    primitive: TYPE_STRING
  }
  declaring_type {
    simple_name: "RangeFieldDiscovered"
    package_name: "spine.validation"
    type_url_prefix: "type.spine.io"
  }
  number: 3
  order_of_declaration: 2
  doc {
    leading_comment: "The error message template."
  }
  span {
    start_line: 150
    start_column: 5
    end_line: 150
    end_column: 30
  }
}
field {
  name {
    value: "range"
  }
  type {
    primitive: TYPE_STRING
  }
  declaring_type {
    simple_name: "RangeFieldDiscovered"
    package_name: "spine.validation"
    type_url_prefix: "type.spine.io"
  }
  number: 4
  order_of_declaration: 3
  doc {
    leading_comment: "The range value."
  }
  span {
    start_line: 153
    start_column: 5
    end_line: 153
    end_column: 22
  }
}
field {
  name {
    value: "lower_bound"
  }
  type {
    message {
      simple_name: "NumericBound"
      package_name: "spine.validation"
      type_url_prefix: "type.spine.io"
    }
  }
  declaring_type {
    simple_name: "RangeFieldDiscovered"
    package_name: "spine.validation"
    type_url_prefix: "type.spine.io"
  }
  number: 5
  order_of_declaration: 4
  doc {
    leading_comment: "The minimum value that a numeric field can have."
  }
  span {
    start_line: 156
    start_column: 5
    end_line: 156
    end_column: 51
  }
}
field {
  name {
    value: "upper_bound"
  }
  type {
    message {
      simple_name: "NumericBound"
      package_name: "spine.validation"
      type_url_prefix: "type.spine.io"
    }
  }
  declaring_type {
    simple_name: "RangeFieldDiscovered"
    package_name: "spine.validation"
    type_url_prefix: "type.spine.io"
  }
  number: 6
  order_of_declaration: 5
  doc {
    leading_comment: "The maximum value that a numeric field can have."
  }
  span {
    start_line: 159
    start_column: 5
    end_line: 159
    end_column: 51
  }
}
doc {
  leading_comment: "The event emitted whenever a field with `(range)` option is discovered\nand has passed the necessary checks to confirm the option is applied correctly."
}
span {
  start_line: 142
  start_column: 1
  end_line: 160
  end_column: 2
}
, file=io/spine/validation/event/RangeFieldDiscovered.java, simpleName="Field")`.
                Message: Incorrect method 'public io.spine.base.EventMessageField float() {
    return new io.spine.base.EventMessageField(getField().nested("float"));                
}  '.                                
com.intellij.util.IncorrectOperationException: Incorrect method 'public io.spine.base.EventMessageField float() {
    return new io.spine.base.EventMessageField(getField().nested("float"));                
}  '
        at com.intellij.psi.impl.PsiJavaParserFacadeImpl.newException(PsiJavaParserFacadeImpl.java:388)
        at com.intellij.psi.impl.PsiJavaParserFacadeImpl.createMethodFromText(PsiJavaParserFacadeImpl.java:184)
        at com.intellij.psi.impl.PsiElementFactoryImpl.createMethodFromText(PsiElementFactoryImpl.java:684)
        at com.intellij.psi.impl.PsiJavaParserFacadeImpl.createMethodFromText(PsiJavaParserFacadeImpl.java:193)
        at io.spine.tools.psi.java.PsiElementFactoryDecorator.createMethodFromText(PsiElementFactoryDecorator.kt:126)
        at io.spine.tools.mc.java.field.FieldAccessor.method$mc_java_base(FieldAccessors.kt:86)
        at io.spine.tools.mc.java.field.MessageTypedField.addFieldMethods(MessageTypedField.kt:140)
        at io.spine.tools.mc.java.field.MessageTypedField.createClass$mc_java_base(MessageTypedField.kt:106)
        at io.spine.tools.mc.java.field.AddFieldClass.addFieldClasses(AddFieldClass.kt:103)
        at io.spine.tools.mc.java.field.AddFieldClass.tuneClass(AddFieldClass.kt:89)
        at io.spine.protodata.java.render.CreateNestedClass.doRender(CreateNestedClass.kt:108)
        at io.spine.protodata.java.render.MessageAction.render(MessageAction.kt:99)
        at io.spine.protodata.java.render.RenderActions.apply(RenderActions.kt:62)
        at io.spine.tools.mc.java.signal.SignalRenderer.doRender$lambda$0(Renderers.kt:64)
        at io.spine.tools.psi.java.PsiCommandsKt.execute$lambda$0(PsiCommands.kt:59)
        at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:219)
        at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:174)
        at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:164)
        at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:150)
        at io.spine.tools.psi.java.PsiCommandsKt.execute(PsiCommands.kt:64)
        at io.spine.tools.psi.java.PsiCommandsKt.execute$default(PsiCommands.kt:55)
        at io.spine.tools.mc.java.signal.SignalRenderer.doRender(Renderers.kt:63)
        at io.spine.protodata.java.render.TypeListRenderer.doRender(TypeListRenderer.kt:63)
        at io.spine.protodata.java.render.AbstractRenderer.render(AbstractRenderer.kt:114)
        at io.spine.protodata.render.Renderer.renderSources(Renderer.kt:51)
        at io.spine.protodata.plugin.PluginKt.render(Plugin.kt:133)
        at io.spine.protodata.backend.Pipeline.renderSources(Pipeline.kt:303)
        at io.spine.protodata.backend.Pipeline.emitEventsAndRenderSources(Pipeline.kt:274)
        at io.spine.protodata.backend.Pipeline.invoke(Pipeline.kt:253)
        at io.spine.protodata.backend.Pipeline.invoke$default(Pipeline.kt:241)
        at io.spine.protodata.cli.app.Run.doRun(Main.kt:137)
        at io.spine.protodata.cli.app.Run.run(Main.kt:124)
        at com.github.ajalt.clikt.parsers.Parser.parse(Parser.kt:198)
        at com.github.ajalt.clikt.parsers.Parser.parse(Parser.kt:18)
        at com.github.ajalt.clikt.core.CliktCommand.parse(CliktCommand.kt:400)
        at com.github.ajalt.clikt.core.CliktCommand.parse$default(CliktCommand.kt:397)
        at com.github.ajalt.clikt.core.CliktCommand.main(CliktCommand.kt:415)
        at com.github.ajalt.clikt.core.CliktCommand.main(CliktCommand.kt:440)
        at io.spine.protodata.cli.app.MainKt.main(Main.kt:66)
Caused by: java.lang.AssertionError: Unexpected token: 'float'
        at com.intellij.lang.java.parser.JavaParserUtil.parseFragment(JavaParserUtil.java:210)
        at com.intellij.psi.impl.source.tree.JavaElementType$JavaDummyElementType.parseContents(JavaElementType.java:273)
        at com.intellij.psi.impl.source.tree.LazyParseableElement.lambda$ensureParsed$2(LazyParseableElement.java:175)
        at com.intellij.psi.impl.DebugUtil.performPsiModification(DebugUtil.java:481)
        at com.intellij.psi.impl.source.tree.LazyParseableElement.ensureParsed(LazyParseableElement.java:174)
        at com.intellij.psi.impl.source.tree.LazyParseableElement.getFirstChildNode(LazyParseableElement.java:226)
        at com.intellij.psi.impl.source.JavaDummyElement.getFirstChildNode(JavaDummyElement.java:69)
        at com.intellij.psi.impl.PsiJavaParserFacadeImpl.createMethodFromText(PsiJavaParserFacadeImpl.java:182)
        ... 37 more

Exception caught in ProtoData `main()`:
com.intellij.util.IncorrectOperationException: Incorrect method 'public io.spine.base.EventMessageField float() {
    return new io.spine.base.EventMessageField(getField().nested("float"));                
}  '
        at com.intellij.psi.impl.PsiJavaParserFacadeImpl.newException(PsiJavaParserFacadeImpl.java:388)
        at com.intellij.psi.impl.PsiJavaParserFacadeImpl.createMethodFromText(PsiJavaParserFacadeImpl.java:184)
        at com.intellij.psi.impl.PsiElementFactoryImpl.createMethodFromText(PsiElementFactoryImpl.java:684)
        at com.intellij.psi.impl.PsiJavaParserFacadeImpl.createMethodFromText(PsiJavaParserFacadeImpl.java:193)
        at io.spine.tools.psi.java.PsiElementFactoryDecorator.createMethodFromText(PsiElementFactoryDecorator.kt:126)
        at io.spine.tools.mc.java.field.FieldAccessor.method$mc_java_base(FieldAccessors.kt:86)
        at io.spine.tools.mc.java.field.MessageTypedField.addFieldMethods(MessageTypedField.kt:140)
        at io.spine.tools.mc.java.field.MessageTypedField.createClass$mc_java_base(MessageTypedField.kt:106)
        at io.spine.tools.mc.java.field.AddFieldClass.addFieldClasses(AddFieldClass.kt:103)
        at io.spine.tools.mc.java.field.AddFieldClass.tuneClass(AddFieldClass.kt:89)
        at io.spine.protodata.java.render.CreateNestedClass.doRender(CreateNestedClass.kt:108)
        at io.spine.protodata.java.render.MessageAction.render(MessageAction.kt:99)
        at io.spine.protodata.java.render.RenderActions.apply(RenderActions.kt:62)
        at io.spine.tools.mc.java.signal.SignalRenderer.doRender$lambda$0(Renderers.kt:64)
        at io.spine.tools.psi.java.PsiCommandsKt.execute$lambda$0(PsiCommands.kt:59)
        at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:219)
        at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:174)
        at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:164)
        at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:150)
        at io.spine.tools.psi.java.PsiCommandsKt.execute(PsiCommands.kt:64)
        at io.spine.tools.psi.java.PsiCommandsKt.execute$default(PsiCommands.kt:55)
        at io.spine.tools.mc.java.signal.SignalRenderer.doRender(Renderers.kt:63)
        at io.spine.protodata.java.render.TypeListRenderer.doRender(TypeListRenderer.kt:63)
        at io.spine.protodata.java.render.AbstractRenderer.render(AbstractRenderer.kt:114)
        at io.spine.protodata.render.Renderer.renderSources(Renderer.kt:51)
        at io.spine.protodata.plugin.PluginKt.render(Plugin.kt:133)
        at io.spine.protodata.backend.Pipeline.renderSources(Pipeline.kt:303)
        at io.spine.protodata.backend.Pipeline.emitEventsAndRenderSources(Pipeline.kt:274)
        at io.spine.protodata.backend.Pipeline.invoke(Pipeline.kt:253)
        at io.spine.protodata.backend.Pipeline.invoke$default(Pipeline.kt:241)
        at io.spine.protodata.cli.app.Run.doRun(Main.kt:137)
        at io.spine.protodata.cli.app.Run.run(Main.kt:124)
        at com.github.ajalt.clikt.parsers.Parser.parse(Parser.kt:198)
        at com.github.ajalt.clikt.parsers.Parser.parse(Parser.kt:18)
        at com.github.ajalt.clikt.core.CliktCommand.parse(CliktCommand.kt:400)
        at com.github.ajalt.clikt.core.CliktCommand.parse$default(CliktCommand.kt:397)
        at com.github.ajalt.clikt.core.CliktCommand.main(CliktCommand.kt:415)
        at com.github.ajalt.clikt.core.CliktCommand.main(CliktCommand.kt:440)
        at io.spine.protodata.cli.app.MainKt.main(Main.kt:66)
Caused by: java.lang.AssertionError: Unexpected token: 'float'
        at com.intellij.lang.java.parser.JavaParserUtil.parseFragment(JavaParserUtil.java:210)
        at com.intellij.psi.impl.source.tree.JavaElementType$JavaDummyElementType.parseContents(JavaElementType.java:273)
        at com.intellij.psi.impl.source.tree.LazyParseableElement.lambda$ensureParsed$2(LazyParseableElement.java:175)
        at com.intellij.psi.impl.DebugUtil.performPsiModification(DebugUtil.java:481)
        at com.intellij.psi.impl.source.tree.LazyParseableElement.ensureParsed(LazyParseableElement.java:174)
        at com.intellij.psi.impl.source.tree.LazyParseableElement.getFirstChildNode(LazyParseableElement.java:226)
        at com.intellij.psi.impl.source.JavaDummyElement.getFirstChildNode(JavaDummyElement.java:69)
        at com.intellij.psi.impl.PsiJavaParserFacadeImpl.createMethodFromText(PsiJavaParserFacadeImpl.java:182)
        ... 37 more

> Task :proto:context:launchProtoData FAILED

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions