Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public SourceCodeDirectory mainGrpc() {
* The directory for the test source code generated by gRPC.
*/
public SourceCodeDirectory testGrpc() {
return new SourceDir(getMain(), GRPC_DIR);
return new SourceDir(getTest(), GRPC_DIR);
}

/**
Expand All @@ -176,7 +176,6 @@ public SourceCodeDirectory mainResources() {
/**
* The directory for generated test resources.
*/
@SuppressWarnings("unused") // reserved for future use.
public SourceCodeDirectory testResources() {
return new SourceDir(getTest(), RESOURCES_DIR);
}
Expand Down
10 changes: 5 additions & 5 deletions base/src/main/java/io/spine/code/java/SourceFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static SourceFile forOuterClassOf(FileDescriptorProto file) {
checkNotNull(file);
FileName filename = SimpleClassName.outerOf(file)
.toFileName();
SourceFile result = getFolder(file).resolve(filename);
SourceFile result = getGeneratedFolder(file).resolve(filename);
return result;
}

Expand All @@ -70,7 +70,7 @@ public static SourceFile forOuterClassOf(FileDescriptorProto file) {
* the proto file descriptor
* @return the relative folder path
*/
private static Directory getFolder(FileDescriptorProto file) {
private static Directory getGeneratedFolder(FileDescriptorProto file) {
checkNotNull(file);
PackageName packageName = PackageName.resolve(file);
Directory result = packageName.toDirectory();
Expand Down Expand Up @@ -120,7 +120,7 @@ private static SourceFile forMessageOrInterface(DescriptorProto message,
}
if (file.getOptions().getJavaMultipleFiles()) {
FileName filename = fileName.apply(message);
SourceFile result = getFolder(file).resolve(filename);
SourceFile result = getGeneratedFolder(file).resolve(filename);
return result;
} else {
SourceFile result = forOuterClassOf(file);
Expand Down Expand Up @@ -153,7 +153,7 @@ public static SourceFile forEnum(EnumDescriptorProto enumType, FileDescriptorPro
}
if (file.getOptions().getJavaMultipleFiles()) {
FileName filename = FileName.forEnum(enumType);
SourceFile result = getFolder(file).resolve(filename);
SourceFile result = getGeneratedFolder(file).resolve(filename);
return result;
} else {
SourceFile result = forOuterClassOf(file);
Expand All @@ -180,7 +180,7 @@ public static SourceFile forService(ServiceDescriptorProto service, FileDescript
}

FileName filename = FileName.forService(service);
SourceFile result = getFolder(file).resolve(filename);
SourceFile result = getGeneratedFolder(file).resolve(filename);
return result;
}

Expand Down
3 changes: 1 addition & 2 deletions base/src/main/java/io/spine/validate/FieldValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,7 @@ protected final List<ConstraintViolation> validate() {
private void checkCanBeRequired() {
boolean fieldIsRequired = isRequiredField();
if (!canBeRequired && fieldIsRequired) {
String messageFormat = "Fields of type %s should not be declared as `(required)`.";
_warn(messageFormat, field().typeName());
_warn("Fields of type {} should not be declared as `(required)`.", field().typeName());
}
}

Expand Down
10 changes: 1 addition & 9 deletions base/src/main/proto/spine/options.proto
Original file line number Diff line number Diff line change
Expand Up @@ -145,17 +145,9 @@ extend google.protobuf.FieldOptions {
// wired into the framework, you may use the internal parts. Please consult with the Spine
// team, as the internal APIs do not have the same stability API guarantee as public ones.
//
// See `SPI` option if you plan to write an extension of the framework.
//
bool internal = 73850;

// Indicates a file which contains elements of Service Provider Interface (SPI).
//
// SPI is used to enable framework extension and replaceable components (implement a new
// storage, etc). See "Effective Java 2nd Edition", chapter 2, item 1 for more info about
// service provider framework pattern.
//
bool SPI = 73851;
// reserved 73851 for the deleted SPI option.

// Indicates a field that can change at any time, and has no guarantee of API stability and
// backward-compatibility.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FileDescriptor;
import com.google.protobuf.Descriptors.GenericDescriptor;
import com.google.protobuf.GeneratedMessage.GeneratedExtension;
import com.google.protobuf.GeneratedMessageV3.ExtendableMessage;
import io.spine.code.java.ClassName;
import io.spine.code.java.SourceFile;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.jboss.forge.roaster.Roaster;
Expand All @@ -37,12 +36,10 @@

import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;
import java.util.Optional;

import static com.google.common.base.Preconditions.checkNotNull;
import static io.spine.code.java.SourceFile.forMessage;
Expand All @@ -63,24 +60,22 @@
* <p>Depending on the option type, an annotator manages a corresponding Protobuf descriptor
* (e.g. {@code FileDescriptorProto} for {@code FileOptions}).
*
* @param <O>
* the type of Protobuf option, which is managed by the annotator
* @param <D>
* the proto descriptor type used to receive {@link #option} value
*/
public abstract class Annotator<O extends ExtendableMessage, D extends GenericDescriptor> {
public abstract class Annotator<D extends GenericDescriptor> {

/**
* An annotation class.
* The name of the Java class of the annotation to apply.
*/
private final Class<? extends Annotation> annotation;
private final ClassName annotation;

/**
* An Protobuf option, that tells whether generated program elements should be annotated.
*
* <p>Can be of any option type, which is {@code boolean}.
*/
private final GeneratedExtension<O, Boolean> option;
private final ApiOption option;

/**
* Protobuf file descriptors to process.
Expand All @@ -92,8 +87,8 @@ public abstract class Annotator<O extends ExtendableMessage, D extends GenericDe
*/
private final String genProtoDir;

protected Annotator(Class<? extends Annotation> annotation,
GeneratedExtension<O, Boolean> option,
protected Annotator(ClassName annotation,
ApiOption option,
Collection<FileDescriptor> fileDescriptors,
String genProtoDir) {
this.annotation = checkNotNull(annotation);
Expand Down Expand Up @@ -150,8 +145,10 @@ protected final void annotate(FileDescriptor fileDescriptor) {
* the descriptor to extract {@link #option} value.
* @return {@code true} if generated element should be annotated, {@code false} otherwise
*/
protected final boolean shouldAnnotate(D descriptor) {
return getOptionValue(descriptor).orElse(false);
protected abstract boolean shouldAnnotate(D descriptor);

protected final ApiOption option() {
return option;
}

/**
Expand All @@ -172,24 +169,6 @@ protected final void annotate(SourceFile relativeSourcePath) {
rewriteSource(relativeSourcePath, new TypeDeclarationAnnotation());
}

/**
* Obtains the value of {@link #option} in the specified descriptor.
*
* @param descriptor
* the descriptor to extract {@link #option} value.
* @return the option value
*/
protected abstract Optional<Boolean> getOptionValue(D descriptor);

/**
* Obtains the {@link #option} number.
*
* @return the option number
*/
protected final GeneratedExtension<O, Boolean> getOption() {
return option;
}

/**
* Rewrites a generated Java source with the specified
* relative path after applying a {@link SourceVisitor}.
Expand Down Expand Up @@ -256,14 +235,12 @@ private static AbstractJavaSource<?> parse(Path sourcePath) {
* the program element to annotate
*/
protected final void addAnnotation(AnnotationTargetSource<?, ?> source) {
AnnotationSource<?> annotation = source.getAnnotation(this.annotation);
if (annotation != null) {
return;
String annotationFQN = annotation.value();
AnnotationSource<?> annotation = source.getAnnotation(annotationFQN);
if (annotation == null) {
AnnotationSource newAnnotation = source.addAnnotation();
newAnnotation.setName(annotationFQN);
}

String annotationFQN = this.annotation.getCanonicalName();
AnnotationSource newAnnotation = source.addAnnotation();
newAnnotation.setName(annotationFQN);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,39 +21,17 @@
package io.spine.tools.compiler.annotation;

import com.google.common.collect.ImmutableList;
import com.google.protobuf.DescriptorProtos.FieldOptions;
import com.google.protobuf.DescriptorProtos.FileOptions;
import com.google.protobuf.DescriptorProtos.MessageOptions;
import com.google.protobuf.DescriptorProtos.ServiceOptions;
import com.google.protobuf.Descriptors.FileDescriptor;
import com.google.protobuf.GeneratedMessage.GeneratedExtension;
import io.spine.annotation.Beta;
import io.spine.annotation.Experimental;
import io.spine.annotation.Internal;
import io.spine.annotation.SPI;
import io.spine.code.java.ClassName;
import io.spine.code.proto.FileDescriptors;
import io.spine.code.proto.FileSet;

import java.io.File;
import java.lang.annotation.Annotation;
import java.util.Collection;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import static io.spine.option.OptionsProto.beta;
import static io.spine.option.OptionsProto.betaAll;
import static io.spine.option.OptionsProto.betaType;
import static io.spine.option.OptionsProto.experimental;
import static io.spine.option.OptionsProto.experimentalAll;
import static io.spine.option.OptionsProto.experimentalType;
import static io.spine.option.OptionsProto.internal;
import static io.spine.option.OptionsProto.internalAll;
import static io.spine.option.OptionsProto.internalType;
import static io.spine.option.OptionsProto.sPI;
import static io.spine.option.OptionsProto.sPIAll;
import static io.spine.option.OptionsProto.sPIService;
import static io.spine.option.OptionsProto.sPIType;
import static java.util.stream.Collectors.toSet;

/**
Expand Down Expand Up @@ -89,66 +67,32 @@ private AnnotatorFactory(Collection<FileDescriptor> fileDescriptors,
this.genGrpcDir = genGrpcDir;
}

public static void process(File descriptorSetFile,
String generatedProtoDir,
String generatedGrpcDir) {
public static AnnotatorFactory newInstance(File descriptorSetFile,
String generatedProtoDir,
String generatedGrpcDir) {
Collection<FileDescriptor> descriptors = FileSet
.parse(descriptorSetFile)
.files()
.stream()
.filter(FileDescriptors::isNotGoogle)
.collect(toSet());
AnnotatorFactory factory =
new AnnotatorFactory(descriptors, generatedProtoDir, generatedGrpcDir);

factory.createFileAnnotator(Experimental.class, experimentalAll)
.annotate();
factory.createMessageAnnotator(Experimental.class, experimentalType)
.annotate();
factory.createFieldAnnotator(Experimental.class, experimental)
.annotate();

factory.createFileAnnotator(Beta.class, betaAll)
.annotate();
factory.createMessageAnnotator(Beta.class, betaType)
.annotate();
factory.createFieldAnnotator(Beta.class, beta)
.annotate();

factory.createFileAnnotator(SPI.class, sPIAll)
.annotate();
factory.createMessageAnnotator(SPI.class, sPIType)
.annotate();
factory.createServiceAnnotator(SPI.class, sPIService)
.annotate();
factory.createFieldAnnotator(SPI.class, sPI)
.annotate();

factory.createFileAnnotator(Internal.class, internalAll)
.annotate();
factory.createMessageAnnotator(Internal.class, internalType)
.annotate();
factory.createFieldAnnotator(Internal.class, internal)
.annotate();
return new AnnotatorFactory(descriptors, generatedProtoDir,generatedGrpcDir);
}

private Annotator createFileAnnotator(Class<? extends Annotation> annotation,
GeneratedExtension<FileOptions, Boolean> option) {
Annotator createFileAnnotator(ClassName annotation, ApiOption option) {
return new FileAnnotator(annotation, option, fileDescriptors, genProtoDir, genGrpcDir);
}

private Annotator createMessageAnnotator(Class<? extends Annotation> annotation,
GeneratedExtension<MessageOptions, Boolean> option) {
Annotator createMessageAnnotator(ClassName annotation, ApiOption option) {
return new MessageAnnotator(annotation, option, fileDescriptors, genProtoDir);
}

private Annotator createFieldAnnotator(Class<? extends Annotation> annotation,
GeneratedExtension<FieldOptions, Boolean> option) {
Annotator createFieldAnnotator(ClassName annotation, ApiOption option) {
return new FieldAnnotator(annotation, option, fileDescriptors, genProtoDir);
}

private Annotator createServiceAnnotator(Class<? extends Annotation> annotation,
GeneratedExtension<ServiceOptions, Boolean> option) {
Annotator createServiceAnnotator(ClassName annotation,
ApiOption option) {
return new ServiceAnnotator(annotation, option, fileDescriptors, genGrpcDir);
}
}
Loading