use of net.morimekta.providence.model.ProgramType in project providence by morimekta.
the class ThriftProgramParserTest method testParser_annotations.
@Test
public void testParser_annotations() throws IOException {
copyResourceTo("/parser/tests/annotations.thrift", tmp.getRoot());
File annotations = new File(tmp.getRoot(), "annotations.thrift");
ThriftProgramParser parser = new ThriftProgramParser();
ProgramType program = parser.parse(new FileInputStream(annotations), annotations, new TreeSet<>());
assertThat(debugString(program), equalToLines("{\n" + " program_name = \"annotations\"\n" + " namespaces = {\n" + " \"java\": \"net.morimekta.test.annotations\"\n" + " }\n" + " decl = [\n" + " {\n" + " decl_enum = {\n" + " name = \"E\"\n" + " values = [\n" + " {\n" + " name = \"VAL\"\n" + " id = 0\n" + " annotations = {\n" + " \"anno\": \"str\"\n" + " \"anno.other\": \"other\"\n" + " }\n" + " }\n" + " ]\n" + " annotations = {\n" + " \"e.anno\": \"E\"\n" + " }\n" + " }\n" + " },\n" + " {\n" + " decl_struct = {\n" + " variant = EXCEPTION\n" + " name = \"S\"\n" + " fields = [\n" + " {\n" + " id = 1\n" + " type = \"bool\"\n" + " name = \"val\"\n" + " annotations = {\n" + " \"anno\": \"str\"\n" + " }\n" + " }\n" + " ]\n" + " annotations = {\n" + " \"other\": \"\"\n" + " }\n" + " }\n" + " },\n" + " {\n" + " decl_service = {\n" + " name = \"Srv\"\n" + " methods = [\n" + " {\n" + " name = \"method\"\n" + " params = [\n" + " {\n" + " id = 1\n" + " type = \"i32\"\n" + " name = \"param\"\n" + " annotations = {\n" + " \"abba\": \"7\"\n" + " }\n" + " }\n" + " ]\n" + " annotations = {\n" + " \"anno\": \"anno\"\n" + " }\n" + " },\n" + " {\n" + " name = \"method2\"\n" + " params = [\n" + " {\n" + " id = 1\n" + " type = \"i32\"\n" + " name = \"param\"\n" + " annotations = {\n" + " \"abba\": \"7\"\n" + " }\n" + " }\n" + " ]\n" + " exceptions = [\n" + " {\n" + " id = 1\n" + " type = \"S\"\n" + " name = \"e\"\n" + " annotations = {\n" + " \"ex\": \"667\"\n" + " }\n" + " }\n" + " ]\n" + " annotations = {\n" + " \"anno\": \"anno\"\n" + " }\n" + " }\n" + " ]\n" + " annotations = {\n" + " \"bin\": \"bin\"\n" + " \"src\": \"src\"\n" + " }\n" + " }\n" + " }\n" + " ]\n" + "}"));
}
use of net.morimekta.providence.model.ProgramType in project providence by morimekta.
the class ProgramRegistryTest method setUp.
@Before
public void setUp() throws IOException {
File num = ResourceUtils.copyResourceTo("/parser/calculator/number.thrift", tmp.getRoot());
File calc = ResourceUtils.copyResourceTo("/parser/calculator/calculator.thrift", tmp.getRoot());
registry = new ProgramRegistry();
ThriftProgramParser parser = new ThriftProgramParser();
ProgramType pNum = parser.parse(new FileInputStream(num), num, ImmutableSet.of(tmp.getRoot()));
ProgramType pCalc = parser.parse(new FileInputStream(calc), calc, ImmutableSet.of(tmp.getRoot()));
ProgramConverter converter = new ProgramConverter(registry);
registry.putProgram(num.toString(), converter.convert(num.toString(), pNum));
registry.putProgram(calc.toString(), converter.convert(calc.toString(), pCalc));
}
use of net.morimekta.providence.model.ProgramType 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.model.ProgramType in project providence by morimekta.
the class CMessageBuilderTest method setUp.
@Before
public void setUp() throws IOException {
File file = tmp.newFile("test.thrift").getCanonicalFile().getAbsoluteFile();
ProgramRegistry tmp = new ProgramRegistry();
ThriftProgramParser parser = new ThriftProgramParser();
ProgramConverter converter = new ProgramConverter(tmp);
ProgramType program = parser.parse(getClass().getResourceAsStream("/parser/tests/test.thrift"), file, ImmutableList.of());
tmp.putProgram(file.getPath(), converter.convert(file.getPath(), program));
registry = tmp.registryForPath(file.getCanonicalFile().getAbsolutePath());
}
use of net.morimekta.providence.model.ProgramType in project providence by morimekta.
the class CServiceMethodTest method setUp.
@Before
public void setUp() throws IOException {
File numeric = ResourceUtils.copyResourceTo("/parser/calculator/number.thrift", tmp.getRoot());
File calculator = ResourceUtils.copyResourceTo("/parser/calculator/calculator.thrift", tmp.getRoot());
ProgramRegistry registry = new ProgramRegistry();
ThriftProgramParser parser = new ThriftProgramParser();
ProgramConverter converter = new ProgramConverter(registry);
ProgramType program = parser.parse(new FileInputStream(numeric), numeric, ImmutableList.of(tmp.getRoot()));
registry.putProgram(numeric.getCanonicalPath(), converter.convert(numeric.getCanonicalPath(), program));
program = parser.parse(new FileInputStream(calculator), calculator, ImmutableList.of(tmp.getRoot()));
registry.putProgram(calculator.getCanonicalPath(), converter.convert(calculator.getCanonicalPath(), program));
this.registry = registry.registryForPath(calculator.getCanonicalPath());
}
Aggregations