@Value.Default default TypesDefinition types() { return TypesDefinition.builder().build(); }
public static void recordMetrics(ConjureSourceFile definition) { Optional.ofNullable(SharedMetricRegistries.tryGetDefault()).ifPresent(metrics -> { metrics.counter(MetricRegistry.name(TypesDefinition.class, "conjure-imports")) .inc(definition.types().conjureImports().size()); metrics.counter(MetricRegistry.name(TypesDefinition.class, "imports")) .inc(definition.types().imports().size()); metrics.counter(MetricRegistry.name(NamedTypesDefinition.class, "services")) .inc(definition.services().size()); metrics.counter(MetricRegistry.name(NamedTypesDefinition.class, "types")) .inc(definition.types().definitions().objects().size()); metrics.counter(MetricRegistry.name(NamedTypesDefinition.class, "empty-default-conjure-package")) .inc(definition.types().definitions().defaultConjurePackage().isPresent() ? 0 : 1); metrics.counter(MetricRegistry.name(NamedTypesDefinition.class, "errors")) .inc(definition.types().definitions().errors().size()); }); } }
private ConjureSourceFile parseInternal(File file) { // Note(rfink): The mechanism of parsing the ConjureSourceFile and the imports separately isn't pretty, // but it's better than the previous implementation where ConjureImports types were passed around all // over the place. Main obstacle to simpler parsing is that Jackson parsers don't have context, i.e., it's // impossible to know the base-path w.r.t. which the imported file is declared. if (!Files.exists(file.toPath())) { throw new ImportNotFoundException(file); } try { ConjureSourceFile definition = MAPPER.readValue(file, ConjureSourceFile.class); Map<Namespace, ConjureImports> imports = parseImports(definition.types().conjureImports(), file.toPath().getParent()); return ConjureSourceFile.builder() .from(definition) .types(TypesDefinition.builder() .from(definition.types()) .conjureImports(imports) .build()) .build(); } catch (IOException e) { throw new RuntimeException(e); } }
private static Map<TypeName, TypeDefinition> parseImportObjects(Map<Namespace, ConjureImports> conjureImports) { Map<TypeName, TypeDefinition> allDefinitions = Maps.newHashMap(); conjureImports.values().forEach(conjureImport -> { ConjureSourceFile conjureDef = conjureImport.conjure(); ReferenceTypeResolver importTypeResolver = new ConjureTypeParserVisitor.ByParsedRepresentationTypeNameResolver(conjureDef.types()); allDefinitions.putAll(parseImportObjects(conjureDef.types().conjureImports())); allDefinitions.putAll(parseObjects(conjureDef.types(), importTypeResolver)); }); return allDefinitions; }
private static Type resolveFromTypeName( com.palantir.conjure.parser.types.names.TypeName name, TypesDefinition types) { Optional<String> defaultPackage = types.definitions().defaultConjurePackage().map(ConjureParserUtils::parseConjurePackage); BaseObjectTypeDefinition maybeDirectDef = types.definitions().objects().get(name); String conjurePackage; String typeName; if (maybeDirectDef == null) { ExternalTypeDefinition maybeExternalDef = types.imports().get(name); if (maybeExternalDef == null) { throw new IllegalStateException("Unknown LocalReferenceType: " + name); } String externalPath = maybeExternalDef.external().java(); int lastIndex = externalPath.lastIndexOf("."); conjurePackage = externalPath.substring(0, lastIndex); typeName = externalPath.substring(lastIndex + 1); return Type.external(ExternalReference.builder() .externalReference(TypeName.of(typeName, conjurePackage)) .fallback(ConjureParserUtils.parsePrimitiveType(maybeExternalDef.baseType())) .build()); } else { // Conjure-defined object conjurePackage = ConjureParserUtils.parsePackageOrElseThrow( maybeDirectDef.conjurePackage(), defaultPackage); return Type.reference(TypeName.of(name.name(), conjurePackage)); } } }
Map<TypeName, TypeDefinition> importedObjects = parseImportObjects(parsed.types().conjureImports()); Map<TypeName, TypeDefinition> allObjects = Maps.newHashMap(); allObjects.putAll(objects); errorsBuilder.addAll(parseErrors(parsed.types().definitions(), typeResolver)); });
@Test public void testConjureExternalImports() { ConjureSourceFile conjure = ConjureParser.parse(new File("src/test/resources/example-external-types.yml")); assertThat(conjure.types().imports().get(TypeName.of("ExampleAnyImport")).baseType()) .isEqualTo(PrimitiveType.fromString("any")); }
static Map<TypeName, TypeDefinition> parseObjects( com.palantir.conjure.parser.types.TypesDefinition parsed, ConjureTypeParserVisitor.ReferenceTypeResolver typeResolver) { Optional<String> defaultPackage = parsed.definitions().defaultConjurePackage().map(ConjurePackage::name); // no need to use validator here since TypeDefinitionParserVisitor calls each TypeDefinition parser that // validates its type. return parsed.definitions().objects().entrySet().stream() .map(entry -> entry.getValue().visit( new TypeDefinitionParserVisitor(entry.getKey().name(), defaultPackage, typeResolver))) .collect(Collectors.toMap(td -> td.accept(TypeDefinitionVisitor.TYPE_NAME), td -> td)); }
@Override public Type resolve(ForeignReferenceType reference) { ConjureImports conjureImports = types.conjureImports().get(reference.namespace()); Preconditions.checkNotNull(conjureImports, "Import not found for namespace: %s", reference.namespace()); return resolveFromTypeName(reference.type(), conjureImports.conjure().types()); }
@Test public void testConjureInlinedImports() throws IOException { ConjureSourceFile conjure = ConjureParser.parse(new File("src/test/resources/example-conjure-imports.yml")); assertThat(conjure.types().conjureImports()).containsKey(Namespace.of("imports")); }
assertThat(def).isEqualTo( ConjureSourceFile.builder() .types(TypesDefinition.builder() .putImports(TypeName.of("ResourceIdentifier"), ExternalTypeDefinition.javaType(
@Test public void testConjureRevisitedImports() throws IOException { // create a hierarchy of dependencies such that a significant amount of files is visited repeatedly // each file depends on all files from the previous level List<String> inners = ImmutableList.of("innerOne", "innerTwo", "innerThree", "innerFour", "innerFive", "innerSix", "innerSeven", "innerEight", "innerNine", "innerTen"); List<String> mid = ImmutableList.of("midOne", "midTwo", "midThree", "midFour", "midFive"); List<String> top = ImmutableList.of("topOne", "topTwo", "topThree", "topFour", "topFive", "topSix"); String root = "root"; generateFiles(inners, ImmutableList.of()); generateFiles(mid, inners); generateFiles(top, mid); generateFiles(ImmutableList.of(root), top); ConjureSourceFile result = ConjureParser.parse( temporaryFolder.getRoot().toPath().resolve(root + ".yml").toFile()); assertThat(result.types().conjureImports()).isNotEmpty(); }