
zserio.extension.java.CompoundFieldTemplateData Maven / Gradle / Ivy
package zserio.extension.java;
import java.util.ArrayList;
import zserio.ast.ArrayInstantiation;
import zserio.ast.ChoiceType;
import zserio.ast.CompoundType;
import zserio.ast.Expression;
import zserio.ast.Field;
import zserio.ast.ParameterizedTypeInstantiation;
import zserio.ast.ParameterizedTypeInstantiation.InstantiatedParameter;
import zserio.ast.TypeInstantiation;
import zserio.ast.TypeReference;
import zserio.ast.UnionType;
import zserio.ast.ZserioType;
import zserio.extension.common.ExpressionFormatter;
import zserio.extension.common.ZserioExtensionException;
import zserio.extension.java.types.JavaNativeType;
import zserio.extension.java.types.NativeArrayTraits;
import zserio.extension.java.types.NativeArrayType;
import zserio.extension.java.types.NativeRawArray;
/**
* FreeMarker template data for compound fields.
*/
public final class CompoundFieldTemplateData
{
public CompoundFieldTemplateData(TemplateDataContext context, CompoundType parentType, Field field)
throws ZserioExtensionException
{
final TypeInstantiation fieldTypeInstantiation = field.getTypeInstantiation();
name = field.getName();
// this must be the first one because we need to determine isTypeNullable
final ExpressionFormatter javaExpressionFormatter = context.getJavaExpressionFormatter();
final ExpressionFormatter javaLambdaExpressionFormatter = context.getJavaLambdaExpressionFormatter();
optional = createOptional(field, fieldTypeInstantiation.getBaseType(), parentType,
javaExpressionFormatter, javaLambdaExpressionFormatter);
final JavaNativeMapper javaNativeMapper = context.getJavaNativeMapper();
final boolean isTypeNullable = (optional != null);
final JavaNativeType nullableNativeType = javaNativeMapper.getNullableJavaType(fieldTypeInstantiation);
final JavaNativeType nativeType =
(isTypeNullable) ? nullableNativeType : javaNativeMapper.getJavaType(fieldTypeInstantiation);
nullableTypeInfo = new NativeTypeInfoTemplateData(nullableNativeType, fieldTypeInstantiation);
typeInfo = new NativeTypeInfoTemplateData(nativeType, fieldTypeInstantiation);
getterName = AccessorNameFormatter.getGetterName(field);
setterName = AccessorNameFormatter.getSetterName(field);
isExtended = field.isExtended();
isPresentIndicatorName = AccessorNameFormatter.getIsPresentIndicatorName(field);
isPackable = field.isPackable();
final boolean withRangeCheckCode = context.getWithRangeCheckCode();
rangeCheckData = new RangeCheckTemplateData(this, javaNativeMapper, withRangeCheckCode,
fieldTypeInstantiation, isTypeNullable, javaExpressionFormatter);
alignmentValue = createAlignmentValue(field, javaExpressionFormatter);
initializer = createInitializer(field, javaExpressionFormatter);
usesObjectChoice = (parentType instanceof ChoiceType) || (parentType instanceof UnionType);
constraint = createConstraint(field, javaExpressionFormatter);
lambdaConstraint = createConstraint(field, javaLambdaExpressionFormatter);
bitSize = BitSizeTemplateData.create(
fieldTypeInstantiation, javaExpressionFormatter, javaLambdaExpressionFormatter);
offset = createOffset(field, javaNativeMapper, javaExpressionFormatter, javaLambdaExpressionFormatter);
array = createArray(context, nativeType, fieldTypeInstantiation, parentType);
runtimeFunction = RuntimeFunctionDataCreator.createData(context, fieldTypeInstantiation);
compound = createCompound(context, fieldTypeInstantiation);
docComments = DocCommentsDataCreator.createData(context, field);
}
public String getName()
{
return name;
}
public NativeTypeInfoTemplateData getNullableTypeInfo()
{
return nullableTypeInfo;
}
public NativeTypeInfoTemplateData getTypeInfo()
{
return typeInfo;
}
public String getGetterName()
{
return getterName;
}
public String getSetterName()
{
return setterName;
}
public boolean getIsExtended()
{
return isExtended;
}
public String getIsPresentIndicatorName()
{
return isPresentIndicatorName;
}
public boolean getIsPackable()
{
return isPackable;
}
public RangeCheckTemplateData getRangeCheckData()
{
return rangeCheckData;
}
public Optional getOptional()
{
return optional;
}
public String getAlignmentValue()
{
return alignmentValue;
}
public String getInitializer()
{
return initializer;
}
public boolean getUsesObjectChoice()
{
return usesObjectChoice;
}
public String getConstraint()
{
return constraint;
}
public String getLambdaConstraint()
{
return lambdaConstraint;
}
public BitSizeTemplateData getBitSize()
{
return bitSize;
}
public Offset getOffset()
{
return offset;
}
public Array getArray()
{
return array;
}
public RuntimeFunctionTemplateData getRuntimeFunction()
{
return runtimeFunction;
}
public Compound getCompound()
{
return compound;
}
public DocCommentsTemplateData getDocComments()
{
return docComments;
}
public static final class Optional
{
public Optional(Field field, ExpressionFormatter javaExpressionFormatter,
ExpressionFormatter javaLambdaExpressionFormatter, boolean isRecursive)
throws ZserioExtensionException
{
final Expression optionalClauseExpression = field.getOptionalClauseExpr();
clause = (optionalClauseExpression == null)
? null
: javaExpressionFormatter.formatGetter(optionalClauseExpression);
lambdaClause = (optionalClauseExpression == null)
? null
: javaLambdaExpressionFormatter.formatGetter(optionalClauseExpression);
isUsedIndicatorName = AccessorNameFormatter.getIsUsedIndicatorName(field);
isSetIndicatorName = AccessorNameFormatter.getIsSetIndicatorName(field);
resetterName = AccessorNameFormatter.getResetterName(field);
this.isRecursive = isRecursive;
}
public String getClause()
{
return clause;
}
public String getLambdaClause()
{
return lambdaClause;
}
public String getIsUsedIndicatorName()
{
return isUsedIndicatorName;
}
public String getIsSetIndicatorName()
{
return isSetIndicatorName;
}
public String getResetterName()
{
return resetterName;
}
public boolean getIsRecursive()
{
return isRecursive;
}
private final String clause;
private final String lambdaClause;
private final String isUsedIndicatorName;
private final String isSetIndicatorName;
private final String resetterName;
private final boolean isRecursive;
}
public static final class Offset
{
public Offset(Expression offsetExpression, JavaNativeMapper javaNativeMapper,
ExpressionFormatter javaExpressionFormatter, ExpressionFormatter javaLambdaExpressionFormatter)
throws ZserioExtensionException
{
getter = javaExpressionFormatter.formatGetter(offsetExpression);
setter = javaExpressionFormatter.formatSetter(offsetExpression);
lambdaGetter = javaLambdaExpressionFormatter.formatGetter(offsetExpression);
final JavaNativeType nativeType =
javaNativeMapper.getJavaType(offsetExpression.getExprZserioType());
typeInfo = new NativeTypeInfoTemplateData(nativeType);
containsIndex = offsetExpression.containsIndex();
}
public String getGetter()
{
return getter;
}
public String getSetter()
{
return setter;
}
public String getLambdaGetter()
{
return lambdaGetter;
}
public NativeTypeInfoTemplateData getTypeInfo()
{
return typeInfo;
}
public boolean getContainsIndex()
{
return containsIndex;
}
private final String getter;
private final String setter;
private final String lambdaGetter;
private final NativeTypeInfoTemplateData typeInfo;
private final boolean containsIndex;
}
public static final class Array
{
public Array(TemplateDataContext context, NativeArrayType nativeType,
ArrayInstantiation arrayInstantiation, CompoundType parentType) throws ZserioExtensionException
{
final TypeInstantiation elementTypeInstantiation = arrayInstantiation.getElementTypeInstantiation();
isImplicit = arrayInstantiation.isImplicit();
isPacked = arrayInstantiation.isPacked();
final ExpressionFormatter javaExpressionFormatter = context.getJavaExpressionFormatter();
length = createLength(arrayInstantiation, javaExpressionFormatter);
final ExpressionFormatter javaLambdaExpressionFormatter =
context.getJavaLambdaExpressionFormatter();
lambdaLength = createLength(arrayInstantiation, javaLambdaExpressionFormatter);
wrapperJavaTypeName = nativeType.getArrayWrapper().getFullName();
final NativeRawArray nativeRawArray = nativeType.getRawArray();
rawHolderJavaTypeName = nativeRawArray.getFullName();
final NativeArrayTraits nativeArrayTraits = nativeType.getArrayTraits();
arrayTraits = new ArrayTraitsTemplateData(nativeArrayTraits);
final JavaNativeMapper javaNativeMapper = context.getJavaNativeMapper();
final JavaNativeType elementNativeType = javaNativeMapper.getJavaType(elementTypeInstantiation);
elementTypeInfo = new NativeTypeInfoTemplateData(elementNativeType, elementTypeInstantiation);
requiresElementClass = nativeRawArray.requiresElementClass();
requiresOwnerContext = createRequiresOwnerContext(elementTypeInstantiation);
elementBitSize = BitSizeTemplateData.create(
elementTypeInstantiation, javaExpressionFormatter, javaLambdaExpressionFormatter);
elementCompound = createCompound(context, elementTypeInstantiation);
elementIsRecursive = elementTypeInstantiation.getBaseType() == parentType;
elementUsedInPackedArray = context.getPackedTypesCollector().isUsedInPackedArray(
elementTypeInstantiation.getBaseType());
}
public boolean getIsImplicit()
{
return isImplicit;
}
public boolean getIsPacked()
{
return isPacked;
}
public String getLength()
{
return length;
}
public String getLambdaLength()
{
return lambdaLength;
}
public String getWrapperJavaTypeName()
{
return wrapperJavaTypeName;
}
public String getRawHolderJavaTypeName()
{
return rawHolderJavaTypeName;
}
public ArrayTraitsTemplateData getArrayTraits()
{
return arrayTraits;
}
public NativeTypeInfoTemplateData getElementTypeInfo()
{
return elementTypeInfo;
}
public boolean getRequiresElementClass()
{
return requiresElementClass;
}
public boolean getRequiresOwnerContext()
{
return requiresOwnerContext;
}
public BitSizeTemplateData getElementBitSize()
{
return elementBitSize;
}
public Compound getElementCompound()
{
return elementCompound;
}
public boolean getElementIsRecursive()
{
return elementIsRecursive;
}
public boolean getElementUsedInPackedArray()
{
return elementUsedInPackedArray;
}
private static String createLength(ArrayInstantiation arrayInstantiation,
ExpressionFormatter javaExpressionFormatter) throws ZserioExtensionException
{
final Expression lengthExpression = arrayInstantiation.getLengthExpression();
if (lengthExpression == null)
return null;
return javaExpressionFormatter.formatGetter(lengthExpression);
}
private static boolean createRequiresOwnerContext(TypeInstantiation elementTypeInstantiation)
{
/*
* Array length expression (Foo field[expr];) is not needed here because it's handled by the array
* class itself, it's not propagated to the array factory.
* But an array can be composed of type instantiations and these need to be handled.
*/
if (elementTypeInstantiation instanceof ParameterizedTypeInstantiation)
{
final ParameterizedTypeInstantiation parameterizedInstantiation =
(ParameterizedTypeInstantiation)elementTypeInstantiation;
for (InstantiatedParameter instantiatedParameter :
parameterizedInstantiation.getInstantiatedParameters())
{
if (instantiatedParameter.getArgumentExpression().requiresOwnerContext())
return true;
}
}
return false;
}
private final boolean isImplicit;
private final boolean isPacked;
private final String length;
private final String lambdaLength;
private final String wrapperJavaTypeName;
private final String rawHolderJavaTypeName;
private final ArrayTraitsTemplateData arrayTraits;
private final NativeTypeInfoTemplateData elementTypeInfo;
private final boolean requiresElementClass;
private final boolean requiresOwnerContext;
private final BitSizeTemplateData elementBitSize;
private final Compound elementCompound;
private final boolean elementIsRecursive;
private final boolean elementUsedInPackedArray;
}
public static final class Compound
{
public Compound(TemplateDataContext context,
ParameterizedTypeInstantiation parameterizedTypeInstantiation) throws ZserioExtensionException
{
this(context, parameterizedTypeInstantiation.getBaseType());
for (InstantiatedParameter param : parameterizedTypeInstantiation.getInstantiatedParameters())
{
instantiatedParameters.add(new InstantiatedParameterData(context, param));
}
}
public Compound(TemplateDataContext context, CompoundType compoundType) throws ZserioExtensionException
{
instantiatedParameters = new ArrayList();
parameters = new CompoundParameterTemplateData(context, compoundType);
}
public Iterable getInstantiatedParameters()
{
return instantiatedParameters;
}
public CompoundParameterTemplateData getParameters()
{
return parameters;
}
public static final class InstantiatedParameterData
{
public InstantiatedParameterData(TemplateDataContext context,
InstantiatedParameter instantiatedParameter) throws ZserioExtensionException
{
final TypeReference parameterTypeReference =
instantiatedParameter.getParameter().getTypeReference();
final JavaNativeMapper javaNativeMapper = context.getJavaNativeMapper();
final JavaNativeType nativeParameterType = javaNativeMapper.getJavaType(parameterTypeReference);
typeInfo = new NativeTypeInfoTemplateData(nativeParameterType, parameterTypeReference);
final ExpressionFormatter javaExpressionFormatter = context.getJavaExpressionFormatter();
expression =
javaExpressionFormatter.formatGetter(instantiatedParameter.getArgumentExpression());
final ExpressionFormatter javaLambdaExpressionFormatter =
context.getJavaLambdaExpressionFormatter();
lambdaExpression = javaLambdaExpressionFormatter.formatGetter(
instantiatedParameter.getArgumentExpression());
}
public NativeTypeInfoTemplateData getTypeInfo()
{
return typeInfo;
}
public String getExpression()
{
return expression;
}
public String getLambdaExpression()
{
return lambdaExpression;
}
private final NativeTypeInfoTemplateData typeInfo;
private final String expression;
private final String lambdaExpression;
}
private final ArrayList instantiatedParameters;
private final CompoundParameterTemplateData parameters;
}
private static Optional createOptional(Field field, ZserioType fieldBaseType, CompoundType parentType,
ExpressionFormatter javaExpressionFormatter, ExpressionFormatter javaLambdaExpressionFormatter)
throws ZserioExtensionException
{
if (!field.isOptional())
return null;
final boolean isRecursive = fieldBaseType == parentType;
return new Optional(field, javaExpressionFormatter, javaLambdaExpressionFormatter, isRecursive);
}
private static String createInitializer(Field field, ExpressionFormatter javaExpressionFormatter)
throws ZserioExtensionException
{
final Expression initializerExpression = field.getInitializerExpr();
if (initializerExpression == null)
return null;
return javaExpressionFormatter.formatGetter(initializerExpression);
}
private static String createAlignmentValue(Field field, ExpressionFormatter javaExpressionFormatter)
throws ZserioExtensionException
{
final Expression alignmentExpression = field.getAlignmentExpr();
if (alignmentExpression == null)
return null;
return javaExpressionFormatter.formatGetter(alignmentExpression);
}
private static String createConstraint(Field field, ExpressionFormatter javaExpressionFormatter)
throws ZserioExtensionException
{
final Expression constraintExpression = field.getConstraintExpr();
if (constraintExpression == null)
return null;
return javaExpressionFormatter.formatGetter(constraintExpression);
}
private static Offset createOffset(Field field, JavaNativeMapper javaNativeMapper,
ExpressionFormatter javaExpressionFormatter, ExpressionFormatter javaLambdaExpressionFormatter)
throws ZserioExtensionException
{
final Expression offsetExpression = field.getOffsetExpr();
if (offsetExpression == null)
return null;
return new Offset(
offsetExpression, javaNativeMapper, javaExpressionFormatter, javaLambdaExpressionFormatter);
}
private static Array createArray(TemplateDataContext context, JavaNativeType nativeType,
TypeInstantiation typeInstantiation, CompoundType parentType) throws ZserioExtensionException
{
if (!(nativeType instanceof NativeArrayType))
return null;
if (!(typeInstantiation instanceof ArrayInstantiation))
{
throw new ZserioExtensionException("Inconsistent instantiation '" +
typeInstantiation.getClass().getName() + "' and native type '" +
nativeType.getClass().getName() + "'!");
}
return new Array(
context, (NativeArrayType)nativeType, (ArrayInstantiation)typeInstantiation, parentType);
}
private static Compound createCompound(TemplateDataContext context, TypeInstantiation typeInstantiation)
throws ZserioExtensionException
{
if (typeInstantiation instanceof ParameterizedTypeInstantiation)
{
return new Compound(context, (ParameterizedTypeInstantiation)typeInstantiation);
}
else if (typeInstantiation.getBaseType() instanceof CompoundType)
{
return new Compound(context, (CompoundType)typeInstantiation.getBaseType());
}
else
{
return null;
}
}
private final String name;
private final NativeTypeInfoTemplateData nullableTypeInfo;
private final NativeTypeInfoTemplateData typeInfo;
private final String getterName;
private final String setterName;
private final boolean isExtended;
private final String isPresentIndicatorName;
private final boolean isPackable;
private final RangeCheckTemplateData rangeCheckData;
private final Optional optional;
private final String alignmentValue;
private final String initializer;
private final boolean usesObjectChoice;
private final String constraint;
private final String lambdaConstraint;
private final BitSizeTemplateData bitSize;
private final Offset offset;
private final Array array;
private final RuntimeFunctionTemplateData runtimeFunction;
private final Compound compound;
private final DocCommentsTemplateData docComments;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy