From 3d0a5c0eaaf77b61d870bf04ebe91d1b081bcdec Mon Sep 17 00:00:00 2001 From: Dmitrii Duzhinskii Date: Thu, 7 Sep 2023 16:54:33 +0300 Subject: [PATCH] Descriptors cleanup --- .../org/sudu/protogen/ProtogenGenerator.java | 8 +- .../protogen/config/naming/NamingManager.java | 2 +- .../config/naming/SuduNamingManager.java | 8 +- .../org/sudu/protogen/descriptors/Enum.java | 48 +++++----- .../protogen/descriptors/EnumOrMessage.java | 77 +++++----------- .../org/sudu/protogen/descriptors/Field.java | 26 ++---- .../org/sudu/protogen/descriptors/File.java | 74 ++++++--------- .../sudu/protogen/descriptors/Message.java | 91 ++++++++++--------- .../org/sudu/protogen/descriptors/Method.java | 31 +++---- .../sudu/protogen/descriptors/Service.java | 31 ++++--- .../generator/EnumOrMessageGenerator.java | 30 ++++++ .../protogen/generator/GenerationContext.java | 12 +-- .../sudu/protogen/generator/Generator.java | 52 +++-------- .../client/DomainRequestMethodBuilder.java | 2 +- .../client/GrpcCallMethodGenerator.java | 2 +- .../UnfoldedRequestMethodGenerator.java | 4 +- .../generator/enumeration/EnumGenerator.java | 7 +- .../generator/message/MessageGenerator.java | 34 ++----- .../type/processors/DomainTypeProcessor.java | 4 +- .../processors/RegisteredTypeProcessor.java | 2 +- .../sudu/protogen/plugin/ProtocPlugin.java | 6 +- 21 files changed, 244 insertions(+), 307 deletions(-) create mode 100644 generator/src/main/java/org/sudu/protogen/generator/EnumOrMessageGenerator.java diff --git a/generator/src/main/java/org/sudu/protogen/ProtogenGenerator.java b/generator/src/main/java/org/sudu/protogen/ProtogenGenerator.java index a3f605e..5b4576a 100644 --- a/generator/src/main/java/org/sudu/protogen/ProtogenGenerator.java +++ b/generator/src/main/java/org/sudu/protogen/ProtogenGenerator.java @@ -16,7 +16,6 @@ import org.sudu.protogen.plugin.Generator; import org.sudu.protogen.plugin.GeneratorException; -import java.util.HashMap; import java.util.List; import java.util.stream.Stream; @@ -44,14 +43,11 @@ private GenerationResult generate(GenerationRequest request, Configuration confi .filter(file -> request.filesToGenerateNames().contains(file.getName())) .toList(); var context = new GenerationContext( - filesToGenerate, configuration, TypeProcessor.Chain.getProcessingChain(), - FieldTypeProcessor.Chain.getProcessingChain(), - new HashMap<>(), - new HashMap<>() + FieldTypeProcessor.Chain.getProcessingChain() ); - return new org.sudu.protogen.generator.Generator(context).generate(); + return new org.sudu.protogen.generator.Generator(context, filesToGenerate).generate(); } @NotNull diff --git a/generator/src/main/java/org/sudu/protogen/config/naming/NamingManager.java b/generator/src/main/java/org/sudu/protogen/config/naming/NamingManager.java index d491e68..adf778d 100644 --- a/generator/src/main/java/org/sudu/protogen/config/naming/NamingManager.java +++ b/generator/src/main/java/org/sudu/protogen/config/naming/NamingManager.java @@ -5,5 +5,5 @@ public interface NamingManager { @NotNull - String getDomainName(@NotNull String messageName); + String manageName(@NotNull String originalName); } diff --git a/generator/src/main/java/org/sudu/protogen/config/naming/SuduNamingManager.java b/generator/src/main/java/org/sudu/protogen/config/naming/SuduNamingManager.java index c805626..f477f94 100644 --- a/generator/src/main/java/org/sudu/protogen/config/naming/SuduNamingManager.java +++ b/generator/src/main/java/org/sudu/protogen/config/naming/SuduNamingManager.java @@ -9,11 +9,11 @@ public class SuduNamingManager implements NamingManager { private static final String PREFIX = "Grpc"; @Override - public @NotNull String getDomainName(@NotNull String messageName) { + public @NotNull String manageName(@NotNull String originalName) { Validate.validState( - messageName.startsWith(PREFIX), - "Naming policy violation for %s. Its name should start with \"Grpc\"", messageName + originalName.startsWith(PREFIX), + "Naming policy violation for %s. Its name should start with \"Grpc\"", originalName ); - return StringUtils.removeStart(messageName, PREFIX); + return StringUtils.removeStart(originalName, PREFIX); } } diff --git a/generator/src/main/java/org/sudu/protogen/descriptors/Enum.java b/generator/src/main/java/org/sudu/protogen/descriptors/Enum.java index d70b6d6..819ffc5 100644 --- a/generator/src/main/java/org/sudu/protogen/descriptors/Enum.java +++ b/generator/src/main/java/org/sudu/protogen/descriptors/Enum.java @@ -11,54 +11,58 @@ public class Enum extends EnumOrMessage { - private final Descriptors.EnumDescriptor descriptor; + private final Descriptors.EnumDescriptor enumDescriptor; - public Enum(Descriptors.EnumDescriptor descriptor) { - this.descriptor = descriptor; + public Enum(Descriptors.EnumDescriptor enumDescriptor) { + this.enumDescriptor = enumDescriptor; } public List getValues() { - return descriptor.getValues().stream().map(Value::new).toList(); + return enumDescriptor.getValues().stream().map(Value::new).toList(); } @Override public @NotNull String getName() { - return descriptor.getName(); + return enumDescriptor.getName(); } @Override public @NotNull String getFullName() { - return descriptor.getFullName(); + return enumDescriptor.getFullName(); + } + + @Override + public @NotNull List getNested() { + return List.of(); } @Override public @NotNull File getContainingFile() { - return new File(descriptor.getFile()); + return new File(enumDescriptor.getFile()); } @Override public @Nullable Message getContainingType() { - return descriptor.getContainingType() == null ? null : new Message(descriptor.getContainingType()); + return Optional.ofNullable(enumDescriptor.getContainingType()) + .map(Message::new) + .orElse(null); } @Override - public List getNested() { - return List.of(); + public @Nullable String getCustomClass() { + return Options.wrapExtension(enumDescriptor.getOptions(), protogen.Options.customEnum).orElse(null); } + // ----------------- + @Override protected Optional getDoGenerateOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.genEnum); + return Options.wrapExtension(enumDescriptor.getOptions(), protogen.Options.genEnum); } @Override protected Optional getOverriddenNameOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.enumName); - } - - @Override - protected Optional getCustomClassNameOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.customEnum); + return Options.wrapExtension(enumDescriptor.getOptions(), protogen.Options.enumName); } @Override @@ -66,12 +70,12 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Enum anEnum = (Enum) o; - return Objects.equals(descriptor, anEnum.descriptor); + return Objects.equals(enumDescriptor, anEnum.enumDescriptor); } @Override public int hashCode() { - return Objects.hash(descriptor); + return Objects.hash(enumDescriptor); } public static class Value { @@ -82,11 +86,11 @@ public Value(Descriptors.EnumValueDescriptor valueDescriptor) { this.valueDescriptor = valueDescriptor; } - public final String generatedName() { + public String generatedName() { return getOverriddenNameOption().orElse(getName()); } - public final boolean isUnused() { + public boolean isUnused() { return getUnusedOption().orElse(false); } @@ -94,6 +98,8 @@ public String getName() { return valueDescriptor.getName(); } + // ----------------- + protected Optional getOverriddenNameOption() { return Options.wrapExtension(valueDescriptor.getOptions(), protogen.Options.enumValName); } diff --git a/generator/src/main/java/org/sudu/protogen/descriptors/EnumOrMessage.java b/generator/src/main/java/org/sudu/protogen/descriptors/EnumOrMessage.java index f16b985..530f5bd 100644 --- a/generator/src/main/java/org/sudu/protogen/descriptors/EnumOrMessage.java +++ b/generator/src/main/java/org/sudu/protogen/descriptors/EnumOrMessage.java @@ -16,85 +16,58 @@ public abstract class EnumOrMessage { public abstract @NotNull String getFullName(); + public abstract @NotNull List getNested(); + public abstract @NotNull File getContainingFile(); public abstract @Nullable Message getContainingType(); - public abstract List getNested(); + public abstract @Nullable String getCustomClass(); - // todo apply - public final void verify() { - int optCnt = 0; - if (getDoGenerateOption().isPresent() && getDoGenerateOption().get()) optCnt++; - if (getCustomClassNameOption().isPresent()) optCnt++; - if (this instanceof Message msg) { - if (msg.getUnfoldOption().isPresent() && msg.getUnfoldOption().get()) optCnt++; - } - if (optCnt > 1) { - throw new IllegalStateException("Only one of generate, decompose or customClass option could be set"); - } + public final boolean isDomain() { + return doGenerate() || getCustomClass() != null; } - public final ClassName getProtobufTypeName(NamingManager namingManager) { + public boolean doGenerate() { + if (getCustomClass() != null) return false; + return getDoGenerateOption() + .orElse(getContainingFile().doEnableGenerator() + && !getName().endsWith("Request") + && !getName().endsWith("Response") + ); + } + + public ClassName getProtobufTypeName() { if (getContainingType() == null) { String javaPackage = getContainingFile().getJavaPackage(); String enclosingClass = getContainingFile().getEnclosingClass(); String className = enclosingClass == null ? getName() : enclosingClass + "." + getName(); return ClassName.get(javaPackage, className); } else { - ClassName containing = getContainingType().getProtobufTypeName(namingManager); + ClassName containing = getContainingType().getProtobufTypeName(); return ClassName.get(containing.packageName(), containing.simpleName(), getName()); } } - public final ClassName getGeneratedTypeName(NamingManager namingManager) { - String customClass = customClass(); - if (customClass != null) { + public ClassName getDomainTypeName(NamingManager namingManager) { + Validate.validState(isDomain()); + if (getCustomClass() != null) { + String customClass = getCustomClass(); return ClassName.get(Name.getPackage(customClass), Name.getLastName(customClass)); } if (getContainingType() == null) { String javaPackage = getContainingFile().getGeneratePackage(); - return ClassName.get(javaPackage, generatedName(namingManager)); + return ClassName.get(javaPackage, getDomainName(namingManager)); } else { - ClassName containing = getContainingType().getGeneratedTypeName(namingManager); - return ClassName.get(containing.packageName(), containing.simpleName(), generatedName(namingManager)); - } - } - - public final String generatedName(NamingManager namingManager) { - Validate.validState(doGenerate(), "Check doGenerate() before calling generatedName()!"); - return getOverriddenNameOption() - .orElseGet(() -> namingManager.getDomainName(getName())); - } - - public final boolean doGenerate() { - if (this instanceof Message msg) { - if (msg.isMap()) return getDoGenerateOption().orElse(false); - if (msg.isUnfolded()) return getDoGenerateOption().orElse(false); + ClassName containing = getContainingType().getDomainTypeName(namingManager); + return ClassName.get(containing.packageName(), containing.simpleName(), getDomainName(namingManager)); } - if (customClass() != null) return false; - return getDoGenerateOption() - .orElse(getContainingFile().doGenerate() && !getName().endsWith("Request") && !getName().endsWith("Response")); } - public final boolean isDomain() { - return doGenerate() || customClass() != null; + private String getDomainName(NamingManager namingManager) { + return getOverriddenNameOption().orElseGet(() -> namingManager.manageName(getName())); } - @Nullable - public final String customClass() { - return getCustomClassNameOption().orElse(null); - } - - /* - * Options are not supposed to be used at high-level logic. - * They return only the value of an option in .proto file. - * Advanced logic taking into account other options and configuration values - * is placed at top-level methods such as getGenerateOption for getGenerateOption. - */ - - protected abstract Optional getCustomClassNameOption(); - protected abstract Optional getDoGenerateOption(); protected abstract Optional getOverriddenNameOption(); diff --git a/generator/src/main/java/org/sudu/protogen/descriptors/Field.java b/generator/src/main/java/org/sudu/protogen/descriptors/Field.java index 5950999..82481aa 100644 --- a/generator/src/main/java/org/sudu/protogen/descriptors/Field.java +++ b/generator/src/main/java/org/sudu/protogen/descriptors/Field.java @@ -2,7 +2,7 @@ import com.google.protobuf.Descriptors; import org.apache.commons.lang3.Validate; -import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.NotNull; import org.sudu.protogen.Options; import java.util.Objects; @@ -28,16 +28,14 @@ public Type getType() { return mapType(descriptor.getJavaType()); } - public @Nullable Message getMessageType() { - return descriptor.getJavaType() == Descriptors.FieldDescriptor.JavaType.MESSAGE - ? new Message(descriptor.getMessageType()) - : null; + public @NotNull Message getMessageType() { + Validate.validState(getType() == Type.MESSAGE); + return new Message(descriptor.getMessageType()); } - public @Nullable Enum getEnumType() { - return descriptor.getJavaType() == Descriptors.FieldDescriptor.JavaType.ENUM - ? new Enum(descriptor.getEnumType()) - : null; + public @NotNull Enum getEnumType() { + Validate.validState(getType() == Type.ENUM); + return new Enum(descriptor.getEnumType()); } public Message getContainingMessage() { @@ -53,13 +51,11 @@ public final boolean isList() { } public final boolean isMap() { -// noinspection DataFlowIssue because getMessageType() != null iff type == MESSAGE return getType() == Type.MESSAGE && getMessageType().isMap(); } public final boolean isUnfolded() { - //noinspection DataFlowIssue because getMessageType() != null iff type == MESSAGE return getType() == Type.MESSAGE && getMessageType().isUnfolded(); } @@ -68,7 +64,6 @@ public final boolean isIgnored() { } public final Field getUnfoldedField() { - //noinspection DataFlowIssue because isUnfolded() true iff getMessageType() != null Validate.validState(isUnfolded()); return getMessageType().getFields().get(0); } @@ -82,12 +77,7 @@ public final RepeatedContainer getRepeatedContainer() { return getRepeatedContainerOption().orElse(RepeatedContainer.LIST); } - /* - * Options are not supposed to be used at high-level logic. - * They return only the value of an option in .proto file. - * Advanced logic taking into account other options and configuration values - * is placed at top-level methods such as getGenerateOption for getGenerateOption. - */ + // ----------- protected boolean isRepeated() { return descriptor.isRepeated(); diff --git a/generator/src/main/java/org/sudu/protogen/descriptors/File.java b/generator/src/main/java/org/sudu/protogen/descriptors/File.java index ffa925c..c2c5ded 100644 --- a/generator/src/main/java/org/sudu/protogen/descriptors/File.java +++ b/generator/src/main/java/org/sudu/protogen/descriptors/File.java @@ -15,47 +15,47 @@ public class File { - private final Descriptors.FileDescriptor descriptor; + private final Descriptors.FileDescriptor fileDescriptor; - public File(Descriptors.FileDescriptor descriptor) { - this.descriptor = descriptor; + public File(Descriptors.FileDescriptor fileDescriptor) { + this.fileDescriptor = fileDescriptor; } public @NotNull String getName() { - return descriptor.getName(); + return fileDescriptor.getName(); } public @NotNull String getProtoPackage() { - return descriptor.getPackage(); + return fileDescriptor.getPackage(); } public @NotNull List getNested() { - var messages = descriptor.getMessageTypes().stream() + var messages = fileDescriptor.getMessageTypes().stream() .map(Message::new); - var enums = descriptor.getEnumTypes().stream() + var enums = fileDescriptor.getEnumTypes().stream() .map(Enum::new); return Stream.concat(messages, enums).toList(); } public @NotNull List getServices() { - return descriptor.getServices().stream() + return fileDescriptor.getServices().stream() .map(Service::new) .toList(); } // ============= - public final @NotNull String getGeneratePackage() { + public @NotNull String getGeneratePackage() { return getProtogenPackageOption() .orElse(StringUtils.removeEnd(getJavaPackage(), ".grpc")); } - public final @NotNull String getJavaPackage() { + public @NotNull String getJavaPackage() { return getJavaPackageOption() .orElse(getProtoPackage()); } - public final @NotNull String getJavaOuterClassname() { + public @NotNull String getJavaOuterClassname() { if (getJavaOuterClassnameOption().isPresent()) { return getJavaOuterClassnameOption().get(); } @@ -76,65 +76,47 @@ public File(Descriptors.FileDescriptor descriptor) { return filename; } - @Nullable - public final String getEnclosingClass() { + public @Nullable String getEnclosingClass() { return getJavaMultipleFiles() ? null : getJavaOuterClassname(); } - public final boolean getJavaMultipleFiles() { - return getJavaMultipleFilesOption().orElse(false); + public boolean getJavaMultipleFiles() { + return fileDescriptor.getOptions().getJavaMultipleFiles(); } // ============= - /** - * @return Whether generation of all entries of file is required. - * However, it doesn't applicable to determine whether scanning of the file is required. - * Primarily created for EnumOrMessage#goGenerate - */ - public final boolean doGenerate() { - return getGenerateOption().orElse(false); + public boolean doEnableGenerator() { + return getEnableOption().orElse(false); } - public final boolean doUseNullabilityAnnotation(boolean isNullable) { - // !nullable -> disable_notnull == false <=> nullable || disable_notnull == false + public boolean doUseNullabilityAnnotation(boolean isNullable) { + // notNullable -> !disable_notnull return isNullable || !getDisableNotNullOption().orElse(false); } // ============= - /* - * Options are not supposed to be used at high-level logic. - * They return only the value of an option in .proto file. - * Advanced logic taking into account other options and configuration values - * is placed at top-level methods such as doGenerate for getGenerateOption. - */ - - protected @NotNull Optional getJavaMultipleFilesOption() { - return Optional.of(descriptor.getOptions().getJavaMultipleFiles()) - .filter($ -> descriptor.getOptions().hasJavaMultipleFiles()); - } - protected @NotNull Optional getJavaOuterClassnameOption() { - return Optional.of(descriptor.getOptions().getJavaOuterClassname()) - .filter($ -> descriptor.getOptions().hasJavaOuterClassname()); + return Optional.of(fileDescriptor.getOptions().getJavaOuterClassname()) + .filter($ -> fileDescriptor.getOptions().hasJavaOuterClassname()); } protected @NotNull Optional getProtogenPackageOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.pkg); + return Options.wrapExtension(fileDescriptor.getOptions(), protogen.Options.pkg); } protected @NotNull Optional getJavaPackageOption() { - return Optional.of(descriptor.getOptions().getJavaPackage()) - .filter($ -> descriptor.getOptions().hasJavaPackage()); + return Optional.of(fileDescriptor.getOptions().getJavaPackage()) + .filter($ -> fileDescriptor.getOptions().hasJavaPackage()); } - protected @NotNull Optional getGenerateOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.enable); + protected @NotNull Optional getEnableOption() { + return Options.wrapExtension(fileDescriptor.getOptions(), protogen.Options.enable); } protected @NotNull Optional getDisableNotNullOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.disableNotnull); + return Options.wrapExtension(fileDescriptor.getOptions(), protogen.Options.disableNotnull); } @Override @@ -142,11 +124,11 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; File file = (File) o; - return Objects.equals(descriptor, file.descriptor); + return Objects.equals(fileDescriptor, file.fileDescriptor); } @Override public int hashCode() { - return Objects.hash(descriptor); + return Objects.hash(fileDescriptor); } } diff --git a/generator/src/main/java/org/sudu/protogen/descriptors/Message.java b/generator/src/main/java/org/sudu/protogen/descriptors/Message.java index a1f2976..e75c0c2 100644 --- a/generator/src/main/java/org/sudu/protogen/descriptors/Message.java +++ b/generator/src/main/java/org/sudu/protogen/descriptors/Message.java @@ -12,90 +12,93 @@ public class Message extends EnumOrMessage { - private final Descriptors.Descriptor descriptor; + private final Descriptors.Descriptor messageDescriptor; - public Message(Descriptors.Descriptor descriptor) { - this.descriptor = descriptor; + public Message(Descriptors.Descriptor messageDescriptor) { + this.messageDescriptor = messageDescriptor; } public List getFields() { - return descriptor.getFields().stream() + return messageDescriptor.getFields().stream() .map(Field::new) .toList(); } - public final boolean isUnfolded() { + public boolean isUnfolded() { if (getFields().size() != 1) return false; return getUnfoldOption().orElse(false); } - @Override - public @NotNull String getName() { - return descriptor.getName(); + /** + * protobuf internal flag to mark map entries + * + * @see map specification + */ + public boolean isMap() { + return messageDescriptor.getOptions().getMapEntry(); } - @Override - public @NotNull String getFullName() { - return descriptor.getFullName(); + public Optional getComparatorReference() { + return Options.wrapExtension(messageDescriptor.getOptions(), protogen.Options.messageComparator); } @Override - public @NotNull File getContainingFile() { - return new File(descriptor.getFile()); + public @NotNull String getName() { + return messageDescriptor.getName(); } @Override - public @Nullable Message getContainingType() { - return descriptor.getContainingType() == null ? null : new Message(descriptor.getContainingType()); + public @NotNull String getFullName() { + return messageDescriptor.getFullName(); } @Override - public List getNested() { - var messages = descriptor.getNestedTypes().stream() + public @NotNull List getNested() { + var messages = messageDescriptor.getNestedTypes().stream() .map(Message::new); - var enums = descriptor.getEnumTypes().stream() + var enums = messageDescriptor.getEnumTypes().stream() .map(Enum::new); return Stream.concat(messages, enums).toList(); } - /* - * Options are not supposed to be used at high-level logic. - * They return only the value of an option in .proto file. - * Advanced logic taking into account other options and configuration values - * is placed at top-level methods such as isUnfolded for getUnfoldOption. - */ - - /** - * protobuf internal flag to tag map entries - * - * @see map specification - */ + @Override + public @NotNull File getContainingFile() { + return new File(messageDescriptor.getFile()); + } @Override - protected Optional getDoGenerateOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.genMessage); + public @Nullable Message getContainingType() { + return Optional.ofNullable(messageDescriptor.getContainingType()) + .map(Message::new) + .orElse(null); } @Override - protected Optional getOverriddenNameOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.messageName); + public @Nullable String getCustomClass() { + return Options.wrapExtension(messageDescriptor.getOptions(), protogen.Options.customClass).orElse(null); } @Override - protected Optional getCustomClassNameOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.customClass); + public boolean doGenerate() { + if (isMap()) return getDoGenerateOption().orElse(false); + if (isUnfolded()) return getDoGenerateOption().orElse(false); + return super.doGenerate(); } - public boolean isMap() { - return descriptor.getOptions().getMapEntry(); + // ----------------- + + protected Optional getUnfoldOption() { + return Options.wrapExtension(messageDescriptor.getOptions(), protogen.Options.unfold); } - public Optional getComparatorReference() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.messageComparator); + @Override + protected Optional getDoGenerateOption() { + return Options.wrapExtension(messageDescriptor.getOptions(), protogen.Options.genMessage); } - public Optional getUnfoldOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.unfold); + @Override + protected Optional getOverriddenNameOption() { + return Options.wrapExtension(messageDescriptor.getOptions(), protogen.Options.messageName); } @Override @@ -103,11 +106,11 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Message message = (Message) o; - return Objects.equals(descriptor, message.descriptor); + return Objects.equals(messageDescriptor, message.messageDescriptor); } @Override public int hashCode() { - return Objects.hash(descriptor); + return Objects.hash(messageDescriptor); } } diff --git a/generator/src/main/java/org/sudu/protogen/descriptors/Method.java b/generator/src/main/java/org/sudu/protogen/descriptors/Method.java index 860f2b6..150e597 100644 --- a/generator/src/main/java/org/sudu/protogen/descriptors/Method.java +++ b/generator/src/main/java/org/sudu/protogen/descriptors/Method.java @@ -9,33 +9,32 @@ public class Method { - private final Descriptors.MethodDescriptor descriptor; + private final Descriptors.MethodDescriptor methodDescriptor; - public Method(Descriptors.MethodDescriptor descriptor) { - this.descriptor = descriptor; + public Method(Descriptors.MethodDescriptor methodDescriptor) { + this.methodDescriptor = methodDescriptor; } public String getName() { - return descriptor.getName(); + return methodDescriptor.getName(); } public Message getInputType() { - return new Message(descriptor.getInputType()); + return new Message(methodDescriptor.getInputType()); } public Message getOutputType() { - return new Message(descriptor.getOutputType()); + return new Message(methodDescriptor.getOutputType()); } public boolean isInputStreaming() { - return descriptor.isClientStreaming(); + return methodDescriptor.isClientStreaming(); } public boolean isOutputStreaming() { - return descriptor.isServerStreaming(); + return methodDescriptor.isServerStreaming(); } - public final boolean isNullable() { return getNullableOption().orElse(false); } @@ -65,24 +64,24 @@ public final Field unfoldedResponseField() { } protected Optional getGenerateOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.genMethod); + return Options.wrapExtension(methodDescriptor.getOptions(), protogen.Options.genMethod); } protected Optional getUnfoldRequestOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.unfoldRequest); + return Options.wrapExtension(methodDescriptor.getOptions(), protogen.Options.unfoldRequest); } protected Optional getNullableOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.nullable); + return Options.wrapExtension(methodDescriptor.getOptions(), protogen.Options.nullable); } public Optional getStreamToContainer() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.streamToContainer) + return Options.wrapExtension(methodDescriptor.getOptions(), protogen.Options.streamToContainer) .map(RepeatedContainer::fromGrpc); } protected Optional getNameOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.methodName); + return Options.wrapExtension(methodDescriptor.getOptions(), protogen.Options.methodName); } @Override @@ -90,11 +89,11 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Method method = (Method) o; - return Objects.equals(descriptor, method.descriptor); + return Objects.equals(methodDescriptor, method.methodDescriptor); } @Override public int hashCode() { - return Objects.hash(descriptor); + return Objects.hash(methodDescriptor); } } diff --git a/generator/src/main/java/org/sudu/protogen/descriptors/Service.java b/generator/src/main/java/org/sudu/protogen/descriptors/Service.java index ccb1b9b..54131bd 100644 --- a/generator/src/main/java/org/sudu/protogen/descriptors/Service.java +++ b/generator/src/main/java/org/sudu/protogen/descriptors/Service.java @@ -2,7 +2,10 @@ import com.google.protobuf.Descriptors; import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.TypeSpec; import org.sudu.protogen.Options; +import org.sudu.protogen.generator.GenerationContext; +import org.sudu.protogen.generator.client.ClientGenerator; import org.sudu.protogen.utils.Name; import java.util.List; @@ -11,22 +14,22 @@ public class Service { - private final Descriptors.ServiceDescriptor descriptor; + private final Descriptors.ServiceDescriptor serviceDescriptor; - public Service(Descriptors.ServiceDescriptor descriptor) { - this.descriptor = descriptor; + public Service(Descriptors.ServiceDescriptor serviceDescriptor) { + this.serviceDescriptor = serviceDescriptor; } public String getName() { - return descriptor.getName(); + return serviceDescriptor.getName(); } public File getContainingFile() { - return new File(descriptor.getFile()); + return new File(serviceDescriptor.getFile()); } public List getMethods() { - return descriptor.getMethods().stream() + return serviceDescriptor.getMethods().stream() .map(Method::new) .toList(); } @@ -36,7 +39,7 @@ public final boolean isAbstract() { } public final boolean doGenerate() { - return getGenerateOption().orElse(getContainingFile().doGenerate()); + return getGenerateOption().orElse(getContainingFile().doEnableGenerator()); } public final String generatedName() { @@ -55,16 +58,20 @@ public final ClassName blockingStubClass() { return ClassName.get(stubClass.packageName(), stubClass.simpleName() + "." + getName() + "BlockingStub"); } + public final TypeSpec generate(GenerationContext context) { + return new ClientGenerator(context, this).generate(); + } + protected Optional getAbstractOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.abstract_); + return Options.wrapExtension(serviceDescriptor.getOptions(), protogen.Options.abstract_); } protected Optional getGenerateOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.genService); + return Options.wrapExtension(serviceDescriptor.getOptions(), protogen.Options.genService); } protected Optional getNameOption() { - return Options.wrapExtension(descriptor.getOptions(), protogen.Options.serviceName); + return Options.wrapExtension(serviceDescriptor.getOptions(), protogen.Options.serviceName); } @Override @@ -72,11 +79,11 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Service service = (Service) o; - return Objects.equals(descriptor, service.descriptor); + return Objects.equals(serviceDescriptor, service.serviceDescriptor); } @Override public int hashCode() { - return Objects.hash(descriptor); + return Objects.hash(serviceDescriptor); } } diff --git a/generator/src/main/java/org/sudu/protogen/generator/EnumOrMessageGenerator.java b/generator/src/main/java/org/sudu/protogen/generator/EnumOrMessageGenerator.java new file mode 100644 index 0000000..46f3209 --- /dev/null +++ b/generator/src/main/java/org/sudu/protogen/generator/EnumOrMessageGenerator.java @@ -0,0 +1,30 @@ +package org.sudu.protogen.generator; + +import com.squareup.javapoet.TypeSpec; +import org.sudu.protogen.descriptors.Enum; +import org.sudu.protogen.descriptors.EnumOrMessage; +import org.sudu.protogen.descriptors.Message; +import org.sudu.protogen.generator.enumeration.EnumGenerator; +import org.sudu.protogen.generator.message.MessageGenerator; + +public class EnumOrMessageGenerator { + + private final GenerationContext context; + + private final EnumOrMessage descriptor; + + public EnumOrMessageGenerator(GenerationContext context, EnumOrMessage descriptor) { + this.context = context; + this.descriptor = descriptor; + } + + public TypeSpec generate() { + if (descriptor instanceof Message msg) { + return new MessageGenerator(context, msg).generate(); + } + if (descriptor instanceof Enum en) { + return new EnumGenerator(context, en).generate(); + } + throw new IllegalStateException(); + } +} diff --git a/generator/src/main/java/org/sudu/protogen/generator/GenerationContext.java b/generator/src/main/java/org/sudu/protogen/generator/GenerationContext.java index 6f6dcb8..01b7aa0 100644 --- a/generator/src/main/java/org/sudu/protogen/generator/GenerationContext.java +++ b/generator/src/main/java/org/sudu/protogen/generator/GenerationContext.java @@ -1,22 +1,12 @@ package org.sudu.protogen.generator; -import com.squareup.javapoet.TypeSpec; import org.sudu.protogen.config.Configuration; -import org.sudu.protogen.descriptors.EnumOrMessage; -import org.sudu.protogen.descriptors.File; -import org.sudu.protogen.descriptors.Service; import org.sudu.protogen.generator.field.processors.FieldTypeProcessor; import org.sudu.protogen.generator.type.processors.TypeProcessor; -import java.util.List; -import java.util.Map; - public record GenerationContext( - List filesToGenerate, Configuration configuration, TypeProcessor typeProcessor, - FieldTypeProcessor fieldTypeProcessor, - Map domains, - Map clients + FieldTypeProcessor fieldTypeProcessor ) { } diff --git a/generator/src/main/java/org/sudu/protogen/generator/Generator.java b/generator/src/main/java/org/sudu/protogen/generator/Generator.java index 5ddd04f..1d1dae5 100644 --- a/generator/src/main/java/org/sudu/protogen/generator/Generator.java +++ b/generator/src/main/java/org/sudu/protogen/generator/Generator.java @@ -4,23 +4,23 @@ import com.squareup.javapoet.TypeSpec; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; -import org.sudu.protogen.descriptors.Enum; -import org.sudu.protogen.descriptors.*; -import org.sudu.protogen.generator.client.ClientGenerator; -import org.sudu.protogen.generator.enumeration.EnumGenerator; -import org.sudu.protogen.generator.message.MessageGenerator; +import org.sudu.protogen.descriptors.EnumOrMessage; +import org.sudu.protogen.descriptors.File; +import org.sudu.protogen.descriptors.Service; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.stream.Stream; public class Generator { private final GenerationContext context; - public Generator(@NotNull GenerationContext context) { + private final List filesToGenerate; + + public Generator(@NotNull GenerationContext context, List filesToGenerate) { this.context = context; + this.filesToGenerate = filesToGenerate; } @NotNull @@ -44,54 +44,28 @@ private GenerationResult.File javaFileToResult(JavaFile gen) { private List generateFiles() { List result = new ArrayList<>(); - for (File file : context.filesToGenerate()) { - + for (File file : filesToGenerate) { String packageName = file.getGeneratePackage(); for (EnumOrMessage type : file.getNested()) { if (!type.doGenerate()) continue; - generateType(type) - .map(typeSpec -> JavaFile.builder(packageName, typeSpec) - .indent(getIndentation()) - .build() - ) - .forEach(result::add); + result.add(JavaFile.builder(packageName, new EnumOrMessageGenerator(context, type).generate()) + .indent(getIndentation()) + .build() + ); } - } - - for (File file : context.filesToGenerate()) { - String packageName = file.getGeneratePackage(); for (Service service : file.getServices()) { if (!service.doGenerate()) { continue; } - TypeSpec clientTypeSpec = new ClientGenerator(context, service).generate(); + TypeSpec clientTypeSpec = service.generate(context); result.add(JavaFile.builder(packageName, clientTypeSpec) .indent(getIndentation()) .build()); } } - return result; } - private Stream generateType(EnumOrMessage descriptor) { - Stream result = Stream.of(); - if (!descriptor.doGenerate()) return result; - TypeSpec generated = invokeTypeGenerator(descriptor); - context.domains().put(descriptor, generated); - result = Stream.concat(result, Stream.of(generated)); - return result; - } - - @NotNull - private TypeSpec invokeTypeGenerator(EnumOrMessage type) { - if (type instanceof Message msg) - return new MessageGenerator(context, msg).generate(); - else if (type instanceof Enum en) - return new EnumGenerator(context, en).generate(); - throw new IllegalStateException(); - } - private String getIndentation() { return StringUtils.repeat(" ", context.configuration().indentationSize()); } diff --git a/generator/src/main/java/org/sudu/protogen/generator/client/DomainRequestMethodBuilder.java b/generator/src/main/java/org/sudu/protogen/generator/client/DomainRequestMethodBuilder.java index d86f2f3..5fb0d6a 100644 --- a/generator/src/main/java/org/sudu/protogen/generator/client/DomainRequestMethodBuilder.java +++ b/generator/src/main/java/org/sudu/protogen/generator/client/DomainRequestMethodBuilder.java @@ -18,7 +18,7 @@ public DomainRequestMethodBuilder(GenerationContext context, Method method, Fiel @Override protected List parameters() { - ClassName domainType = method.getInputType().getGeneratedTypeName(context.configuration().namingManager()); + ClassName domainType = method.getInputType().getDomainTypeName(context.configuration().namingManager()); return List.of(ParameterSpec.builder(domainType, "request").build()); } diff --git a/generator/src/main/java/org/sudu/protogen/generator/client/GrpcCallMethodGenerator.java b/generator/src/main/java/org/sudu/protogen/generator/client/GrpcCallMethodGenerator.java index a508cd3..4221cbf 100644 --- a/generator/src/main/java/org/sudu/protogen/generator/client/GrpcCallMethodGenerator.java +++ b/generator/src/main/java/org/sudu/protogen/generator/client/GrpcCallMethodGenerator.java @@ -20,7 +20,7 @@ public GrpcCallMethodGenerator(GenerationContext context, Method method, FieldSp @Override protected List parameters() { - ClassName protoType = method.getInputType().getProtobufTypeName(context.configuration().namingManager()); + ClassName protoType = method.getInputType().getProtobufTypeName(); return List.of(ParameterSpec.builder(protoType, "request").build()); } diff --git a/generator/src/main/java/org/sudu/protogen/generator/client/UnfoldedRequestMethodGenerator.java b/generator/src/main/java/org/sudu/protogen/generator/client/UnfoldedRequestMethodGenerator.java index ea290aa..c7173de 100644 --- a/generator/src/main/java/org/sudu/protogen/generator/client/UnfoldedRequestMethodGenerator.java +++ b/generator/src/main/java/org/sudu/protogen/generator/client/UnfoldedRequestMethodGenerator.java @@ -32,9 +32,9 @@ protected List parameters() { @Override protected CodeBlock body(TypeModel returnType, List params) { - ClassName protoType = method.getInputType().getProtobufTypeName(context.configuration().namingManager()); + ClassName protoType = method.getInputType().getProtobufTypeName(); if (method.getInputType().isDomain()) { - ClassName inputType = method.getInputType().getGeneratedTypeName(context.configuration().namingManager()); + ClassName inputType = method.getInputType().getDomainTypeName(context.configuration().namingManager()); CodeBlock paramsAsList = Poem.separatedSequence( params.stream() .map(p -> CodeBlock.builder().add("$N", p).build()) // extract param name diff --git a/generator/src/main/java/org/sudu/protogen/generator/enumeration/EnumGenerator.java b/generator/src/main/java/org/sudu/protogen/generator/enumeration/EnumGenerator.java index 89fde39..da69b71 100644 --- a/generator/src/main/java/org/sudu/protogen/generator/enumeration/EnumGenerator.java +++ b/generator/src/main/java/org/sudu/protogen/generator/enumeration/EnumGenerator.java @@ -17,12 +17,13 @@ public class EnumGenerator { public EnumGenerator(GenerationContext context, Enum anEnum) { this.context = context; this.anEnum = anEnum; - this.protoType = anEnum.getProtobufTypeName(context.configuration().namingManager()); - this.generatedType = anEnum.getGeneratedTypeName(context.configuration().namingManager()); + this.protoType = anEnum.getProtobufTypeName(); + this.generatedType = anEnum.getDomainTypeName(context.configuration().namingManager()); } public TypeSpec generate() { - var builder = TypeSpec.enumBuilder(anEnum.generatedName(context.configuration().namingManager())) + ClassName domainTypeName = anEnum.getDomainTypeName(context.configuration().namingManager()); + var builder = TypeSpec.enumBuilder(domainTypeName.simpleName()) .addModifiers(Modifier.PUBLIC); anEnum.getValues().stream() .filter(val -> !val.isUnused()) diff --git a/generator/src/main/java/org/sudu/protogen/generator/message/MessageGenerator.java b/generator/src/main/java/org/sudu/protogen/generator/message/MessageGenerator.java index 7cd5fd7..20a3e67 100644 --- a/generator/src/main/java/org/sudu/protogen/generator/message/MessageGenerator.java +++ b/generator/src/main/java/org/sudu/protogen/generator/message/MessageGenerator.java @@ -2,11 +2,10 @@ import com.squareup.javapoet.*; import org.jetbrains.annotations.NotNull; -import org.sudu.protogen.descriptors.Enum; import org.sudu.protogen.descriptors.EnumOrMessage; import org.sudu.protogen.descriptors.Message; +import org.sudu.protogen.generator.EnumOrMessageGenerator; import org.sudu.protogen.generator.GenerationContext; -import org.sudu.protogen.generator.enumeration.EnumGenerator; import org.sudu.protogen.generator.field.FieldGenerator; import org.sudu.protogen.generator.field.FieldProcessingResult; import org.sudu.protogen.utils.Poem; @@ -38,7 +37,11 @@ public TypeSpec generate() { .map(FieldProcessingResult::field) .toList(); - TypeSpec.Builder typeBuilder = getRecordBuilder(fields); + List parameters = fields.stream() + .map(Poem::fieldToParameter) + .toList(); + TypeSpec.Builder typeBuilder = TypeSpec.recordBuilder(generatedType().simpleName()) + .addRecordComponents(parameters); boolean annotateNotNull = msgDescriptor.getContainingFile().doUseNullabilityAnnotation(false); msgDescriptor.getComparatorReference().ifPresent( @@ -69,37 +72,18 @@ private void addComparable(TypeSpec.Builder typeBuilder, String comparator) { ); } - private TypeSpec.Builder getRecordBuilder(List fields) { - List parameters = fields.stream() - .map(Poem::fieldToParameter) - .toList(); - return TypeSpec.recordBuilder(generatedType().simpleName()) - .addRecordComponents(parameters); - } - - private TypeSpec.Builder getClassBuilder(List fields) { - return TypeSpec.classBuilder(generatedType().simpleName()) - .addFields(fields) - .addMethods(new ClassBoilerplateGenerator(generatedType(), fields).generateBoilerplate()); - } - private List generateNested() { return msgDescriptor.getNested().stream() .filter(EnumOrMessage::doGenerate) - .map(e -> { - if (e instanceof Message msg) - return new MessageGenerator(generationContext, msg).generate(); - else - return new EnumGenerator(generationContext, (Enum) e).generate(); - }) + .map(e -> new EnumOrMessageGenerator(generationContext, e).generate()) .toList(); } private ClassName protoType() { - return msgDescriptor.getProtobufTypeName(generationContext.configuration().namingManager()); + return msgDescriptor.getProtobufTypeName(); } private ClassName generatedType() { - return msgDescriptor.getGeneratedTypeName(generationContext.configuration().namingManager()); + return msgDescriptor.getDomainTypeName(generationContext.configuration().namingManager()); } } diff --git a/generator/src/main/java/org/sudu/protogen/generator/type/processors/DomainTypeProcessor.java b/generator/src/main/java/org/sudu/protogen/generator/type/processors/DomainTypeProcessor.java index 44a9713..3605b28 100644 --- a/generator/src/main/java/org/sudu/protogen/generator/type/processors/DomainTypeProcessor.java +++ b/generator/src/main/java/org/sudu/protogen/generator/type/processors/DomainTypeProcessor.java @@ -10,8 +10,8 @@ class DomainTypeProcessor extends TypeProcessor.Chain { @Override public @NotNull TypeModel processType(@NotNull EnumOrMessage type, @NotNull GenerationContext context) { - if (type.doGenerate() || type.customClass() != null) { - return new DomainType(type.getGeneratedTypeName(context.configuration().namingManager())); + if (type.doGenerate() || type.getCustomClass() != null) { + return new DomainType(type.getDomainTypeName(context.configuration().namingManager())); } else { throw new IllegalArgumentException(( "It's not possible to process type of %s because it doesn't have a domain object. " + diff --git a/generator/src/main/java/org/sudu/protogen/generator/type/processors/RegisteredTypeProcessor.java b/generator/src/main/java/org/sudu/protogen/generator/type/processors/RegisteredTypeProcessor.java index 73e18c5..d6d68dd 100644 --- a/generator/src/main/java/org/sudu/protogen/generator/type/processors/RegisteredTypeProcessor.java +++ b/generator/src/main/java/org/sudu/protogen/generator/type/processors/RegisteredTypeProcessor.java @@ -20,7 +20,7 @@ class RegisteredTypeProcessor extends TypeProcessor.Chain { if (!type.getFullName().matches(transformer.protoType())) continue; return new RegisteredType( ClassName.get(Name.getPackage(transformer.javaClass()), Name.getLastName(transformer.javaClass())), - type.getProtobufTypeName(context.configuration().namingManager()), + type.getProtobufTypeName(), transformer ); } diff --git a/generator/src/main/java/org/sudu/protogen/plugin/ProtocPlugin.java b/generator/src/main/java/org/sudu/protogen/plugin/ProtocPlugin.java index 304b8fa..1ec03d2 100644 --- a/generator/src/main/java/org/sudu/protogen/plugin/ProtocPlugin.java +++ b/generator/src/main/java/org/sudu/protogen/plugin/ProtocPlugin.java @@ -10,7 +10,6 @@ import com.google.protobuf.ExtensionRegistry; import com.google.protobuf.GeneratedMessage.GeneratedExtension; import com.google.protobuf.compiler.PluginProtos; -import org.apache.commons.io.Charsets; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; @@ -20,6 +19,7 @@ import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -29,6 +29,7 @@ * ProtocPlugin is the main entry point for running one or more java-base protoc plugins. This class handles * I/O marshaling and error reporting. */ +@SuppressWarnings("rawtypes") public final class ProtocPlugin { private ProtocPlugin() { @@ -172,11 +173,12 @@ public static void debug( } FileUtils.createParentDirectories(outFile); - FileUtils.write(outFile, file.getContent(), Charsets.UTF_8); + FileUtils.write(outFile, file.getContent(), StandardCharsets.UTF_8); // FileUtils.write(outFile, file.getContentBytes()); } } catch (Throwable ex) { // Catch all the things! + //noinspection CallToPrintStackTrace ex.printStackTrace(); } }