-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds read-write API generation support for Java code generation #100
Conversation
* Adds import statement for IonReader and IonException * Adds read API for `AbstractDataType::Value`, `AbstractDataType::Sequence` and `AbstractDataType::Structure`
* Adds new tests for read APi generation * Modifies current `is_built_in_type` filter for `JavaLanguage` to change float to double * Modifies test input and schemas to use Ion float values
* Modifies class template toa dd writer API support * Adds roundtrip tests in CodeGenTest.java
assertEquals(false, n.getC().getD(), "n.getC().getD() should return `false`"); | ||
} | ||
|
||
@Test void roundtripTestForStructWithFields() throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(🗺️ PR tour) Added roundtrip tests for generated read-write APIs
@@ -16,4 +21,110 @@ public final class {{ target_kind_name }} { | |||
return this.{{ field.name | camel }}; | |||
} | |||
{% endfor %} | |||
|
|||
public static {{ target_kind_name }} readFrom(IonReader reader) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(🗺️ PR tour) Added readFrom
API in the class template for reading an Ion value into the given data model.
return new {{ target_kind_name }}({% for field in fields | sort(attribute="name") -%}{{ field.name | camel }}{% if not loop.last %},{% endif %}{% endfor %}); | ||
} | ||
|
||
public void writeTo(IonWriter writer) throws IOException { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(🗺️ PR tour) Added writeTo
API in the class template for writing the given data model as Ion.
@@ -88,7 +88,7 @@ impl Language for JavaLanguage { | |||
} | |||
|
|||
fn is_built_in_type(name: &str) -> bool { | |||
matches!(name, "int" | "String" | "boolean" | "byte[]" | "float") | |||
matches!(name, "int" | "String" | "boolean" | "byte[]" | "double") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(🗺️ PR tour) ion-java uses doubleValue
API for IonReader
, so changing this similar to ion-java.
@@ -2,4 +2,5 @@ | |||
A: "hello", | |||
B: 12, | |||
C: ["foo", "bar", "baz"], | |||
D: 10e2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(🗺️ PR tour) Added this field to test for double value in Java.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is good progress!
It would be nice if you could drop the generated code into a GitHub Gist or something so that a reviewer can also look at the generated code without having to check out and build the PR locally.
The read and write code is exposing some things that are not very idiomatic Java. They don't need to be addressed in this PR, but I think they are things that must be addressed before saying that this is production-ready.
- The "new type" pattern—while this is idiomatic in Rust, it is potentially expensive and awkward to use in Java. I think that anonymous, parameterized-list types should not be wrapped in a new Java type.
- We need to have a builder for classes that are based on Ion
struct
s. - I think we should try to define anonymous types as nested static classes inside their respective parent type. E.g. using the schema given here, that would mean that
AnonymousType2
would actually beStructWithFields.AnonymousType2
.
} | ||
reader.stepOut(); | ||
{% endif %} | ||
return new {{ target_kind_name }}({% for field in fields | sort(attribute="name") -%}{{ field.name | camel }}{% if not loop.last %},{% endif %}{% endfor %}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We really need to have a builder class so that we can avoid things like sorting the field names and having to check to see if we're on the last loop iteration to see if we need a comma.
{% if field.value == "boolean" %} | ||
false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you use Boolean
instead of boolean
, then this could be initialized to null
. Similarly for int
/Integer
and double
/Double
.
However, if it's not an optional field, then we're better off using the primitive types to avoid the overhead of the boxed types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am going to keep this as boolean/int/double for now. I will change it in separate PR to consider nulls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reference: #101
I added the generated code in the PR description for one of the schema files. But I will add Gists with generated code from now to make this easier.
What did you mean by
Yes, builder needs to be added for sure. I have already created an issue for it and will work on it as the next PR.
Yes, I will change that. |
* Modified indentation for template files * Adds doc comment * Minor typo fixes
I didn't even notice that... it's my fault for jumping straight into the code, I guess. |
https://doc.rust-lang.org/rust-by-example/generics/new_types.html The |
As per offline discussion, this will be added with a separate PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome :) lgtm, as long as popematt's concerns are met.
* Changes Rust and Java demo project tests to run throughbad/invalid input Ion files and assert Exception is thrown * Changes Rust and java dmeo projects tests to run through each good/valid input Ion files and assert equivelnce for roundtrip test * Adds valid and invalid inpu Ion files for tests
Issue #87:
Description of changes:
This PR adds read-write API generation support for Java.
Example generated APIs
This example uses schema
struct_with_fields
fromcode-gen-projects/schema/
.Note: The generated code has been formatted here and actual code might have extra lines and tabs.
Complete generated code can be found here.
List of changes:
is_built_in_type
filter forJavaLanguage
tochange
float
todouble
and added Ion float field to verifyCodeGenTest.java
CodeGenTest.java
Test
Roundtrip tests are added to test generated read-write API.
The test consists of 3 steps:
IonReader
into data model withreadFrom
APIIonWriter
as Ion withwriteTo
APIIonLoader
check equivalence of initially provided Ion data and the Ion data written bywriteTo
API.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.