@Override public Either<TypeDefinition, Type> visitList(ListType value) { return Either.right(Type.list(value)); }
@Override public Either<TypeDefinition, Type> visitMap(MapType value) { return Either.right(Type.map(value)); }
@Override public Either<TypeDefinition, Type> visitOptional(OptionalType value) { return Either.right(Type.optional(value)); }
@Test public void testRecursiveTypeOkInReference() { Type referenceType = Type.reference(FOO); TypeDefinition objectDefinition = TypeDefinition.object( ObjectDefinition.builder() .typeName(TypeName.of("Foo", "bar")) .addAllFields(ImmutableList.of( FieldDefinition.of(FieldName.of("selfOptional"), Type.optional(OptionalType.of(Type.reference(FOO))), DOCS), FieldDefinition.of(FieldName.of("selfMap"), Type.map(MapType.of(referenceType, referenceType)), DOCS), FieldDefinition.of(FieldName.of("selfSet"), Type.set(SetType.of(referenceType)), DOCS), FieldDefinition.of(FieldName.of("selfList"), Type.list(ListType.of(referenceType)), DOCS))) .build()); ConjureDefinition conjureDef = ConjureDefinition.builder() .version(1) .types(ImmutableList.of(objectDefinition)) .build(); ConjureDefinitionValidator.NO_RECURSIVE_TYPES.validate(conjureDef); }
@Test public void testNoComplexKeysInMaps() { String illegalFieldName = "asdf"; Type complexKeyType = Type.list(ListType.of(Type.primitive(PrimitiveType.STRING))); FieldDefinition fieldDefinition = FieldDefinition.of( FieldName.of(illegalFieldName), Type.map(MapType.of(complexKeyType, Type.primitive(PrimitiveType.STRING))), Documentation.of("docs")); assertThatThrownBy(() -> FieldDefinitionValidator.validate(fieldDefinition)) .isInstanceOf(IllegalStateException.class) .hasMessageContaining(illegalFieldName) .hasMessageContaining(complexKeyType.toString()); } }
@Override public Type visitAny(AnyType type) { return Type.primitive(com.palantir.conjure.spec.PrimitiveType.ANY); }
/** * Inlines outer-level aliases and references, but not within objects or container types. * <p> * For example, a reference to an alias A which wraps another alias B which wraps a {@code list<integer>}, we'll * return {@code list<integer>}. Note that these are outer-level references being resolved. * However, if the aforementioned list's inner type was also a reference e.g. {@code list<C>}, we * wouldn't unwrap that, so we'd just return the same {@code list<C>}. */ public Either<TypeDefinition, Type> dealias(Type type) { return type.accept(this); }
@Test public void testComplexHeader() { EndpointDefinition.Builder definition = EndpointDefinition.builder() .args(ArgumentDefinition.builder() .argName(ArgumentName.of("someName")) .type(Type.list(ListType.builder().itemType(Type.primitive(PrimitiveType.STRING)).build())) .paramType(ParameterType.header(HeaderParameterType.of(ParameterId.of("someId")))) .build()) .endpointName(ENDPOINT_NAME) .httpMethod(HttpMethod.GET) .httpPath(HttpPath.of("/a/path")); assertThatThrownBy(() -> EndpointDefinitionValidator.validateAll(definition.build(), emptyDealiasingVisitor)) .isInstanceOf(IllegalStateException.class) .hasMessage("Header parameters must be enums, primitives, aliases or optional primitive:" + " \"someName\" is not allowed"); }
@Override public Either<TypeDefinition, Type> visitSet(SetType value) { return Either.right(Type.set(value)); }
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)); } } }
private FieldDefinition field(FieldName name, String type) { return FieldDefinition.of(name, Type.reference(TypeName.of(type, PACKAGE)), DOCS); } }
@Override public Type visitDateTime(DateTimeType type) { return Type.primitive(com.palantir.conjure.spec.PrimitiveType.DATETIME); } }
/** * Inlines outer-level aliases and references, but not within objects or container types. * <p> * For example, a reference to an alias A which wraps another alias B which wraps a {@code list<integer>}, we'll * return {@code list<integer>}. Note that these are outer-level references being resolved. * However, if the aforementioned list's inner type was also a reference e.g. {@code list<C>}, we * wouldn't unwrap that, so we'd just return the same {@code list<C>}. */ public Either<TypeDefinition, Type> dealias(Type type) { return type.accept(this); }
@Override public Either<TypeDefinition, Type> visitSet(SetType value) { return Either.right(Type.set(value)); }
@Test public void testNoSelfRecursiveType() { ConjureDefinition conjureDef = ConjureDefinition.builder() .version(1) .types(ImmutableList.of(TypeDefinition.object( ObjectDefinition.builder() .typeName(FOO) .fields(FieldDefinition.of(FieldName.of("self"), Type.reference(FOO), DOCS)) .build()))) .build(); assertThatThrownBy(() -> ConjureDefinitionValidator.NO_RECURSIVE_TYPES.validate(conjureDef)) .isInstanceOf(IllegalStateException.class) .hasMessage("Illegal recursive data type: Foo -> Foo"); }
@Override public Type visitBinary(BinaryType type) { return Type.primitive(com.palantir.conjure.spec.PrimitiveType.BINARY); }
private static Optional<TypeName> resolveReferenceType(Type type) { if (type.accept(TypeVisitor.IS_REFERENCE)) { return Optional.of(type.accept(TypeVisitor.REFERENCE)); } else if (type.accept(TypeVisitor.IS_PRIMITIVE)) { return Optional.of( TypeName.of(type.accept(TypeVisitor.PRIMITIVE).get().name(), "")); } return Optional.empty(); }
@Override public Either<TypeDefinition, Type> visitList(ListType value) { return Either.right(Type.list(value)); }
@Override public Either<TypeDefinition, Type> visitOptional(OptionalType value) { return Either.right(Type.optional(value)); }
@Override public Either<TypeDefinition, Type> visitMap(MapType value) { return Either.right(Type.map(value)); }