use of org.infinispan.protostream.annotations.impl.types.XClass in project protostream by infinispan.
the class ReservedProcessorTest method testDuplicateReservedNumber.
@Test
public void testDuplicateReservedNumber() {
expectedException.expect(ProtoSchemaBuilderException.class);
expectedException.expectMessage("Found duplicate @ProtoReserved number 1 in org.infinispan.protostream.annotations.impl.ReservedProcessorTest.DuplicateNumber");
XClass classToTest = new ReflectionTypeFactory().fromClass(DuplicateNumber.class);
new ReservedProcessor().scan(classToTest);
}
use of org.infinispan.protostream.annotations.impl.types.XClass in project protostream by infinispan.
the class MirrorTypeFactoryTest method testFromClass.
@Test
public void testFromClass() {
ProcessingEnvironment processingEnvironmentMock = mock(ProcessingEnvironment.class);
Elements elementsMock = mock(Elements.class);
Types typesMock = mock(Types.class);
when(processingEnvironmentMock.getElementUtils()).thenReturn(elementsMock);
when(processingEnvironmentMock.getTypeUtils()).thenReturn(typesMock);
TypeElement typeElementMock = mock(TypeElement.class);
DeclaredType typeMirrorMock = mock(DeclaredType.class);
when(typeMirrorMock.asElement()).thenReturn(typeElementMock);
when(typeElementMock.asType()).thenReturn(typeMirrorMock);
when(typeMirrorMock.getKind()).thenReturn(TypeKind.DECLARED);
when(typeElementMock.getKind()).thenReturn(ElementKind.CLASS);
Name nameMock = mock(Name.class);
when(nameMock.toString()).thenReturn("java.lang.Integer");
when(typeElementMock.getQualifiedName()).thenReturn(nameMock);
when(elementsMock.getTypeElement("java.lang.Integer")).thenReturn(typeElementMock);
when(elementsMock.getBinaryName(typeElementMock)).thenReturn(nameMock);
MirrorTypeFactory typeFactory = new MirrorTypeFactory(processingEnvironmentMock);
XClass integerClass = typeFactory.fromClass(Integer.class);
assertFalse(integerClass.isArray());
}
use of org.infinispan.protostream.annotations.impl.types.XClass in project protostream by infinispan.
the class ProtoEnumTypeMetadata method generateProto.
@Override
public void generateProto(IndentWriter iw) {
scanMemberAnnotations();
iw.append("\n\n");
appendDocumentation(iw, getDocumentation());
iw.append("enum ").append(name);
if (BaseProtoSchemaGenerator.generateSchemaDebugComments) {
iw.append(" /* ").append(getJavaClassName()).append(" */");
}
iw.append(" {\n");
iw.inc();
ReservedProcessor reserved = new ReservedProcessor();
reserved.scan(annotatedEnumClass);
for (String memberName : membersByName.keySet()) {
XClass where = reserved.checkReserved(name);
if (where != null) {
throw new ProtoSchemaBuilderException("Protobuf enum value " + memberName + " of enum constant " + membersByName.get(memberName).getJavaEnumName() + " conflicts with 'reserved' statement in " + where.getCanonicalName());
}
}
for (int memberNumber : membersByNumber.keySet()) {
XClass where = reserved.checkReserved(memberNumber);
if (where != null) {
throw new ProtoSchemaBuilderException("Protobuf enum number " + memberNumber + " of enum constant " + membersByNumber.get(memberNumber).getJavaEnumName() + " conflicts with 'reserved' statement in " + where.getCanonicalName());
}
}
reserved.generate(iw);
for (ProtoEnumValueMetadata m : membersByNumber.values()) {
m.generateProto(iw);
}
iw.dec();
iw.append("}\n");
}
use of org.infinispan.protostream.annotations.impl.types.XClass in project protostream by infinispan.
the class ProtoSchemaBuilder method build.
/**
* Builds the Protocol Buffers schema file defining the types and generates marshaller implementations for these
* types and registers everything with the given {@link SerializationContext}.The generated classes are defined in
* the given ClassLoader.
*
* @param serializationContext
* @param classLoader the ClassLoader in which the generated classes will be defined. If {@code null}, this
* behaves as {@link #build(SerializationContext)}
* @return the generated Protocol Buffers schema file text
* @throws ProtoSchemaBuilderException
* @throws IOException
*/
public String build(SerializationContext serializationContext, ClassLoader classLoader) throws ProtoSchemaBuilderException, IOException {
ReflectionTypeFactory typeFactory = new ReflectionTypeFactory();
Set<XClass> xclasses = classes.stream().map(typeFactory::fromClass).collect(Collectors.toCollection(LinkedHashSet::new));
BaseProtoSchemaGenerator.generateSchemaDebugComments = generateSchemaDebugComments;
return new RuntimeProtoSchemaGenerator(typeFactory, serializationContext, generator, fileName, packageName, xclasses, autoImportClasses, classLoader).generateAndRegister();
}
use of org.infinispan.protostream.annotations.impl.types.XClass in project protostream by infinispan.
the class BaseProtoSchemaGenerator method generateAndRegister.
public String generateAndRegister() {
// collect supers
for (XClass c : classes) {
collectKnownClasses(c);
}
// scan initial classes
for (XClass c : classes) {
collectMetadata(makeTypeMetadata(c));
}
// scan member annotations and possibly discover more classes being referenced
while (true) {
List<ProtoTypeMetadata> meta = new ArrayList<>(metadataByClass.values());
for (ProtoTypeMetadata m : meta) {
m.scanMemberAnnotations();
}
if (metadataByClass.size() == meta.size()) {
// no new classes were discovered
break;
}
}
// establish the outer-inner relationship between definitions
for (XClass c : metadataByClass.keySet()) {
ProtoTypeMetadata m = metadataByClass.get(c);
if (!m.isImported()) {
ProtoMessageTypeMetadata outer = findOuterType(c);
if (outer != null) {
m.setOuterType(outer);
outer.addInnerType(m);
}
}
}
IndentWriter iw = new IndentWriter();
iw.append("// File name: ").append(fileName).append('\n');
if (generator != null) {
iw.append("// Generated from : ").append(generator).append('\n');
}
if (generateSchemaDebugComments) {
iw.append("// Scanned classes:\n");
// todo [anistor] this list of scanned classes should include all interfaces and base classes not just the ones for which a proto definition was generated
for (ProtoTypeMetadata ptm : metadataByClass.values()) {
if (!ptm.isImported()) {
iw.append("// ").append(ptm.getJavaClassName()).append('\n');
}
}
}
iw.append("\nsyntax = \"proto2\";\n\n");
if (packageName != null) {
iw.append("package ").append(packageName).append(";\n\n");
}
for (String dependency : imports) {
iw.append("import \"").append(dependency).append("\";\n");
}
// generate type definitions for all top-level types, except the ones found in imported files
for (XClass c : metadataByClass.keySet()) {
ProtoTypeMetadata m = metadataByClass.get(c);
if (m.getOuterType() == null && !m.isImported()) {
m.generateProto(iw);
}
}
String protoFile = iw.toString();
if (log.isTraceEnabled()) {
log.tracef("Generated proto file:\n%s", protoFile);
}
serializationContext.registerProtoFiles(FileDescriptorSource.fromString(fileName, protoFile));
try {
generateMarshallers();
} catch (Exception e) {
throw new ProtoSchemaBuilderException("Failed to generate marshaller implementation class", e);
}
return protoFile;
}
Aggregations