Skip to content

Commit

Permalink
Adds separate template files for sequence, scalar and struct in Java …
Browse files Browse the repository at this point in the history
…and Rust
  • Loading branch information
desaikd committed May 29, 2024
1 parent c4b327f commit 6160cc6
Show file tree
Hide file tree
Showing 7 changed files with 363 additions and 202 deletions.
144 changes: 40 additions & 104 deletions src/bin/ion/commands/beta/generate/templates/java/class.templ
Original file line number Diff line number Diff line change
Expand Up @@ -58,74 +58,36 @@ public class {{ target_kind_name }} {
null
{% endif %};
{% endfor %}
{% if abstract_data_type == "Value"%}
{# Reads `Value` class with a single field `value` #}
value = {% if fields[0].value_type | is_built_in_type %}
{% if fields[0].value_type == "bytes[]" %}
reader.newBytes();
{% else %}
reader.{{ fields[0].value_type | camel }}Value();
{% endif %}
{% else %}
{{ fields[0].value_type }}.readFrom(reader);
{% endif %}
{% elif abstract_data_type is object and abstract_data_type is containing("Structure") %}
{# Reads `Structure` class with multiple fields based on `field.name` #}
reader.stepIn();
while (reader.hasNext()) {
reader.next();
String fieldName = reader.getFieldName();
switch(fieldName) {
{% for field in fields %}
case "{{ field.name }}":
{{ field.name | camel }} = {% if field.value_type | is_built_in_type %}
{% if field.value_type == "bytes[]" %}
reader.newBytes();
{% else %}
reader.{{ field.value_type | camel }}Value();
{% endif %}

{# Reads `Structure` class with multiple fields based on `field.name` #}
reader.stepIn();
while (reader.hasNext()) {
reader.next();
String fieldName = reader.getFieldName();
switch(fieldName) {
{% for field in fields %}
case "{{ field.name }}":
{{ field.name | camel }} = {% if field.value_type | is_built_in_type %}
{% if field.value_type == "bytes[]" %}
reader.newBytes();
{% else %}
reader.{{ field.value_type | camel }}Value();
{% endif %}
{% else %}
{% if field.value_type is containing("ArrayList") %}
{{ util_macros::read_as_sequence(field=field) }}
{% else %}
{% if field.value_type is containing("ArrayList") %}
{{ util_macros::read_as_sequence(field=field) }}
{% else %}
{{ field.value_type }}.readFrom(reader);
{% endif %}
{{ field.value_type }}.readFrom(reader);
{% endif %}
break;
{% endfor %}
default:
throw new IonException("Can not read field name:" + fieldName + " for {{ target_kind_name }} as it doesn't exist in the given schema type definition.");
}
}
reader.stepOut();
{% elif abstract_data_type is object and abstract_data_type is containing("Sequence") %}
{# Reads `Sequence` class with a single field `value` that is an `ArrayList` #}
{% if abstract_data_type["Sequence"].sequence_type == "List" %}
if(reader.getType() != IonType.LIST) {
throw new IonException("Expected list, found " + reader.getType() + " while reading {{ target_kind_name }}.");
}
{% elif abstract_data_type["Sequence"].sequence_type == "SExp" %}
if(reader.getType() != IonType.SEXP) {
throw new IonException("Expected sexpression, found " + reader.getType() + " while reading {{ target_kind_name }}.");
}
{% endif %}
reader.stepIn();
value = new {{ fields[0].value_type }}();
{# Iterate through the `ArrayList` and read each element in it based on the data type provided in `abstract_data_type[Sequence]` #}
while (reader.hasNext()) {
reader.next();
{% if abstract_data_type["Sequence"].element_type | is_built_in_type == false %}
value.add({{ abstract_data_type["Sequence"].element_type }}.readFrom(reader));
{% else %}
{% if abstract_data_type["Sequence"].element_type == "bytes[]" %}
value.add(reader.newBytes());
{% else %}
value.add(reader.{{ abstract_data_type["Sequence"].element_type | camel }}Value());
{% endif %}
{% endif %}
{% endif %}
break;
{% endfor %}
default:
throw new IonException("Can not read field name:" + fieldName + " for {{ target_kind_name }} as it doesn't exist in the given schema type definition.");
}
reader.stepOut();
{% endif %}
}
reader.stepOut();

{{ target_kind_name }} {{ target_kind_name | camel }} = new {{ target_kind_name }}();
{% for field in fields -%}
{{ target_kind_name | camel }}.{{ field.name | camel }} = {{ field.name | camel }};
Expand All @@ -141,47 +103,21 @@ public class {{ target_kind_name }} {
* The caller is responsible for closing the stream associated with the writer.
*/
public void writeTo(IonWriter writer) throws IOException {
{% if abstract_data_type == "Value" %}
{# Writes `Value` class with a single field `value` as an Ion value #}
{% for field in fields %}
{% if field.value_type | is_built_in_type == false %}
this.{{ field.name | camel }}.writeTo(writer)?;
{% else %}
writer.write{{ field.isl_type_name | upper_camel }}(this.value);
{% endif %}
{% endfor %}
{% elif abstract_data_type is object and abstract_data_type is containing("Structure") %}
{# Writes `Structure` class with multiple fields based on `field.name` as an Ion struct #}
writer.stepIn(IonType.STRUCT);
{% for field in fields %}
writer.setFieldName("{{ field.name }}");
{% if field.value_type | is_built_in_type == false %}
{% if field.value_type is containing("ArrayList") %}
{{ util_macros::write_as_sequence(field=field) }}
{% else %}
this.{{ field.name | camel }}.writeTo(writer);
{% endif %}
{# Writes `Structure` class with multiple fields based on `field.name` as an Ion struct #}
writer.stepIn(IonType.STRUCT);
{% for field in fields %}
writer.setFieldName("{{ field.name }}");
{% if field.value_type | is_built_in_type == false %}
{% if field.value_type is containing("ArrayList") %}
{{ util_macros::write_as_sequence(field=field) }}
{% else %}
writer.write{{ field.isl_type_name | upper_camel }}(this.{{ field.name | camel }});
this.{{ field.name | camel }}.writeTo(writer);
{% endif %}
{% endfor %}
writer.stepOut();
{% elif abstract_data_type is object and abstract_data_type is containing("Sequence") %}
{# Writes `Sequence` class with a single field `value` that is an `ArrayList` as an Ion sequence #}
{% if abstract_data_type["Sequence"].sequence_type == "List" %}
writer.stepIn(IonType.LIST);
{% else %}
writer.stepIn(IonType.SEXP);
{% endif %}
for ({{ abstract_data_type["Sequence"].element_type }} value: this.value) {
{% if abstract_data_type["Sequence"].element_type | is_built_in_type == false %}
value.writeTo(writer);
{% else %}
writer.write{{ abstract_data_type["Sequence"].element_type | upper_camel }}(value);
{% endif %}
}
writer.stepOut();
{% endif %}
{% else %}
writer.write{{ field.isl_type_name | upper_camel }}(this.{{ field.name | camel }});
{% endif %}
{% endfor %}
writer.stepOut();
}

{% for inline_type in nested_types -%}
Expand Down
69 changes: 69 additions & 0 deletions src/bin/ion/commands/beta/generate/templates/java/scalar.templ
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package {{ namespace }};
import java.util.ArrayList;
import com.amazon.ion.IonReader;
import com.amazon.ion.IonException;
import com.amazon.ion.IonWriter;
import com.amazon.ion.IonType;
import java.io.IOException;

public class {{ target_kind_name }} {
private {{ fields[0].value_type }} value;

public {{ target_kind_name }}() {}

public {{ fields[0].value_type }} getValue() {
return this.value;
}

public void setValue({{ fields[0].value_type }} value) {
this.value = value;
return;
}

/**
* Reads a {{ target_kind_name }} from an {@link IonReader}.
*
* This method does not advance the reader at the current level.
* The caller is responsible for positioning the reader on the value to read.
*/
public static {{ target_kind_name }} readFrom(IonReader reader) {
{# Initializes all the fields of this class #}
{{ fields[0].value_type }} value =
{% if fields[0].value_type == "boolean" %}
false
{% elif fields[0].value_type == "int" or fields[0].value_type == "double" %}
0
{% else %}
null
{% endif %};
{# Reads `Value` class with a single field `value` #}
value = {% if fields[0].value_type | is_built_in_type %}
{% if fields[0].value_type == "bytes[]" %}
reader.newBytes();
{% else %}
reader.{{ fields[0].value_type | camel }}Value();
{% endif %}
{% else %}
{{ fields[0].value_type }}.readFrom(reader);
{% endif %}
{{ target_kind_name }} {{ target_kind_name | camel }} = new {{ target_kind_name }}();
{{ target_kind_name | camel }}.value = value;

return {{ target_kind_name | camel }};
}

/**
* Writes a {{ target_kind_name }} as Ion from an {@link IonWriter}.
*
* This method does not close the writer after writing is complete.
* The caller is responsible for closing the stream associated with the writer.
*/
public void writeTo(IonWriter writer) throws IOException {
{# Writes `Value` class with a single field `value` as an Ion value #}
{% if fields[0].value_type | is_built_in_type == false %}
this.value.writeTo(writer)?;
{% else %}
writer.write{{ fields[0].isl_type_name | upper_camel }}(this.value);
{% endif %}
}
}
93 changes: 93 additions & 0 deletions src/bin/ion/commands/beta/generate/templates/java/sequence.templ
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package {{ namespace }};
import java.util.ArrayList;
import com.amazon.ion.IonReader;
import com.amazon.ion.IonException;
import com.amazon.ion.IonWriter;
import com.amazon.ion.IonType;
import java.io.IOException;

public class {{ target_kind_name }} {
private {{ fields[0].value_type }} value;

public {{ target_kind_name }}() {}

public {{ fields[0].value_type }} getValue() {
return this.value;
}

public void setValue({{ fields[0].value_type }} value) {
this.value = value;
return;
}

/**
* Reads a {{ target_kind_name }} from an {@link IonReader}.
*
* This method does not advance the reader at the current level.
* The caller is responsible for positioning the reader on the value to read.
*/
public static {{ target_kind_name }} readFrom(IonReader reader) {
{# Initializes all the fields of this class #}
{{ fields[0].value_type }} value =
{% if fields[0].value_type == "boolean" %}
false
{% elif fields[0].value_type == "int" or fields[0].value_type == "double" %}
0
{% else %}
null
{% endif %};
{# Reads `Sequence` class with a single field `value` that is an `ArrayList` #}
{% if abstract_data_type["Sequence"].sequence_type == "List" %}
if(reader.getType() != IonType.LIST) {
throw new IonException("Expected list, found " + reader.getType() + " while reading {{ target_kind_name }}.");
}
{% elif abstract_data_type["Sequence"].sequence_type == "SExp" %}
if(reader.getType() != IonType.SEXP) {
throw new IonException("Expected sexpression, found " + reader.getType() + " while reading {{ target_kind_name }}.");
}
{% endif %}
reader.stepIn();
value = new {{ fields[0].value_type }}();
{# Iterate through the `ArrayList` and read each element in it based on the data type provided in `abstract_data_type[Sequence]` #}
while (reader.hasNext()) {
reader.next();
{% if abstract_data_type["Sequence"].element_type | is_built_in_type == false %}
value.add({{ abstract_data_type["Sequence"].element_type }}.readFrom(reader));
{% else %}
{% if abstract_data_type["Sequence"].element_type == "bytes[]" %}
value.add(reader.newBytes());
{% else %}
value.add(reader.{{ abstract_data_type["Sequence"].element_type | camel }}Value());
{% endif %}
{% endif %}
}
reader.stepOut();
{{ target_kind_name }} {{ target_kind_name | camel }} = new {{ target_kind_name }}();
{{ target_kind_name | camel }}.value = value;

return {{ target_kind_name | camel }};
}

/**
* Writes a {{ target_kind_name }} as Ion from an {@link IonWriter}.
*
* This method does not close the writer after writing is complete.
* The caller is responsible for closing the stream associated with the writer.
*/
public void writeTo(IonWriter writer) throws IOException {
{# Writes `Sequence` class with a single field `value` that is an `ArrayList` as an Ion sequence #}
{% if abstract_data_type["Sequence"].sequence_type == "List" %}
writer.stepIn(IonType.LIST);
{% else %}
writer.stepIn(IonType.SEXP);
{% endif %}
for ({{ abstract_data_type["Sequence"].element_type }} value: this.value) {
{% if abstract_data_type["Sequence"].element_type | is_built_in_type == false %}
value.writeTo(writer);
{% else %}
writer.write{{ abstract_data_type["Sequence"].element_type | upper_camel }}(value);
{% endif %}
}
writer.stepOut();
}
}
42 changes: 42 additions & 0 deletions src/bin/ion/commands/beta/generate/templates/rust/scalar.templ
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use {{ target_kind_name | snake }}::{{ target_kind_name }};
pub mod {{ target_kind_name | snake }} {
use super::*;

#[derive(Debug, Clone, Default)]
pub struct {{ target_kind_name }} {
value: {{ fields[0].value_type }},
}

impl {{ target_kind_name }} {
pub fn new(value: {{ fields[0].value_type }}) -> Self {
Self {
value,
}
}


pub fn value(&self) -> &{{ fields[0].value_type }} {
&self.value
}


pub fn read_from(reader: &mut Reader) -> SerdeResult<Self> {
let mut abstract_data_type = {{ target_kind_name }}::default();
abstract_data_type.value = {% if fields[0].value_type | is_built_in_type == false %}
{{ fields[0].value_type }}::read_from(reader)?;
{% else %}
reader.read_{% if fields[0].isl_type_name == "symbol" %}symbol()?.text().unwrap(){% else %}{{ fields[0].value_type | lower | replace(from="string", to ="str") }}()?{% endif %}{% if fields[0].value_type | lower == "string" %} .to_string() {% endif %};
{% endif %}
Ok(abstract_data_type)
}

pub fn write_to<W: IonWriter>(&self, writer: &mut W) -> SerdeResult<()> {
{% if fields[0].value_type | is_built_in_type == false %}
self.value.write_to(writer)?;
{% else %}
writer.write_{% if fields[0].isl_type_name == "symbol" %}symbol{% else %}{{ fields[0].value_type | lower }}{% endif %}(self.value.to_owned())?;
{% endif %}
Ok(())
}
}
}
Loading

0 comments on commit 6160cc6

Please sign in to comment.