zserio icon indicating copy to clipboard operation
zserio copied to clipboard

Defined 'subtype' is not available in generated Java API.

Open MisterGC opened this issue 3 years ago • 4 comments

Consider the following schema:

package myschema;               
                            
struct MyTemplate<MY_TYPE>      
{                                
    MY_TYPE value;              
};                              
                                 
subtype MyTemplate<int32> MyType;

When generating the API for Java, there is no class/type-identifier MyType available, for Python and C++ there is. I expected that subtype defines something that has to be provided by the API regardless of the target language.

MisterGC avatar Oct 14 '22 15:10 MisterGC

Java language does support any alternative to C++ typedef. Therefore subtypes in Java is resolved during API generation (resolved means that generated Java API uses always original type directly).

We might consider to use duplication or inheritance in the previous example but we will still have a problem for native types:

subtype uint32 U32;

Besides of that, subtype in Zserio means alias which allows writing the following schema:

struct Identifier
{
    uint32 id;
};

subtype Identifier Parameter;

struct Consumer(Parameter parameter)
{
    uint32 value;

    function bool isIdZero()
    {
        return parameter.id == 0;
    }
};

struct Holder
{
    Identifier identifier;
    Consumer(identifier) consumer1;
    
    Parameter parameter;
    Consumer(parameter) consumer2;
};

So, because Zserio language uses alias, we must find out the real alternative in Java to be able to generate working code.

mikir avatar Oct 19 '22 07:10 mikir

Regarding problem with native/primitive types, we might think to use objects instead of them. In this case, we will be hit by significant memory and performance penalty. The fresh comparison of memory and performance between primitives and objects is available at https://www.baeldung.com/java-primitives-vs-objects.

mikir avatar Oct 19 '22 07:10 mikir

The solution for classes (not for native/primitive types) could be if subtypes will be modeled by inheritance of original types and original types will be used everywhere instead of subtypes. Or maybe even better original types will define interface which will be implemented by all subtypes.

mikir avatar Oct 19 '22 08:10 mikir

Note that even with interfaces the getters will still return only the interface, so that the following Java code will not compile:

someZserioObject.setMyField(new MySubtype(10)); // here it works since MySubtype will down-cast to MyBaseType
final MySubtype field = someZserioObject.getMyField(); // myField member will always be of type MyBaseType and thus the up-cast will not work automatically

The member cannot by of type MySubtype since it then wouldn't be possible to call setter with MyBaseType.

Mi-La avatar Oct 19 '22 10:10 Mi-La