use of net.morimekta.providence.reflect.contained.CStructDescriptor in project providence by morimekta.
the class ProgramConverter method convert.
/**
* Convert document model to declared document.
*
* @param path The program file path.
* @param path Path of the program file to convert.
* @param program Program model to convert.
* @return The declared thrift document.
*/
public CProgram convert(String path, ProgramType program) {
ImmutableList.Builder<PDeclaredDescriptor<?>> declaredTypes = ImmutableList.builder();
ImmutableList.Builder<CConst> constants = ImmutableList.builder();
ImmutableMap.Builder<String, String> typedefs = ImmutableMap.builder();
ImmutableList.Builder<CService> services = ImmutableList.builder();
RecursiveTypeRegistry registry = programRegistry.registryForPath(path);
File dir = new File(path).getParentFile();
if (program.hasIncludes()) {
for (String include : program.getIncludes()) {
String includePath = new File(dir, include).getPath();
registry.registerInclude(ReflectionUtils.programNameFromPath(include), programRegistry.registryForPath(includePath));
}
}
for (Declaration decl : program.getDecl()) {
switch(decl.unionField()) {
case DECL_ENUM:
{
EnumType enumType = decl.getDeclEnum();
int nextValue = PEnumDescriptor.DEFAULT_FIRST_VALUE;
CEnumDescriptor type = new CEnumDescriptor(enumType.getDocumentation(), program.getProgramName(), enumType.getName(), enumType.getAnnotations());
List<CEnumValue> values = new ArrayList<>();
for (EnumValue value : enumType.getValues()) {
int v = value.hasId() ? value.getId() : nextValue;
nextValue = v + 1;
values.add(new CEnumValue(value.getDocumentation(), value.getId(), value.getName(), type, value.getAnnotations()));
}
type.setValues(values);
declaredTypes.add(type);
registry.register(type);
break;
}
case DECL_STRUCT:
{
MessageType messageType = decl.getDeclStruct();
List<CField> fields = new ArrayList<>();
if (messageType.hasFields()) {
fields.addAll(messageType.getFields().stream().map(field -> makeField(registry, program.getProgramName(), field, messageType.getVariant())).collect(Collectors.toList()));
}
PMessageDescriptor<?, ?> type;
switch(messageType.getVariant()) {
case STRUCT:
type = new CStructDescriptor(messageType.getDocumentation(), program.getProgramName(), messageType.getName(), fields, messageType.getAnnotations());
break;
case UNION:
type = new CUnionDescriptor(messageType.getDocumentation(), program.getProgramName(), messageType.getName(), fields, messageType.getAnnotations());
break;
case EXCEPTION:
type = new CExceptionDescriptor(messageType.getDocumentation(), program.getProgramName(), messageType.getName(), fields, messageType.getAnnotations());
break;
default:
throw new UnsupportedOperationException("Unhandled message variant " + messageType.getVariant());
}
declaredTypes.add(type);
registry.register(type);
break;
}
case DECL_CONST:
{
ConstType constant = decl.getDeclConst();
constants.add(makeConst(registry, program.getProgramName(), constant));
break;
}
case DECL_TYPEDEF:
{
typedefs.put(decl.getDeclTypedef().getName(), decl.getDeclTypedef().getType());
registry.registerTypedef(decl.getDeclTypedef().getName(), program.getProgramName(), decl.getDeclTypedef().getType());
break;
}
case DECL_SERVICE:
{
ServiceType serviceType = decl.getDeclService();
ImmutableList.Builder<CServiceMethod> methodBuilder = ImmutableList.builder();
if (serviceType.hasMethods()) {
for (FunctionType sm : serviceType.getMethods()) {
List<CField> rqFields = new ArrayList<>();
if (sm.numParams() > 0) {
for (FieldType field : sm.getParams()) {
rqFields.add(makeField(registry, program.getProgramName(), field, MessageVariant.STRUCT));
}
}
CStructDescriptor request = new CStructDescriptor(null, program.getProgramName(), serviceType.getName() + '.' + sm.getName() + ".request", rqFields, null);
CUnionDescriptor response = null;
if (!sm.isOneWay()) {
List<CField> rsFields = new ArrayList<>();
CField success;
if (sm.getReturnType() != null) {
PDescriptorProvider type = registry.getProvider(sm.getReturnType(), program.getProgramName(), sm.getAnnotations());
success = new CField(null, 0, PRequirement.OPTIONAL, "success", type, null, null);
} else {
success = new CField(null, 0, PRequirement.OPTIONAL, "success", PPrimitive.VOID.provider(), null, null);
}
rsFields.add(success);
if (sm.numExceptions() > 0) {
for (FieldType field : sm.getExceptions()) {
rsFields.add(makeField(registry, program.getProgramName(), field, MessageVariant.UNION));
}
}
response = new CUnionDescriptor(null, program.getProgramName(), serviceType.getName() + '.' + sm.getName() + ".response", rsFields, null);
}
CServiceMethod method = new CServiceMethod(sm.getDocumentation(), sm.getName(), sm.isOneWay(), request, response, sm.getAnnotations());
methodBuilder.add(method);
}
// for each method
}
// if has methods
PServiceProvider extendsProvider = null;
if (serviceType.hasExtend()) {
extendsProvider = registry.getServiceProvider(serviceType.getExtend(), program.getProgramName());
}
CService service = new CService(serviceType.getDocumentation(), program.getProgramName(), serviceType.getName(), extendsProvider, methodBuilder.build(), serviceType.getAnnotations());
services.add(service);
registry.registerRecursively(service);
}
}
}
return new CProgram(path, program.getDocumentation(), program.getProgramName(), program.getNamespaces(), getIncludedProgramNames(program), program.getIncludes(), typedefs.build(), declaredTypes.build(), services.build(), constants.build());
}
use of net.morimekta.providence.reflect.contained.CStructDescriptor in project providence by morimekta.
the class HazelcastPortableProgramFormatter method appendCreateMethod.
/**
* Method to write the create method from implemented PortableFactory
*
* @param messages List with CStructDescriptor.
* <pre>
* {@code
* @Override
* public com.hazelcast.nio.serialization.Portable create(int classId) {
* switch(classId) {
* ...
* default: {
* return null;
* }
* }
* }
* }
* </pre>
*/
private void appendCreateMethod(List<CStructDescriptor> messages) {
writer.appendln("@Override").formatln("public %s create(int classId) {", Portable.class.getName()).begin().appendln("switch(classId) {").begin();
for (CStructDescriptor message : messages) {
writer.formatln("case %s: {", getHazelcastClassId(message.getName())).begin().formatln("return new %s.%s();", message.getName(), HazelcastPortableMessageFormatter.WRAPPER_CLASS_NAME).end().appendln("}");
}
writer.appendln("default: {").begin().appendln("return null;").end().appendln("}").end();
writer.appendln("}").end().appendln("}").newline();
}
use of net.morimekta.providence.reflect.contained.CStructDescriptor in project providence by morimekta.
the class HazelcastPortableProgramFormatter method appendProgramClass.
@Override
public void appendProgramClass(CProgram document) throws GeneratorException {
if (document.getDocumentation() != null) {
new BlockCommentBuilder(writer).comment(document.getDocumentation()).finish();
}
if (javaOptions.generated_annotation_version) {
writer.formatln("@%s(\"%s %s\")", Generated.class.getName(), generatorOptions.generator_program_name, generatorOptions.program_version);
} else {
writer.formatln("@%s(\"%s\")", Generated.class.getName(), generatorOptions.generator_program_name);
}
writer.formatln("public class %s {", helper.getHazelcastFactoryClassName(document)).begin().newline();
Optional<CConst> factoryID = document.getConstants().stream().filter(t -> t.getName().equals(FACTORY_ID)).findFirst();
if (!factoryID.isPresent()) {
throw new GeneratorException("Need to provide \"const i32 FACTORY_ID = ?\" in the thrift file for " + "hazelcast generation!");
} else {
CConst c = factoryID.get();
String type = helper.getValueType(c.getDescriptor());
String name = c.getName();
writer.formatln("public static final %s %s = %s.%s;", type, name, helper.getConstantsClassName(document), name).newline();
}
List<CStructDescriptor> messages = new ArrayList<>();
for (PDeclaredDescriptor c : document.getDeclaredTypes()) {
try {
if (PType.MESSAGE == c.getType() && c instanceof CStructDescriptor) {
CStructDescriptor message = (CStructDescriptor) c;
if (message.hasAnnotation(ThriftAnnotation.JAVA_HAZELCAST_CLASS_ID)) {
writer.formatln("public static final int %s = %s;", getHazelcastClassId(message.getName()), message.getAnnotationValue(ThriftAnnotation.JAVA_HAZELCAST_CLASS_ID));
messages.add(message);
}
}
} catch (Exception e) {
throw new GeneratorException(e.getMessage());
}
}
writer.newline();
appendPopulateMethod(messages);
if (messages.isEmpty()) {
throw new GeneratorException("No annotations available to generate!");
} else {
writer.formatln("private static class %s implements %s {", FACTORY_IMPL, PortableFactory.class.getName()).begin().newline();
appendCreateMethod(messages);
appendGetDefinitions(messages);
writer.end().appendln("}");
}
writer.end().appendln("}").newline();
}
use of net.morimekta.providence.reflect.contained.CStructDescriptor in project providence by morimekta.
the class HazelcastPortableProgramFormatter method appendPopulateMethod.
/**
* Method to append populate methods for the Hazelcast Config.
*
* @param messages List with CStructDescriptor to iterate through.
* <pre>
* {@code
* public static final com.hazelcast.config.Config populateConfig(com.hazelcast.config.Config config) {
* PortableFactoryImpl instance = new PortableFactoryImpl();
* config.getSerializationConfig().addPortableFactory(FACTORY_ID, instance);
* ...
* return config;
* }
* }
* </pre>
*/
private void appendPopulateMethod(List<CStructDescriptor> messages) {
writer.formatln("public static final %s populateConfig(%s %s, int %s) {", Config.class.getName(), Config.class.getName(), CONFIG, PORTABLE_VERSION).begin().formatln("%s %s = new %s();", FACTORY_IMPL, INSTANCE, FACTORY_IMPL).formatln("%s.getSerializationConfig().addPortableFactory(%s, %s);", CONFIG, FACTORY_ID, INSTANCE).formatln("%s.getSerializationConfig().setPortableVersion(%s);", CONFIG, PORTABLE_VERSION).appendln().formatln("%s.getSerializationConfig()", CONFIG).begin().begin();
for (CStructDescriptor struct : messages) {
writer.formatln(".addClassDefinition(%s.%s(%s))", INSTANCE, camelCase("get", struct.getName() + "Definition"), PORTABLE_VERSION);
}
writer.append(";").end().end().formatln("return %s;", CONFIG).end().appendln("}").newline();
}
use of net.morimekta.providence.reflect.contained.CStructDescriptor in project providence by morimekta.
the class Convert method run.
@SuppressWarnings("unchecked")
void run(String... args) {
try {
ArgumentParser cli = options.getArgumentParser("pvd", "Providence Converter");
try {
cli.parse(args);
if (options.showHelp()) {
System.out.println(cli.getProgramDescription());
System.out.println("Usage: " + cli.getSingleLineUsage());
System.out.println();
System.out.println("Example code to run:");
System.out.println("$ cat call.json | pvd -I thrift/ -S cal.Calculator");
System.out.println("$ pvd -i binary,file:my.data -o json_protocol -I thrift/ cal.Operation");
System.out.println();
System.out.println("Note that when handling service calls, only 1 call can be converted.");
System.out.println();
cli.printUsage(System.out);
System.out.println();
System.out.println("Available formats are:");
for (Format format : Format.values()) {
System.out.println(String.format(" - %-20s : %s", format.name(), format.desc));
}
return;
}
if (options.showVersion()) {
System.out.println(cli.getProgramDescription());
return;
}
if (options.listTypes) {
ProgramRegistry registry = options.getProgramRegistry();
for (ProgramTypeRegistry pr : registry.getLoadedRegistries()) {
CProgram program = pr.getProgram();
System.out.println(program.getProgramFilePath() + ":");
for (PDeclaredDescriptor dd : program.getDeclaredTypes()) {
if (dd instanceof CStructDescriptor) {
System.out.println(" struct " + dd.getQualifiedName());
} else if (dd instanceof CUnionDescriptor) {
System.out.println(" union " + dd.getQualifiedName());
} else if (dd instanceof CExceptionDescriptor) {
System.out.println(" exception " + dd.getQualifiedName());
}
}
for (PService s : program.getServices()) {
System.out.println(" service " + s.getQualifiedName());
}
}
return;
}
cli.validate();
if (options.getDefinition() == null) {
MessageReader in = options.getServiceInput();
MessageWriter out = options.getServiceOutput();
PService service = options.getServiceDefinition();
PServiceCall call = in.read(service);
in.close();
out.write(call);
out.separator();
out.close();
// TODO: Validate we don't have garbage data after call.
if (options.out.base64mime && options.out.file == null) {
System.out.println();
}
} else {
AtomicInteger num = new AtomicInteger(0);
int size = options.getInput().peek(m -> num.incrementAndGet()).collect(options.getOutput());
if (num.get() == 0 || size == 0) {
throw new IOException("No data");
}
if (options.out.base64mime && options.out.file == null) {
System.out.println();
}
}
return;
} catch (ArgumentException e) {
System.err.println(e.getMessage());
System.out.println("Usage: " + cli.getSingleLineUsage());
System.err.println();
System.err.println("Run $ pvd --help # for available options.");
if (options.verbose()) {
System.err.println();
e.printStackTrace();
}
} catch (SerializerException e) {
System.out.flush();
System.err.println();
System.err.println(e.asString());
if (options.verbose()) {
System.err.println();
e.printStackTrace();
}
} catch (UncheckedIOException | IOException e) {
System.out.flush();
System.err.println();
System.err.println("I/O error: " + e.getMessage());
if (options.verbose()) {
System.err.println();
e.printStackTrace();
}
}
} catch (Exception e) {
System.out.flush();
System.err.println();
System.err.println("Unchecked exception: " + e.getMessage());
if (options.verbose()) {
System.err.println();
e.printStackTrace();
}
}
exit(1);
}
Aggregations