
com.facebook.swift.generator.ConstantRenderer Maven / Gradle / Ivy
/*
* Copyright (C) 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.swift.generator;
import com.facebook.swift.parser.model.BaseType;
import com.facebook.swift.parser.model.Const;
import com.facebook.swift.parser.model.ConstIdentifier;
import com.facebook.swift.parser.model.ConstInteger;
import com.facebook.swift.parser.model.ConstList;
import com.facebook.swift.parser.model.ConstMap;
import com.facebook.swift.parser.model.ConstString;
import com.facebook.swift.parser.model.ConstValue;
import com.facebook.swift.parser.model.IdentifierType;
import com.facebook.swift.parser.model.ListType;
import com.facebook.swift.parser.model.MapType;
import com.facebook.swift.parser.model.SetType;
import com.facebook.swift.parser.model.ThriftType;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Shorts;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static java.lang.String.format;
public class ConstantRenderer
{
private final TypeToJavaConverter typeConverter;
private final String defaultNamespace;
private final TypeRegistry typeRegistry;
private final TypedefRegistry typedefRegistry;
public ConstantRenderer(
TypeToJavaConverter typeConverter,
String defaultNamespace,
TypeRegistry typeRegistry,
TypedefRegistry typedefRegistry)
{
this.typeConverter = typeConverter;
this.defaultNamespace = defaultNamespace;
this.typeRegistry = typeRegistry;
this.typedefRegistry = typedefRegistry;
}
public String render(Const constant)
{
return render(constant.getType(), constant.getValue());
}
public String render(ThriftType thriftType, ConstValue value)
{
if (thriftType instanceof BaseType) {
return renderBaseConstant((BaseType) thriftType, value);
}
else if (thriftType instanceof ListType) {
checkArgument(value instanceof ConstList);
return renderListConstant((ListType) thriftType, (ConstList) value);
}
else if (thriftType instanceof MapType) {
checkArgument(value instanceof ConstMap);
return renderMapType((MapType) thriftType, (ConstMap) value);
}
else if (thriftType instanceof SetType) {
checkArgument(value instanceof ConstList);
return renderSetConstant((SetType) thriftType, (ConstList) value);
}
else if (thriftType instanceof IdentifierType) {
String typeName = ((IdentifierType) thriftType).getName();
ThriftType resolvedType = typedefRegistry.findType(defaultNamespace, typeName);
checkState(resolvedType != null, format("Could not resolve type named '%s'", typeName));
return render(resolvedType, value);
}
else {
throw new IllegalStateException("Not yet implemented");
}
}
private String renderIdentifierType(IdentifierType identifierType, ConstIdentifier value)
{
return value.value();
}
private String renderMapType(MapType mapType, ConstMap value)
{
StringBuilder sb = new StringBuilder();
sb.append("ImmutableMap.<");
sb.append(typeConverter.convert(mapType.getKeyType(), false));
sb.append(", ");
sb.append(typeConverter.convert(mapType.getValueType(), false));
sb.append(">builder()\n");
Set> entries = value.value().entrySet();
for (Map.Entry entry : entries) {
if (entry.getKey() instanceof ConstIdentifier) {
throw new IllegalStateException("Not yet implemented");
}
if (entry.getValue() instanceof ConstIdentifier) {
throw new IllegalStateException("Not yet implemented");
}
sb.append(format(" .put(%s, %s)\n",
render(mapType.getKeyType(), entry.getKey()),
render(mapType.getValueType(), entry.getValue())));
}
sb.append(" .build()");
return sb.toString();
}
private String renderListConstant(ListType listType, ConstList value)
{
StringBuilder sb = new StringBuilder();
sb.append("ImmutableList.<");
sb.append(typeConverter.convert(listType.getElementType(), false));
sb.append(">builder()\n");
List elements = value.value();
for (ConstValue element : elements) {
if (element instanceof ConstIdentifier) {
throw new IllegalStateException("Not yet implemented");
}
sb.append(format(" .add(%s)\n", render(listType.getElementType(), element)));
}
sb.append(" .build()");
return sb.toString();
}
private String renderSetConstant(SetType setType, ConstList value)
{
StringBuilder sb = new StringBuilder();
sb.append("ImmutableSet.<");
sb.append(typeConverter.convert(setType.getElementType(), false));
sb.append(">builder()\n");
List elements = value.value();
for (ConstValue element : elements) {
if (element instanceof ConstIdentifier) {
throw new IllegalStateException("Not yet implemented");
}
sb.append(format(" .add(%s)\n", render(setType.getElementType(), element)));
}
sb.append(" .build()");
return sb.toString();
}
private String renderBaseConstant(BaseType baseType, ConstValue value)
{
switch (baseType.getType()) {
case BOOL:
case BYTE:
case I16:
case I32:
case I64:
checkArgument(value instanceof ConstInteger);
return renderIntegerConstant(baseType, (ConstInteger) value);
case STRING:
checkArgument(value instanceof ConstString);
return "\"" + value.value() + "\"";
case DOUBLE:
// Allow auto-promotion of integer types
checkArgument(value.value() instanceof Number);
return Double.toString(((Number) value.value()).doubleValue());
default:
throw new IllegalArgumentException();
}
}
private String renderIntegerConstant(BaseType baseType, ConstInteger value)
{
switch (baseType.getType()) {
case BOOL:
checkArgument(
value.value() == 0 || value.value() == 1,
"Bool constant out of range '" + value.value() + "' (must be 0 or 1)");
return Boolean.toString(value.value() == 0 ? false : true);
case BYTE:
checkArgument(
value.value() >= Byte.MIN_VALUE && value.value() <= Byte.MAX_VALUE,
"Byte constant out of range: '" + value.value() + "'");
return Byte.toString((byte) (long) value.value());
case I16:
return Short.toString(Shorts.checkedCast(value.value()));
case I32:
return Integer.toString(Ints.checkedCast(value.value()));
case I64:
return Long.toString(value.value()) + "L";
default:
throw new IllegalStateException();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy