You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ignite.apache.org by GitBox <gi...@apache.org> on 2021/05/18 13:19:14 UTC

[GitHub] [ignite-3] sashapolo opened a new pull request #130: WIP

sashapolo opened a new pull request #130:
URL: https://github.com/apache/ignite-3/pull/130


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638662279



##########
File path: modules/network-annotation-processor/src/integrationTest/resources/org/apache/ignite/network/processor/internal/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)
+public interface AllTypesMessage extends NetworkMessage {

Review comment:
       I agree, can we add this support in a separate task?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] alievmirza commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
alievmirza commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638902749



##########
File path: modules/network-annotation-processor/src/integrationTest/resources/org/apache/ignite/network/processor/internal/AllTypesMessageImpl.java
##########
@@ -0,0 +1,477 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.NetworkMessage;
+
+/**
+ * Message with all types supported by Direct Marshalling.
+ */
+class AllTypesMessageImpl implements AllTypesMessage, AllTypesMessage.Builder {
+
+    private byte a;
+
+    private short b;
+
+    private int c;
+
+    private long d;
+
+    private float e;
+
+    private double f;
+
+    private char g;
+
+    private boolean h;
+
+    private byte[] i;
+
+    private short[] j;
+
+    private int[] k;
+
+    private long[] l;
+
+    private float[] m;
+
+    private double[] n;
+
+    private char[] o;
+
+    private boolean[] p;
+
+    private String q;
+
+    private BitSet r;
+
+    private UUID s;
+
+    private IgniteUuid t;
+
+    private NetworkMessage u;
+
+    private NetworkMessage[] v;
+
+    private Collection<NetworkMessage> w;
+
+    private Map<String, NetworkMessage> x;
+
+    /**
+     * @return A.
+     */
+    @Override public byte a() {
+        return a;
+    }
+
+    /**
+     * @param a New a.
+     */
+    @Override public Builder a(byte a) {
+        this.a = a;
+        return this;
+    }
+
+    /**
+     * @return B.
+     */
+    @Override public short b() {
+        return b;
+    }
+
+    /**
+     * @param b New b.
+     */
+    @Override public Builder b(short b) {
+        this.b = b;
+        return this;
+    }
+
+    /**
+     * @return C.
+     */
+    @Override public int c() {
+        return c;
+    }
+
+    /**
+     * @param c New c.
+     */
+    @Override public Builder c(int c) {
+        this.c = c;
+        return this;
+    }
+
+    /**
+     * @return D.
+     */
+    @Override public long d() {
+        return d;
+    }
+
+    /**
+     * @param d New d.
+     */
+    @Override public Builder d(long d) {
+        this.d = d;
+        return this;
+    }
+
+    /**
+     * @return Exception.
+     */
+    @Override public float e() {
+        return e;
+    }
+
+    /**
+     * @param e New exception.
+     */
+    @Override public Builder e(float e) {
+        this.e = e;
+        return this;
+    }
+
+    /**
+     * @return F.
+     */
+    @Override public double f() {
+        return f;
+    }
+
+    /**
+     * @param f New f.
+     */
+    @Override public Builder f(double f) {
+        this.f = f;
+        return this;
+    }
+
+    /**
+     * @return G.
+     */
+    @Override public char g() {
+        return g;
+    }
+
+    /**
+     * @param g New g.
+     */
+    @Override public Builder g(char g) {
+        this.g = g;
+        return this;
+    }
+
+    /**
+     * @return H.
+     */
+    @Override public boolean h() {
+        return h;
+    }
+
+    /**
+     * @param h New h.
+     */
+    @Override public Builder h(boolean h) {
+        this.h = h;
+        return this;
+    }
+
+    /**
+     * @return I.
+     */
+    @Override public byte[] i() {
+        return i;
+    }
+
+    /**
+     * @param i New i.
+     */
+    @Override public Builder i(byte[] i) {
+        this.i = i;
+        return this;
+    }
+
+    /**
+     * @return J.
+     */
+    @Override public short[] j() {
+        return j;
+    }
+
+    /**
+     * @param j New j.
+     */
+    @Override public Builder j(short[] j) {
+        this.j = j;
+        return this;
+    }
+
+    /**
+     * @return K.
+     */
+    @Override public int[] k() {
+        return k;
+    }
+
+    /**
+     * @param k New k.
+     */
+    @Override public Builder k(int[] k) {
+        this.k = k;
+        return this;
+    }
+
+    /**
+     * @return L.
+     */
+    @Override public long[] l() {
+        return l;
+    }
+
+    /**
+     * @param l New l.
+     */
+    @Override public Builder l(long[] l) {
+        this.l = l;
+        return this;
+    }
+
+    /**
+     * @return M.
+     */
+    @Override public float[] m() {
+        return m;
+    }
+
+    /**
+     * @param m New m.
+     */
+    @Override public Builder m(float[] m) {
+        this.m = m;
+        return this;
+    }
+
+    /**
+     * @return N.
+     */
+    @Override public double[] n() {
+        return n;
+    }
+
+    /**
+     * @param n New n.
+     */
+    @Override public Builder n(double[] n) {
+        this.n = n;
+        return this;
+    }
+
+    /**
+     * @return O.
+     */
+    @Override public char[] o() {
+        return o;
+    }
+
+    /**
+     * @param o New o.
+     */
+    @Override public Builder o(char[] o) {
+        this.o = o;
+        return this;
+    }
+
+    /**
+     * @return P.
+     */
+    @Override public boolean[] p() {
+        return p;
+    }
+
+    /**
+     * @param p New p.
+     */
+    @Override public Builder p(boolean[] p) {
+        this.p = p;
+        return this;
+    }
+
+    /**
+     * @return Q.
+     */
+    @Override public String q() {
+        return q;
+    }
+
+    /**
+     * @param q New q.
+     */
+    @Override public Builder q(String q) {
+        this.q = q;
+        return this;
+    }
+
+    /**
+     * @return R.
+     */
+    @Override public BitSet r() {
+        return r;
+    }
+
+    /**
+     * @param r New r.
+     */
+    @Override public Builder r(BitSet r) {
+        this.r = r;
+        return this;
+    }
+
+    /**
+     * @return S.
+     */
+    @Override public UUID s() {
+        return s;
+    }
+
+    /**
+     * @param s New s.
+     */
+    @Override public Builder s(UUID s) {
+        this.s = s;
+        return this;
+    }
+
+    /**
+     * @return T.
+     */
+    @Override public IgniteUuid t() {
+        return t;
+    }
+
+    /**
+     * @param t New t.
+     */
+    @Override public Builder t(IgniteUuid t) {
+        this.t = t;
+        return this;
+    }
+
+    /**
+     * @return U.
+     */
+    @Override public NetworkMessage u() {
+        return u;
+    }
+
+    /**
+     * @param u New u.
+     */
+    @Override public Builder u(NetworkMessage u) {
+        this.u = u;
+        return this;
+    }
+
+    /**
+     * @return V.
+     */
+    @Override public NetworkMessage[] v() {
+        return v;
+    }
+
+    /**
+     * @param v New v.
+     */
+    @Override public Builder v(NetworkMessage[] v) {
+        this.v = v;
+        return this;
+    }
+
+    /**
+     * @return W.
+     */
+    @Override public Collection<NetworkMessage> w() {
+        return w;
+    }
+
+    /**
+     * @param w New w.
+     */
+    @Override public Builder w(Collection<NetworkMessage> w) {
+        this.w = w;
+        return this;
+    }
+
+    /**
+     * @return X.
+     */
+    @Override public Map<String, NetworkMessage> x() {
+        return x;
+    }
+
+    /**
+     * @param x New x.
+     */
+    @Override public Builder x(Map<String, NetworkMessage> x) {
+        this.x = x;
+        return this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override public boolean equals(Object o1) {
+        if (this == o1)
+            return true;
+        if (o1 == null || getClass() != o1.getClass())
+            return false;
+        AllTypesMessageImpl message = (AllTypesMessageImpl)o1;
+        return a == message.a && b == message.b && c == message.c && d == message.d && Float.compare(message.e, e) == 0 && Double.compare(message.f, f) == 0 && g == message.g && h == message.h && Arrays.equals(i, message.i) && Arrays.equals(j, message.j) && Arrays.equals(k, message.k) && Arrays.equals(l, message.l) && Arrays.equals(m, message.m) && Arrays.equals(n, message.n) && Arrays.equals(o, message.o) && Arrays.equals(p, message.p) && Objects.equals(q, message.q) && Objects.equals(r, message.r) && Objects.equals(s, message.s) && Objects.equals(t, message.t) && Objects.equals(u, message.u) && Arrays.equals(v, message.v) && Objects.equals(w, message.w) && Objects.equals(x, message.x);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override public int hashCode() {
+        int result = Objects.hash(a, b, c, d, e, f, g, h, q, r, s, t, u, w, x);
+        result = 31 * result + Arrays.hashCode(i);
+        result = 31 * result + Arrays.hashCode(j);
+        result = 31 * result + Arrays.hashCode(k);
+        result = 31 * result + Arrays.hashCode(l);
+        result = 31 * result + Arrays.hashCode(m);
+        result = 31 * result + Arrays.hashCode(n);
+        result = 31 * result + Arrays.hashCode(o);
+        result = 31 * result + Arrays.hashCode(p);
+        result = 31 * result + Arrays.hashCode(v);
+        return result;
+    }
+
+    /**
+     * {@inheritDoc}

Review comment:
       please use one line javadoc




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] ibessonov commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
ibessonov commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638722868



##########
File path: modules/network-annotation-processor/src/main/java/org/apache/ignite/network/processor/internal/AutoSerializableProcessor.java
##########
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+import org.apache.ignite.network.serialization.MessageDeserializer;
+import org.apache.ignite.network.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.serialization.MessageSerializationRegistry;
+import org.apache.ignite.network.serialization.MessageSerializer;
+
+/**
+ * Annotation processor for generating (de-)serializers for network messages marked with the {@link AutoSerializable}
+ * annotation.
+ */
+@SupportedSourceVersion(SourceVersion.RELEASE_11)
+public class AutoSerializableProcessor extends AbstractProcessor {
+    /** {@inheritDoc} */
+    @Override public Set<String> getSupportedAnnotationTypes() {
+        return Set.of(AutoSerializable.class.getName());
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        Set<TypeElement> annotatedElements = annotations.stream()
+            .map(roundEnv::getElementsAnnotatedWith)
+            .flatMap(Collection::stream)
+            .map(TypeElement.class::cast)
+            .collect(Collectors.toUnmodifiableSet());
+
+        if (annotatedElements.isEmpty()) {
+            return true;
+        }
+
+        try {
+            generateSources(annotatedElements);
+        } catch (IOException e) {
+            throw new IllegalStateException("IO exception during annotation processing", e);
+        }
+
+        return true;
+    }
+
+    /**
+     * Generates serialization-related classes for the given elements.
+     */
+    private void generateSources(Set<TypeElement> annotatedElements) throws IOException {
+        var factories = new HashMap<TypeElement, TypeSpec>();
+
+        for (var messageClass : annotatedElements) {
+            try {
+                if (isValidElement(messageClass)) {
+                    String packageName = ClassName.get(messageClass).packageName();
+
+                    TypeSpec serializer = generateSerializer(messageClass);
+                    writeToFile(packageName, serializer);
+
+                    TypeSpec deserializer = generateDeseralizer(messageClass);
+                    writeToFile(packageName, deserializer);
+
+                    TypeSpec factory = generateFactory(messageClass, serializer, deserializer);
+                    writeToFile(packageName, factory);
+
+                    factories.put(messageClass, factory);
+                } else {
+                    processingEnv.getMessager().printMessage(
+                        Diagnostic.Kind.ERROR,
+                        String.format(
+                            "%s annotation must only be present on interfaces that extend %s",
+                            AutoSerializable.class, NetworkMessage.class
+                        ),
+                        messageClass
+                    );
+                }
+            } catch (ProcessingException e) {
+                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), messageClass);
+            }
+        }
+
+        TypeSpec registryInitializer = generateRegistryInitializer(factories);
+        writeToFile(getParentPackage(annotatedElements), registryInitializer);

Review comment:
       I thought that factory signifies messages group, meaning that they have to be initialized together. So every factory may have its own initializer




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] ibessonov commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
ibessonov commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638703475



##########
File path: modules/network-messages/src/integrationTest/resources/org/apache/ignite/network/messages/internal/processor/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.messages.internal.processor;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.messages.NetworkMessage;
+import org.apache.ignite.network.messages.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)
+public interface AllTypesMessage extends NetworkMessage {
+    short TYPE = 123;
+
+    byte a();
+
+    short b();
+
+    int c();
+
+    long d();
+
+    float e();
+
+    double f();
+
+    char g();
+
+    boolean h();
+
+    byte[] i();
+
+    short[] j();
+
+    int[] k();
+
+    long[] l();
+
+    float[] m();
+
+    double[] n();
+
+    char[] o();
+
+    boolean[] p();
+
+    String q();
+
+    BitSet r();
+
+    UUID s();
+
+    IgniteUuid t();
+
+    NetworkMessage u();
+
+    NetworkMessage[] v();
+
+    Collection<NetworkMessage> w();
+
+    Map<String, NetworkMessage> x();
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override public default short directType() {
+        return 5555;
+    }
+
+    interface Builder {

Review comment:
       I agree with Alexander, right now this is the best that we can do




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r637899901



##########
File path: modules/network-messages/src/integrationTest/resources/org/apache/ignite/network/messages/internal/processor/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.messages.internal.processor;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.messages.NetworkMessage;
+import org.apache.ignite.network.messages.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)
+public interface AllTypesMessage extends NetworkMessage {
+    short TYPE = 123;
+
+    byte a();
+
+    short b();
+
+    int c();
+
+    long d();
+
+    float e();
+
+    double f();
+
+    char g();
+
+    boolean h();
+
+    byte[] i();
+
+    short[] j();
+
+    int[] k();
+
+    long[] l();
+
+    float[] m();
+
+    double[] n();
+
+    char[] o();
+
+    boolean[] p();
+
+    String q();
+
+    BitSet r();
+
+    UUID s();
+
+    IgniteUuid t();
+
+    NetworkMessage u();
+
+    NetworkMessage[] v();
+
+    Collection<NetworkMessage> w();
+
+    Map<String, NetworkMessage> x();
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override public default short directType() {
+        return 5555;
+    }
+
+    interface Builder {

Review comment:
       But how are you going to use the setters, if `MessageImpl` will be a private class? Also, I think that Builder will become a separate class, when we are going to generate the implementations, because current approach with extending Builders makes little sense (why not use setters instead?)




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638661856



##########
File path: modules/network-annotation-processor/src/integrationTest/resources/org/apache/ignite/network/processor/internal/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)
+public interface AllTypesMessage extends NetworkMessage {
+    short TYPE = 123;
+
+    byte a();
+
+    short b();
+
+    int c();
+
+    long d();
+
+    float e();
+
+    double f();
+
+    char g();
+
+    boolean h();
+
+    byte[] i();
+
+    short[] j();
+
+    int[] k();
+
+    long[] l();
+
+    float[] m();
+
+    double[] n();
+
+    char[] o();
+
+    boolean[] p();
+
+    String q();
+
+    BitSet r();
+
+    UUID s();
+
+    IgniteUuid t();
+
+    NetworkMessage u();
+
+    NetworkMessage[] v();
+
+    Collection<NetworkMessage> w();
+
+    Map<String, NetworkMessage> x();
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override public default short directType() {
+        return 5555;
+    }
+
+    interface Builder {
+        AllTypesMessage build();
+
+        Builder a(byte a);
+
+        Builder b(short b);
+
+        Builder c(int c);
+
+        Builder d(long d);
+
+        Builder e(float e);
+
+        Builder f(double f);
+
+        Builder g(char g);
+
+        Builder h(boolean h);
+
+        Builder i(byte[] i);
+
+        Builder j(short[] j);
+
+        Builder k(int[] k);
+
+        Builder l(long[] l);
+
+        Builder m(float[] m);
+
+        Builder n(double[] n);
+
+        Builder o(char[] o);
+
+        Builder p(boolean[] p);
+
+        Builder q(String q);
+
+        Builder r(BitSet r);
+
+        Builder s(UUID s);
+
+        Builder t(IgniteUuid t);
+
+        Builder u(NetworkMessage u);

Review comment:
       I don't think this is relevant for the current task. Here I'm just using what we already have...




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638662844



##########
File path: modules/network-annotation-processor/src/main/java/org/apache/ignite/network/processor/internal/AutoSerializableProcessor.java
##########
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+import org.apache.ignite.network.serialization.MessageDeserializer;
+import org.apache.ignite.network.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.serialization.MessageSerializationRegistry;
+import org.apache.ignite.network.serialization.MessageSerializer;
+
+/**
+ * Annotation processor for generating (de-)serializers for network messages marked with the {@link AutoSerializable}
+ * annotation.
+ */
+@SupportedSourceVersion(SourceVersion.RELEASE_11)
+public class AutoSerializableProcessor extends AbstractProcessor {
+    /** {@inheritDoc} */
+    @Override public Set<String> getSupportedAnnotationTypes() {
+        return Set.of(AutoSerializable.class.getName());
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        Set<TypeElement> annotatedElements = annotations.stream()
+            .map(roundEnv::getElementsAnnotatedWith)
+            .flatMap(Collection::stream)
+            .map(TypeElement.class::cast)
+            .collect(Collectors.toUnmodifiableSet());
+
+        if (annotatedElements.isEmpty()) {
+            return true;
+        }
+
+        try {
+            generateSources(annotatedElements);
+        } catch (IOException e) {
+            throw new IllegalStateException("IO exception during annotation processing", e);
+        }
+
+        return true;
+    }
+
+    /**
+     * Generates serialization-related classes for the given elements.
+     */
+    private void generateSources(Set<TypeElement> annotatedElements) throws IOException {
+        var factories = new HashMap<TypeElement, TypeSpec>();
+
+        for (var messageClass : annotatedElements) {
+            try {
+                if (isValidElement(messageClass)) {
+                    String packageName = ClassName.get(messageClass).packageName();
+
+                    TypeSpec serializer = generateSerializer(messageClass);
+                    writeToFile(packageName, serializer);
+
+                    TypeSpec deserializer = generateDeseralizer(messageClass);
+                    writeToFile(packageName, deserializer);
+
+                    TypeSpec factory = generateFactory(messageClass, serializer, deserializer);
+                    writeToFile(packageName, factory);
+
+                    factories.put(messageClass, factory);
+                } else {
+                    processingEnv.getMessager().printMessage(
+                        Diagnostic.Kind.ERROR,
+                        String.format(
+                            "%s annotation must only be present on interfaces that extend %s",
+                            AutoSerializable.class, NetworkMessage.class
+                        ),
+                        messageClass
+                    );
+                }
+            } catch (ProcessingException e) {
+                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), messageClass);
+            }
+        }
+
+        TypeSpec registryInitializer = generateRegistryInitializer(factories);
+        writeToFile(getParentPackage(annotatedElements), registryInitializer);
+    }
+
+    /**
+     * Generates a {@link MessageSerializer}.
+     */
+    private TypeSpec generateSerializer(TypeElement messageClass) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generating a MessageSerializer", messageClass);
+
+        return new MessageSerializerGenerator(processingEnv, messageClass).generateSerializer();
+    }
+
+    /**
+     * Generates a {@link MessageDeserializer}.
+     */
+    private TypeSpec generateDeseralizer(TypeElement messageClass) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generating a MessageDeserializer", messageClass);
+
+        return new MessageDeserializerGenerator(processingEnv, messageClass).generateDeserializer();
+    }
+
+    /**
+     * Generates a {@link MessageSerializationFactory}.
+     */
+    private TypeSpec generateFactory(TypeElement messageClass, TypeSpec serializer, TypeSpec deserializer) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generating a MessageSerializationFactory", messageClass);
+
+        return new SerializationFactoryGenerator(messageClass).generateFactory(serializer, deserializer);
+    }
+
+    /**
+     * Generates a class for registering all generated {@link MessageSerializationFactory} for the current module.
+     */
+    // TODO: refactor this method to use module names as part of the generated class,
+    //  see https://issues.apache.org/jira/browse/IGNITE-14715
+    private static TypeSpec generateRegistryInitializer(Map<TypeElement, TypeSpec> factoriesByMessageType) {
+        MethodSpec.Builder initializeMethod = MethodSpec.methodBuilder("initialize")
+            .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+            .addParameter(TypeName.get(MessageSerializationRegistry.class), "serializationRegistry");
+
+        factoriesByMessageType.forEach((messageClass, factory) -> {
+            var factoryPackage = ClassName.get(messageClass).packageName();
+            var factoryType = ClassName.get(factoryPackage, factory.name);
+
+            initializeMethod.addStatement("serializationRegistry.registerFactory($T.TYPE, new $T())", messageClass, factoryType);

Review comment:
       This constant will be moved to a special annotation in the next ticket (https://issues.apache.org/jira/browse/IGNITE-14715) and will later be generated based on this annotation.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r637878943



##########
File path: modules/network-messages/src/integrationTest/resources/org/apache/ignite/network/messages/internal/processor/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.messages.internal.processor;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.messages.NetworkMessage;
+import org.apache.ignite.network.messages.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)
+public interface AllTypesMessage extends NetworkMessage {
+    short TYPE = 123;
+
+    byte a();
+
+    short b();
+
+    int c();
+
+    long d();
+
+    float e();
+
+    double f();
+
+    char g();
+
+    boolean h();
+
+    byte[] i();
+
+    short[] j();
+
+    int[] k();
+
+    long[] l();
+
+    float[] m();
+
+    double[] n();
+
+    char[] o();
+
+    boolean[] p();
+
+    String q();
+
+    BitSet r();
+
+    UUID s();
+
+    IgniteUuid t();
+
+    NetworkMessage u();
+
+    NetworkMessage[] v();
+
+    Collection<NetworkMessage> w();
+
+    Map<String, NetworkMessage> x();
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override public default short directType() {
+        return 5555;
+    }
+
+    interface Builder {

Review comment:
       ok, I'll think about this in the next ticket. Here I'm just mimicking the approach used in the raf module... 




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] SammyVimes commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
SammyVimes commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r637591543



##########
File path: modules/network-messages/src/main/java/org/apache/ignite/network/messages/annotations/AutoSerializable.java
##########
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.messages.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.messages.NetworkMessage;
+import org.apache.ignite.network.messages.serialization.MessageDeserializer;
+import org.apache.ignite.network.messages.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.messages.serialization.MessageSerializer;
+
+/**
+ * Annotation for marking network message interfaces (i.e. those extending the {@link NetworkMessage} interface). For
+ * such interfaces, the following classes will be generated:
+ *
+ * <ol>
+ *     <li>{@link MessageSerializer};</li>
+ *     <li>{@link MessageDeserializer};</li>
+ *     <li>{@link MessageSerializationFactory}.</li>
+ * </ol>
+ *
+ * These messages must obey the <i>network message declaration contract</i> and can only contain
+ * <i>directly marshallable types</i>, which can be one of the following:
+ *
+ * <ol>
+ *     <li>Primitive type;</li>
+ *     <li>{@link String};</li>
+ *     <li>{@link UUID};</li>
+ *     <li>{@link IgniteUuid};</li>
+ *     <li>{@link BitSet};</li>
+ *     <li>Nested {@link NetworkMessage};</li>
+ *     <li>Array of primitive types, corresponding boxed types or other directly marshallable types;</li>
+ *     <li>{@link Collection} of boxed primitive types or other directly marshallable types;</li>
+ *     <li>{@link Map} where both keys and values can be of a directly marshallable type.</li>
+ * </ol>
+ */
+// TODO: describe the message declaration contract, see https://issues.apache.org/jira/browse/IGNITE-14715
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.SOURCE)

Review comment:
       It *could* possibly backfire later like with configuration-annotation-processor: During incremental compilation there was no information about non-runtime annotations of the type elements.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638663441



##########
File path: modules/network-annotation-processor/src/main/java/org/apache/ignite/network/processor/internal/AutoSerializableProcessor.java
##########
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+import org.apache.ignite.network.serialization.MessageDeserializer;
+import org.apache.ignite.network.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.serialization.MessageSerializationRegistry;
+import org.apache.ignite.network.serialization.MessageSerializer;
+
+/**
+ * Annotation processor for generating (de-)serializers for network messages marked with the {@link AutoSerializable}
+ * annotation.
+ */
+@SupportedSourceVersion(SourceVersion.RELEASE_11)
+public class AutoSerializableProcessor extends AbstractProcessor {
+    /** {@inheritDoc} */
+    @Override public Set<String> getSupportedAnnotationTypes() {
+        return Set.of(AutoSerializable.class.getName());
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        Set<TypeElement> annotatedElements = annotations.stream()
+            .map(roundEnv::getElementsAnnotatedWith)
+            .flatMap(Collection::stream)
+            .map(TypeElement.class::cast)
+            .collect(Collectors.toUnmodifiableSet());
+
+        if (annotatedElements.isEmpty()) {
+            return true;
+        }
+
+        try {
+            generateSources(annotatedElements);
+        } catch (IOException e) {
+            throw new IllegalStateException("IO exception during annotation processing", e);
+        }
+
+        return true;
+    }
+
+    /**
+     * Generates serialization-related classes for the given elements.
+     */
+    private void generateSources(Set<TypeElement> annotatedElements) throws IOException {
+        var factories = new HashMap<TypeElement, TypeSpec>();
+
+        for (var messageClass : annotatedElements) {
+            try {
+                if (isValidElement(messageClass)) {
+                    String packageName = ClassName.get(messageClass).packageName();
+
+                    TypeSpec serializer = generateSerializer(messageClass);
+                    writeToFile(packageName, serializer);
+
+                    TypeSpec deserializer = generateDeseralizer(messageClass);
+                    writeToFile(packageName, deserializer);
+
+                    TypeSpec factory = generateFactory(messageClass, serializer, deserializer);
+                    writeToFile(packageName, factory);
+
+                    factories.put(messageClass, factory);
+                } else {
+                    processingEnv.getMessager().printMessage(
+                        Diagnostic.Kind.ERROR,
+                        String.format(
+                            "%s annotation must only be present on interfaces that extend %s",
+                            AutoSerializable.class, NetworkMessage.class
+                        ),
+                        messageClass
+                    );
+                }
+            } catch (ProcessingException e) {
+                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), messageClass);
+            }
+        }
+
+        TypeSpec registryInitializer = generateRegistryInitializer(factories);
+        writeToFile(getParentPackage(annotatedElements), registryInitializer);

Review comment:
       What do you mean under "builder factory"?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r637878943



##########
File path: modules/network-messages/src/integrationTest/resources/org/apache/ignite/network/messages/internal/processor/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.messages.internal.processor;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.messages.NetworkMessage;
+import org.apache.ignite.network.messages.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)
+public interface AllTypesMessage extends NetworkMessage {
+    short TYPE = 123;
+
+    byte a();
+
+    short b();
+
+    int c();
+
+    long d();
+
+    float e();
+
+    double f();
+
+    char g();
+
+    boolean h();
+
+    byte[] i();
+
+    short[] j();
+
+    int[] k();
+
+    long[] l();
+
+    float[] m();
+
+    double[] n();
+
+    char[] o();
+
+    boolean[] p();
+
+    String q();
+
+    BitSet r();
+
+    UUID s();
+
+    IgniteUuid t();
+
+    NetworkMessage u();
+
+    NetworkMessage[] v();
+
+    Collection<NetworkMessage> w();
+
+    Map<String, NetworkMessage> x();
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override public default short directType() {
+        return 5555;
+    }
+
+    interface Builder {

Review comment:
       ok, I'll think about this in the next ticket. Here I'm just mimicking the approach used in the raft module... 




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] ibessonov commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
ibessonov commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638697052



##########
File path: modules/network-annotation-processor/src/integrationTest/resources/org/apache/ignite/network/processor/internal/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)
+public interface AllTypesMessage extends NetworkMessage {

Review comment:
       Sure, it's out of scope right now




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638660550



##########
File path: modules/network-annotation-processor/src/integrationTest/java/org/apache/ignite/network/messages/internal/processor/ITAutoSerializableProcessorTest.java
##########
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.tools.JavaFileObject;
+import com.google.testing.compile.Compilation;
+import com.google.testing.compile.Compiler;
+import com.google.testing.compile.JavaFileObjects;
+import org.apache.ignite.network.NetworkMessage;
+import org.junit.jupiter.api.Test;
+
+import static com.google.testing.compile.CompilationSubject.assertThat;
+
+/**
+ * Integration tests for {@link AutoSerializableProcessor}.
+ */
+public class ITAutoSerializableProcessorTest {
+    /** Package name of the test sources. */
+    private static final String RESOURCE_PACKAGE_NAME = "org.apache.ignite.network.processor.internal.";
+
+    /** Compiler instance configured with the annotation processor being tested. */
+    private final Compiler compiler = Compiler.javac().withProcessors(new AutoSerializableProcessor());
+
+    /**
+     * Compiles the network message with all supported directly marshallable types and checks that the compilation
+     * completed successfully.
+     */
+    @Test
+    void testCompileAllTypesMessage() {
+        Compilation compilation = compiler.compile(
+            getSources("AllTypesMessage", "AllTypesMessageImpl", "AllTypesMessageFactory")
+        );
+
+        assertThat(compilation).succeededWithoutWarnings();
+
+        assertThat(compilation).generatedSourceFile(RESOURCE_PACKAGE_NAME + "AllTypesMessageSerializer");
+        assertThat(compilation).generatedSourceFile(RESOURCE_PACKAGE_NAME + "AllTypesMessageDeserializer");
+        assertThat(compilation).generatedSourceFile(RESOURCE_PACKAGE_NAME + "AllTypesMessageSerializationFactory");
+    }
+
+    /**
+     * Compiles a test message that doesn't extend {@link NetworkMessage}.
+     */
+    @Test
+    void testInvalidAnnotatedTypeMessage() {
+        Compilation compilation = compiler.compile(
+            getSources("InvalidAnnotatedTypeMessage", "AllTypesMessageImpl", "AllTypesMessageFactory")
+        );
+
+        assertThat(compilation).hadErrorContaining("annotation must only be present on interfaces that extend");
+    }
+
+    /**
+     * Compiles a test message that contains an unsupported content type.
+     */
+    @Test
+    void testUnsupportedTypeMessage() {
+        Compilation compilation = compiler.compile(
+            getSources("UnsupportedTypeMessage", "AllTypesMessageImpl", "AllTypesMessageFactory")
+        );
+
+        assertThat(compilation).hadErrorContaining("Unsupported reference type for message (de-)serialization: java.util.ArrayList");
+    }
+
+    /**
+     * Compiles a test message that violates the message contract by not declaring a {@code Builder} interface.
+     */
+    @Test
+    void testMissingBuilderMessage() {
+        Compilation compilation = compiler.compile(
+            getSources("MissingBuilderMessage", "AllTypesMessageImpl", "AllTypesMessageFactory")
+        );
+
+        assertThat(compilation).hadErrorContaining("No nested Builder interface found");

Review comment:
       Yes, this is exactly what I'm going to do in the following ticket: https://issues.apache.org/jira/browse/IGNITE-14715

##########
File path: modules/network-annotation-processor/src/integrationTest/resources/org/apache/ignite/network/processor/internal/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)

Review comment:
       Please see my answer above




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638662844



##########
File path: modules/network-annotation-processor/src/main/java/org/apache/ignite/network/processor/internal/AutoSerializableProcessor.java
##########
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+import org.apache.ignite.network.serialization.MessageDeserializer;
+import org.apache.ignite.network.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.serialization.MessageSerializationRegistry;
+import org.apache.ignite.network.serialization.MessageSerializer;
+
+/**
+ * Annotation processor for generating (de-)serializers for network messages marked with the {@link AutoSerializable}
+ * annotation.
+ */
+@SupportedSourceVersion(SourceVersion.RELEASE_11)
+public class AutoSerializableProcessor extends AbstractProcessor {
+    /** {@inheritDoc} */
+    @Override public Set<String> getSupportedAnnotationTypes() {
+        return Set.of(AutoSerializable.class.getName());
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        Set<TypeElement> annotatedElements = annotations.stream()
+            .map(roundEnv::getElementsAnnotatedWith)
+            .flatMap(Collection::stream)
+            .map(TypeElement.class::cast)
+            .collect(Collectors.toUnmodifiableSet());
+
+        if (annotatedElements.isEmpty()) {
+            return true;
+        }
+
+        try {
+            generateSources(annotatedElements);
+        } catch (IOException e) {
+            throw new IllegalStateException("IO exception during annotation processing", e);
+        }
+
+        return true;
+    }
+
+    /**
+     * Generates serialization-related classes for the given elements.
+     */
+    private void generateSources(Set<TypeElement> annotatedElements) throws IOException {
+        var factories = new HashMap<TypeElement, TypeSpec>();
+
+        for (var messageClass : annotatedElements) {
+            try {
+                if (isValidElement(messageClass)) {
+                    String packageName = ClassName.get(messageClass).packageName();
+
+                    TypeSpec serializer = generateSerializer(messageClass);
+                    writeToFile(packageName, serializer);
+
+                    TypeSpec deserializer = generateDeseralizer(messageClass);
+                    writeToFile(packageName, deserializer);
+
+                    TypeSpec factory = generateFactory(messageClass, serializer, deserializer);
+                    writeToFile(packageName, factory);
+
+                    factories.put(messageClass, factory);
+                } else {
+                    processingEnv.getMessager().printMessage(
+                        Diagnostic.Kind.ERROR,
+                        String.format(
+                            "%s annotation must only be present on interfaces that extend %s",
+                            AutoSerializable.class, NetworkMessage.class
+                        ),
+                        messageClass
+                    );
+                }
+            } catch (ProcessingException e) {
+                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), messageClass);
+            }
+        }
+
+        TypeSpec registryInitializer = generateRegistryInitializer(factories);
+        writeToFile(getParentPackage(annotatedElements), registryInitializer);
+    }
+
+    /**
+     * Generates a {@link MessageSerializer}.
+     */
+    private TypeSpec generateSerializer(TypeElement messageClass) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generating a MessageSerializer", messageClass);
+
+        return new MessageSerializerGenerator(processingEnv, messageClass).generateSerializer();
+    }
+
+    /**
+     * Generates a {@link MessageDeserializer}.
+     */
+    private TypeSpec generateDeseralizer(TypeElement messageClass) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generating a MessageDeserializer", messageClass);
+
+        return new MessageDeserializerGenerator(processingEnv, messageClass).generateDeserializer();
+    }
+
+    /**
+     * Generates a {@link MessageSerializationFactory}.
+     */
+    private TypeSpec generateFactory(TypeElement messageClass, TypeSpec serializer, TypeSpec deserializer) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generating a MessageSerializationFactory", messageClass);
+
+        return new SerializationFactoryGenerator(messageClass).generateFactory(serializer, deserializer);
+    }
+
+    /**
+     * Generates a class for registering all generated {@link MessageSerializationFactory} for the current module.
+     */
+    // TODO: refactor this method to use module names as part of the generated class,
+    //  see https://issues.apache.org/jira/browse/IGNITE-14715
+    private static TypeSpec generateRegistryInitializer(Map<TypeElement, TypeSpec> factoriesByMessageType) {
+        MethodSpec.Builder initializeMethod = MethodSpec.methodBuilder("initialize")
+            .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+            .addParameter(TypeName.get(MessageSerializationRegistry.class), "serializationRegistry");
+
+        factoriesByMessageType.forEach((messageClass, factory) -> {
+            var factoryPackage = ClassName.get(messageClass).packageName();
+            var factoryType = ClassName.get(factoryPackage, factory.name);
+
+            initializeMethod.addStatement("serializationRegistry.registerFactory($T.TYPE, new $T())", messageClass, factoryType);

Review comment:
       This constant will be moved to a special annotation in the next ticket (https://issues.apache.org/jira/browse/IGNITE-14715)




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638663952



##########
File path: modules/network/src/test/java/org/apache/ignite/network/internal/AllTypesMessageImpl.java
##########
@@ -0,0 +1,496 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.internal;
+
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
+
+/**
+ * Message with all types supported by Direct Marshalling.
+ */
+class AllTypesMessageImpl implements AllTypesMessage, AllTypesMessage.Builder {

Review comment:
       Impl class is not auto-generated, it will be auto-generated in the next task (https://issues.apache.org/jira/browse/IGNITE-14715)




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] SammyVimes commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
SammyVimes commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r637381616



##########
File path: modules/network-messages/src/main/java/org/apache/ignite/network/messages/annotations/AutoSerializable.java
##########
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.messages.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.messages.NetworkMessage;
+import org.apache.ignite.network.messages.serialization.MessageDeserializer;
+import org.apache.ignite.network.messages.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.messages.serialization.MessageSerializer;
+
+/**
+ * Annotation for marking network message interfaces (i.e. those extending the {@link NetworkMessage} interface). For
+ * such interfaces, the following classes will be generated:
+ *
+ * <ol>
+ *     <li>{@link MessageSerializer};</li>
+ *     <li>{@link MessageDeserializer};</li>
+ *     <li>{@link MessageSerializationFactory}.</li>
+ * </ol>
+ *
+ * These messages must obey the <i>network message declaration contract</i> and can only contain
+ * <i>directly marshallable types</i>, which can be one of the following:
+ *
+ * <ol>
+ *     <li>Primitive type;</li>
+ *     <li>{@link String};</li>
+ *     <li>{@link UUID};</li>
+ *     <li>{@link IgniteUuid};</li>
+ *     <li>{@link BitSet};</li>
+ *     <li>Nested {@link NetworkMessage};</li>
+ *     <li>Array of primitive types, corresponding boxed types or other directly marshallable types;</li>
+ *     <li>{@link Collection} of boxed primitive types or other directly marshallable types;</li>
+ *     <li>{@link Map} where both keys and values can be of a directly marshallable type.</li>
+ * </ol>
+ */
+// TODO: describe the message declaration contract, see https://issues.apache.org/jira/browse/IGNITE-14715
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.SOURCE)

Review comment:
       Should be RUNTIME to avoid problems with incremental compilation




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r637589497



##########
File path: modules/network-messages/src/main/java/org/apache/ignite/network/messages/annotations/AutoSerializable.java
##########
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.messages.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.messages.NetworkMessage;
+import org.apache.ignite.network.messages.serialization.MessageDeserializer;
+import org.apache.ignite.network.messages.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.messages.serialization.MessageSerializer;
+
+/**
+ * Annotation for marking network message interfaces (i.e. those extending the {@link NetworkMessage} interface). For
+ * such interfaces, the following classes will be generated:
+ *
+ * <ol>
+ *     <li>{@link MessageSerializer};</li>
+ *     <li>{@link MessageDeserializer};</li>
+ *     <li>{@link MessageSerializationFactory}.</li>
+ * </ol>
+ *
+ * These messages must obey the <i>network message declaration contract</i> and can only contain
+ * <i>directly marshallable types</i>, which can be one of the following:
+ *
+ * <ol>
+ *     <li>Primitive type;</li>
+ *     <li>{@link String};</li>
+ *     <li>{@link UUID};</li>
+ *     <li>{@link IgniteUuid};</li>
+ *     <li>{@link BitSet};</li>
+ *     <li>Nested {@link NetworkMessage};</li>
+ *     <li>Array of primitive types, corresponding boxed types or other directly marshallable types;</li>
+ *     <li>{@link Collection} of boxed primitive types or other directly marshallable types;</li>
+ *     <li>{@link Map} where both keys and values can be of a directly marshallable type.</li>
+ * </ol>
+ */
+// TODO: describe the message declaration contract, see https://issues.apache.org/jira/browse/IGNITE-14715
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.SOURCE)
+public @interface AutoSerializable {
+    /**
+     * Message factory class that will be used to create message builders during deserialization.
+     * <p>
+     * Message factories must have a static method with the same name as the created message type and return a builder
+     * for that type, e.g. a factory for creating {@code TestMessage} instances must have a
+     * {@code TestMessage.Builder testMessage()} method.
+     */
+    Class<?> messageFactory();

Review comment:
       I agree, but I tried to mimic the current approach used in the raft module. I will try to remove this after we start generating message implementations as well.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] SammyVimes commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
SammyVimes commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r637592377



##########
File path: modules/network-messages/src/integrationTest/resources/org/apache/ignite/network/messages/internal/processor/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.messages.internal.processor;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.messages.NetworkMessage;
+import org.apache.ignite.network.messages.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)
+public interface AllTypesMessage extends NetworkMessage {
+    short TYPE = 123;
+
+    byte a();
+
+    short b();
+
+    int c();
+
+    long d();
+
+    float e();
+
+    double f();
+
+    char g();
+
+    boolean h();
+
+    byte[] i();
+
+    short[] j();
+
+    int[] k();
+
+    long[] l();
+
+    float[] m();
+
+    double[] n();
+
+    char[] o();
+
+    boolean[] p();
+
+    String q();
+
+    BitSet r();
+
+    UUID s();
+
+    IgniteUuid t();
+
+    NetworkMessage u();
+
+    NetworkMessage[] v();
+
+    Collection<NetworkMessage> w();
+
+    Map<String, NetworkMessage> x();
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override public default short directType() {
+        return 5555;
+    }
+
+    interface Builder {

Review comment:
       Sure, I think Builder declaration inside interface is redundant. Declaring it inside Impl class should be enough. I doubt there will be more than one implementation for one message interface. 
   So instead of: 
   ```
   Message.Builder builder = new MessageImpl();
   ```
   the code will look like this:
   ```
   MessageImpl.Builder builder = new MessageImpl();
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r637589758



##########
File path: modules/network/pom.xml
##########
@@ -48,6 +48,11 @@
             <artifactId>ignite-core</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-network-messages</artifactId>

Review comment:
       How is that going to help? "Compile" scope is transitive, so this processor will be visible to the client code in your approach as well. Or am I missing something here?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] ibessonov commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
ibessonov commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638697414



##########
File path: modules/network-annotation-processor/src/main/java/org/apache/ignite/network/processor/internal/AutoSerializableProcessor.java
##########
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+import org.apache.ignite.network.serialization.MessageDeserializer;
+import org.apache.ignite.network.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.serialization.MessageSerializationRegistry;
+import org.apache.ignite.network.serialization.MessageSerializer;
+
+/**
+ * Annotation processor for generating (de-)serializers for network messages marked with the {@link AutoSerializable}
+ * annotation.
+ */
+@SupportedSourceVersion(SourceVersion.RELEASE_11)
+public class AutoSerializableProcessor extends AbstractProcessor {
+    /** {@inheritDoc} */
+    @Override public Set<String> getSupportedAnnotationTypes() {
+        return Set.of(AutoSerializable.class.getName());
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        Set<TypeElement> annotatedElements = annotations.stream()
+            .map(roundEnv::getElementsAnnotatedWith)
+            .flatMap(Collection::stream)
+            .map(TypeElement.class::cast)
+            .collect(Collectors.toUnmodifiableSet());
+
+        if (annotatedElements.isEmpty()) {
+            return true;
+        }
+
+        try {
+            generateSources(annotatedElements);
+        } catch (IOException e) {
+            throw new IllegalStateException("IO exception during annotation processing", e);
+        }
+
+        return true;
+    }
+
+    /**
+     * Generates serialization-related classes for the given elements.
+     */
+    private void generateSources(Set<TypeElement> annotatedElements) throws IOException {
+        var factories = new HashMap<TypeElement, TypeSpec>();
+
+        for (var messageClass : annotatedElements) {
+            try {
+                if (isValidElement(messageClass)) {
+                    String packageName = ClassName.get(messageClass).packageName();
+
+                    TypeSpec serializer = generateSerializer(messageClass);
+                    writeToFile(packageName, serializer);
+
+                    TypeSpec deserializer = generateDeseralizer(messageClass);
+                    writeToFile(packageName, deserializer);
+
+                    TypeSpec factory = generateFactory(messageClass, serializer, deserializer);
+                    writeToFile(packageName, factory);
+
+                    factories.put(messageClass, factory);
+                } else {
+                    processingEnv.getMessager().printMessage(
+                        Diagnostic.Kind.ERROR,
+                        String.format(
+                            "%s annotation must only be present on interfaces that extend %s",
+                            AutoSerializable.class, NetworkMessage.class
+                        ),
+                        messageClass
+                    );
+                }
+            } catch (ProcessingException e) {
+                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), messageClass);
+            }
+        }
+
+        TypeSpec registryInitializer = generateRegistryInitializer(factories);
+        writeToFile(getParentPackage(annotatedElements), registryInitializer);

Review comment:
       Factory that creates builder instances for messages




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638661124



##########
File path: modules/network-annotation-processor/src/integrationTest/resources/org/apache/ignite/network/processor/internal/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)
+public interface AllTypesMessage extends NetworkMessage {
+    short TYPE = 123;

Review comment:
       It's the direct type, the problem is that we can't call `directType()` when registering a factory




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638726874



##########
File path: modules/network-annotation-processor/src/main/java/org/apache/ignite/network/processor/internal/AutoSerializableProcessor.java
##########
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+import org.apache.ignite.network.serialization.MessageDeserializer;
+import org.apache.ignite.network.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.serialization.MessageSerializationRegistry;
+import org.apache.ignite.network.serialization.MessageSerializer;
+
+/**
+ * Annotation processor for generating (de-)serializers for network messages marked with the {@link AutoSerializable}
+ * annotation.
+ */
+@SupportedSourceVersion(SourceVersion.RELEASE_11)
+public class AutoSerializableProcessor extends AbstractProcessor {
+    /** {@inheritDoc} */
+    @Override public Set<String> getSupportedAnnotationTypes() {
+        return Set.of(AutoSerializable.class.getName());
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        Set<TypeElement> annotatedElements = annotations.stream()
+            .map(roundEnv::getElementsAnnotatedWith)
+            .flatMap(Collection::stream)
+            .map(TypeElement.class::cast)
+            .collect(Collectors.toUnmodifiableSet());
+
+        if (annotatedElements.isEmpty()) {
+            return true;
+        }
+
+        try {
+            generateSources(annotatedElements);
+        } catch (IOException e) {
+            throw new IllegalStateException("IO exception during annotation processing", e);
+        }
+
+        return true;
+    }
+
+    /**
+     * Generates serialization-related classes for the given elements.
+     */
+    private void generateSources(Set<TypeElement> annotatedElements) throws IOException {
+        var factories = new HashMap<TypeElement, TypeSpec>();
+
+        for (var messageClass : annotatedElements) {
+            try {
+                if (isValidElement(messageClass)) {
+                    String packageName = ClassName.get(messageClass).packageName();
+
+                    TypeSpec serializer = generateSerializer(messageClass);
+                    writeToFile(packageName, serializer);
+
+                    TypeSpec deserializer = generateDeseralizer(messageClass);
+                    writeToFile(packageName, deserializer);
+
+                    TypeSpec factory = generateFactory(messageClass, serializer, deserializer);
+                    writeToFile(packageName, factory);
+
+                    factories.put(messageClass, factory);
+                } else {
+                    processingEnv.getMessager().printMessage(
+                        Diagnostic.Kind.ERROR,
+                        String.format(
+                            "%s annotation must only be present on interfaces that extend %s",
+                            AutoSerializable.class, NetworkMessage.class
+                        ),
+                        messageClass
+                    );
+                }
+            } catch (ProcessingException e) {
+                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), messageClass);
+            }
+        }
+
+        TypeSpec registryInitializer = generateRegistryInitializer(factories);
+        writeToFile(getParentPackage(annotatedElements), registryInitializer);

Review comment:
       The idea was to have a single initializer per module, since this is the most convenient way (e.g. why would you want to initialize several groups separately?). Anyway, there's no such concept as a message group right now, this will likely change in the next ticket, when we will actually introduce message groups based on the `@MessageTypes` annotation, in which case there will indeed be an initializer per group (see the TODO comment in this method).




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] SammyVimes commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
SammyVimes commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r637590865



##########
File path: modules/network/pom.xml
##########
@@ -48,6 +48,11 @@
             <artifactId>ignite-core</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-network-messages</artifactId>

Review comment:
       Sorry, what I meant was "optional", not "compile"




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638720258



##########
File path: modules/network-annotation-processor/src/main/java/org/apache/ignite/network/processor/internal/AutoSerializableProcessor.java
##########
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+import org.apache.ignite.network.serialization.MessageDeserializer;
+import org.apache.ignite.network.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.serialization.MessageSerializationRegistry;
+import org.apache.ignite.network.serialization.MessageSerializer;
+
+/**
+ * Annotation processor for generating (de-)serializers for network messages marked with the {@link AutoSerializable}
+ * annotation.
+ */
+@SupportedSourceVersion(SourceVersion.RELEASE_11)
+public class AutoSerializableProcessor extends AbstractProcessor {
+    /** {@inheritDoc} */
+    @Override public Set<String> getSupportedAnnotationTypes() {
+        return Set.of(AutoSerializable.class.getName());
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        Set<TypeElement> annotatedElements = annotations.stream()
+            .map(roundEnv::getElementsAnnotatedWith)
+            .flatMap(Collection::stream)
+            .map(TypeElement.class::cast)
+            .collect(Collectors.toUnmodifiableSet());
+
+        if (annotatedElements.isEmpty()) {
+            return true;
+        }
+
+        try {
+            generateSources(annotatedElements);
+        } catch (IOException e) {
+            throw new IllegalStateException("IO exception during annotation processing", e);
+        }
+
+        return true;
+    }
+
+    /**
+     * Generates serialization-related classes for the given elements.
+     */
+    private void generateSources(Set<TypeElement> annotatedElements) throws IOException {
+        var factories = new HashMap<TypeElement, TypeSpec>();
+
+        for (var messageClass : annotatedElements) {
+            try {
+                if (isValidElement(messageClass)) {
+                    String packageName = ClassName.get(messageClass).packageName();
+
+                    TypeSpec serializer = generateSerializer(messageClass);
+                    writeToFile(packageName, serializer);
+
+                    TypeSpec deserializer = generateDeseralizer(messageClass);
+                    writeToFile(packageName, deserializer);
+
+                    TypeSpec factory = generateFactory(messageClass, serializer, deserializer);
+                    writeToFile(packageName, factory);
+
+                    factories.put(messageClass, factory);
+                } else {
+                    processingEnv.getMessager().printMessage(
+                        Diagnostic.Kind.ERROR,
+                        String.format(
+                            "%s annotation must only be present on interfaces that extend %s",
+                            AutoSerializable.class, NetworkMessage.class
+                        ),
+                        messageClass
+                    );
+                }
+            } catch (ProcessingException e) {
+                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), messageClass);
+            }
+        }
+
+        TypeSpec registryInitializer = generateRegistryInitializer(factories);
+        writeToFile(getParentPackage(annotatedElements), registryInitializer);

Review comment:
       we can have multiple factories in the same module, so I don't think it is possible in the general case




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] SammyVimes commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
SammyVimes commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r637381616



##########
File path: modules/network-messages/src/main/java/org/apache/ignite/network/messages/annotations/AutoSerializable.java
##########
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.messages.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.messages.NetworkMessage;
+import org.apache.ignite.network.messages.serialization.MessageDeserializer;
+import org.apache.ignite.network.messages.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.messages.serialization.MessageSerializer;
+
+/**
+ * Annotation for marking network message interfaces (i.e. those extending the {@link NetworkMessage} interface). For
+ * such interfaces, the following classes will be generated:
+ *
+ * <ol>
+ *     <li>{@link MessageSerializer};</li>
+ *     <li>{@link MessageDeserializer};</li>
+ *     <li>{@link MessageSerializationFactory}.</li>
+ * </ol>
+ *
+ * These messages must obey the <i>network message declaration contract</i> and can only contain
+ * <i>directly marshallable types</i>, which can be one of the following:
+ *
+ * <ol>
+ *     <li>Primitive type;</li>
+ *     <li>{@link String};</li>
+ *     <li>{@link UUID};</li>
+ *     <li>{@link IgniteUuid};</li>
+ *     <li>{@link BitSet};</li>
+ *     <li>Nested {@link NetworkMessage};</li>
+ *     <li>Array of primitive types, corresponding boxed types or other directly marshallable types;</li>
+ *     <li>{@link Collection} of boxed primitive types or other directly marshallable types;</li>
+ *     <li>{@link Map} where both keys and values can be of a directly marshallable type.</li>
+ * </ol>
+ */
+// TODO: describe the message declaration contract, see https://issues.apache.org/jira/browse/IGNITE-14715
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.SOURCE)

Review comment:
       Should be RUNTIME, to avoid problems with incremental compilation

##########
File path: modules/network-messages/src/integrationTest/resources/org/apache/ignite/network/messages/internal/processor/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.messages.internal.processor;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.messages.NetworkMessage;
+import org.apache.ignite.network.messages.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)
+public interface AllTypesMessage extends NetworkMessage {
+    short TYPE = 123;
+
+    byte a();
+
+    short b();
+
+    int c();
+
+    long d();
+
+    float e();
+
+    double f();
+
+    char g();
+
+    boolean h();
+
+    byte[] i();
+
+    short[] j();
+
+    int[] k();
+
+    long[] l();
+
+    float[] m();
+
+    double[] n();
+
+    char[] o();
+
+    boolean[] p();
+
+    String q();
+
+    BitSet r();
+
+    UUID s();
+
+    IgniteUuid t();
+
+    NetworkMessage u();
+
+    NetworkMessage[] v();
+
+    Collection<NetworkMessage> w();
+
+    Map<String, NetworkMessage> x();
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override public default short directType() {
+        return 5555;
+    }
+
+    interface Builder {

Review comment:
       I wonder if we should only have Builder interface inside of the MessageImpl class. This way there should be significantly less code to write

##########
File path: modules/network/pom.xml
##########
@@ -48,6 +48,11 @@
             <artifactId>ignite-core</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-network-messages</artifactId>

Review comment:
       If we add ignite-network-messages like this, annotation processor will make its way to the client's code. I think annotation processor should be a separate module that is only added as a compile time dependency. Unfortunately, this means that APIs like NetworkMessage should be moved to yet another module (network-api?)
   In my opinion the dependency tree should look like this:
   
   Network -> (compile) NetworkMessage -> NetworkApi
   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-> NetworkApi
   

##########
File path: modules/network-messages/src/main/java/org/apache/ignite/network/messages/annotations/AutoSerializable.java
##########
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.messages.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.messages.NetworkMessage;
+import org.apache.ignite.network.messages.serialization.MessageDeserializer;
+import org.apache.ignite.network.messages.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.messages.serialization.MessageSerializer;
+
+/**
+ * Annotation for marking network message interfaces (i.e. those extending the {@link NetworkMessage} interface). For
+ * such interfaces, the following classes will be generated:
+ *
+ * <ol>
+ *     <li>{@link MessageSerializer};</li>
+ *     <li>{@link MessageDeserializer};</li>
+ *     <li>{@link MessageSerializationFactory}.</li>
+ * </ol>
+ *
+ * These messages must obey the <i>network message declaration contract</i> and can only contain
+ * <i>directly marshallable types</i>, which can be one of the following:
+ *
+ * <ol>
+ *     <li>Primitive type;</li>
+ *     <li>{@link String};</li>
+ *     <li>{@link UUID};</li>
+ *     <li>{@link IgniteUuid};</li>
+ *     <li>{@link BitSet};</li>
+ *     <li>Nested {@link NetworkMessage};</li>
+ *     <li>Array of primitive types, corresponding boxed types or other directly marshallable types;</li>
+ *     <li>{@link Collection} of boxed primitive types or other directly marshallable types;</li>
+ *     <li>{@link Map} where both keys and values can be of a directly marshallable type.</li>
+ * </ol>
+ */
+// TODO: describe the message declaration contract, see https://issues.apache.org/jira/browse/IGNITE-14715
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.SOURCE)
+public @interface AutoSerializable {
+    /**
+     * Message factory class that will be used to create message builders during deserialization.
+     * <p>
+     * Message factories must have a static method with the same name as the created message type and return a builder
+     * for that type, e.g. a factory for creating {@code TestMessage} instances must have a
+     * {@code TestMessage.Builder testMessage()} method.
+     */
+    Class<?> messageFactory();

Review comment:
       Why won't we just create a new instance of message, without factory? No need for hand-writting these factories




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] ibessonov commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
ibessonov commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638697574



##########
File path: modules/network/src/test/java/org/apache/ignite/network/internal/AllTypesMessageImpl.java
##########
@@ -0,0 +1,496 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.internal;
+
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
+
+/**
+ * Message with all types supported by Direct Marshalling.
+ */
+class AllTypesMessageImpl implements AllTypesMessage, AllTypesMessage.Builder {

Review comment:
       Ok




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] ibessonov merged pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
ibessonov merged pull request #130:
URL: https://github.com/apache/ignite-3/pull/130


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] SammyVimes commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
SammyVimes commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r637592418



##########
File path: modules/network-messages/src/main/java/org/apache/ignite/network/messages/annotations/AutoSerializable.java
##########
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.messages.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.messages.NetworkMessage;
+import org.apache.ignite.network.messages.serialization.MessageDeserializer;
+import org.apache.ignite.network.messages.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.messages.serialization.MessageSerializer;
+
+/**
+ * Annotation for marking network message interfaces (i.e. those extending the {@link NetworkMessage} interface). For
+ * such interfaces, the following classes will be generated:
+ *
+ * <ol>
+ *     <li>{@link MessageSerializer};</li>
+ *     <li>{@link MessageDeserializer};</li>
+ *     <li>{@link MessageSerializationFactory}.</li>
+ * </ol>
+ *
+ * These messages must obey the <i>network message declaration contract</i> and can only contain
+ * <i>directly marshallable types</i>, which can be one of the following:
+ *
+ * <ol>
+ *     <li>Primitive type;</li>
+ *     <li>{@link String};</li>
+ *     <li>{@link UUID};</li>
+ *     <li>{@link IgniteUuid};</li>
+ *     <li>{@link BitSet};</li>
+ *     <li>Nested {@link NetworkMessage};</li>
+ *     <li>Array of primitive types, corresponding boxed types or other directly marshallable types;</li>
+ *     <li>{@link Collection} of boxed primitive types or other directly marshallable types;</li>
+ *     <li>{@link Map} where both keys and values can be of a directly marshallable type.</li>
+ * </ol>
+ */
+// TODO: describe the message declaration contract, see https://issues.apache.org/jira/browse/IGNITE-14715
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.SOURCE)
+public @interface AutoSerializable {
+    /**
+     * Message factory class that will be used to create message builders during deserialization.
+     * <p>
+     * Message factories must have a static method with the same name as the created message type and return a builder
+     * for that type, e.g. a factory for creating {@code TestMessage} instances must have a
+     * {@code TestMessage.Builder testMessage()} method.
+     */
+    Class<?> messageFactory();

Review comment:
       Ok!




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r637589357



##########
File path: modules/network-messages/src/main/java/org/apache/ignite/network/messages/annotations/AutoSerializable.java
##########
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.messages.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.messages.NetworkMessage;
+import org.apache.ignite.network.messages.serialization.MessageDeserializer;
+import org.apache.ignite.network.messages.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.messages.serialization.MessageSerializer;
+
+/**
+ * Annotation for marking network message interfaces (i.e. those extending the {@link NetworkMessage} interface). For
+ * such interfaces, the following classes will be generated:
+ *
+ * <ol>
+ *     <li>{@link MessageSerializer};</li>
+ *     <li>{@link MessageDeserializer};</li>
+ *     <li>{@link MessageSerializationFactory}.</li>
+ * </ol>
+ *
+ * These messages must obey the <i>network message declaration contract</i> and can only contain
+ * <i>directly marshallable types</i>, which can be one of the following:
+ *
+ * <ol>
+ *     <li>Primitive type;</li>
+ *     <li>{@link String};</li>
+ *     <li>{@link UUID};</li>
+ *     <li>{@link IgniteUuid};</li>
+ *     <li>{@link BitSet};</li>
+ *     <li>Nested {@link NetworkMessage};</li>
+ *     <li>Array of primitive types, corresponding boxed types or other directly marshallable types;</li>
+ *     <li>{@link Collection} of boxed primitive types or other directly marshallable types;</li>
+ *     <li>{@link Map} where both keys and values can be of a directly marshallable type.</li>
+ * </ol>
+ */
+// TODO: describe the message declaration contract, see https://issues.apache.org/jira/browse/IGNITE-14715
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.SOURCE)

Review comment:
       What problems?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r637878943



##########
File path: modules/network-messages/src/integrationTest/resources/org/apache/ignite/network/messages/internal/processor/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.messages.internal.processor;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.messages.NetworkMessage;
+import org.apache.ignite.network.messages.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)
+public interface AllTypesMessage extends NetworkMessage {
+    short TYPE = 123;
+
+    byte a();
+
+    short b();
+
+    int c();
+
+    long d();
+
+    float e();
+
+    double f();
+
+    char g();
+
+    boolean h();
+
+    byte[] i();
+
+    short[] j();
+
+    int[] k();
+
+    long[] l();
+
+    float[] m();
+
+    double[] n();
+
+    char[] o();
+
+    boolean[] p();
+
+    String q();
+
+    BitSet r();
+
+    UUID s();
+
+    IgniteUuid t();
+
+    NetworkMessage u();
+
+    NetworkMessage[] v();
+
+    Collection<NetworkMessage> w();
+
+    Map<String, NetworkMessage> x();
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override public default short directType() {
+        return 5555;
+    }
+
+    interface Builder {

Review comment:
       ok, I'll think about this in the next ticket. Here I'm just mimicking the approach used in the raft module... 




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] ibessonov commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
ibessonov commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r638587678



##########
File path: modules/network-annotation-processor/src/integrationTest/java/org/apache/ignite/network/messages/internal/processor/ITAutoSerializableProcessorTest.java
##########
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.tools.JavaFileObject;
+import com.google.testing.compile.Compilation;
+import com.google.testing.compile.Compiler;
+import com.google.testing.compile.JavaFileObjects;
+import org.apache.ignite.network.NetworkMessage;
+import org.junit.jupiter.api.Test;
+
+import static com.google.testing.compile.CompilationSubject.assertThat;
+
+/**
+ * Integration tests for {@link AutoSerializableProcessor}.
+ */
+public class ITAutoSerializableProcessorTest {
+    /** Package name of the test sources. */
+    private static final String RESOURCE_PACKAGE_NAME = "org.apache.ignite.network.processor.internal.";
+
+    /** Compiler instance configured with the annotation processor being tested. */
+    private final Compiler compiler = Compiler.javac().withProcessors(new AutoSerializableProcessor());
+
+    /**
+     * Compiles the network message with all supported directly marshallable types and checks that the compilation
+     * completed successfully.
+     */
+    @Test
+    void testCompileAllTypesMessage() {
+        Compilation compilation = compiler.compile(
+            getSources("AllTypesMessage", "AllTypesMessageImpl", "AllTypesMessageFactory")
+        );
+
+        assertThat(compilation).succeededWithoutWarnings();
+
+        assertThat(compilation).generatedSourceFile(RESOURCE_PACKAGE_NAME + "AllTypesMessageSerializer");
+        assertThat(compilation).generatedSourceFile(RESOURCE_PACKAGE_NAME + "AllTypesMessageDeserializer");
+        assertThat(compilation).generatedSourceFile(RESOURCE_PACKAGE_NAME + "AllTypesMessageSerializationFactory");
+    }
+
+    /**
+     * Compiles a test message that doesn't extend {@link NetworkMessage}.
+     */
+    @Test
+    void testInvalidAnnotatedTypeMessage() {
+        Compilation compilation = compiler.compile(
+            getSources("InvalidAnnotatedTypeMessage", "AllTypesMessageImpl", "AllTypesMessageFactory")
+        );
+
+        assertThat(compilation).hadErrorContaining("annotation must only be present on interfaces that extend");
+    }
+
+    /**
+     * Compiles a test message that contains an unsupported content type.
+     */
+    @Test
+    void testUnsupportedTypeMessage() {
+        Compilation compilation = compiler.compile(
+            getSources("UnsupportedTypeMessage", "AllTypesMessageImpl", "AllTypesMessageFactory")
+        );
+
+        assertThat(compilation).hadErrorContaining("Unsupported reference type for message (de-)serialization: java.util.ArrayList");
+    }
+
+    /**
+     * Compiles a test message that violates the message contract by not declaring a {@code Builder} interface.
+     */
+    @Test
+    void testMissingBuilderMessage() {
+        Compilation compilation = compiler.compile(
+            getSources("MissingBuilderMessage", "AllTypesMessageImpl", "AllTypesMessageFactory")
+        );
+
+        assertThat(compilation).hadErrorContaining("No nested Builder interface found");

Review comment:
       Can we avoid this requirement and generate builders by ourselves?

##########
File path: modules/network-annotation-processor/src/integrationTest/resources/org/apache/ignite/network/processor/internal/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)
+public interface AllTypesMessage extends NetworkMessage {
+    short TYPE = 123;

Review comment:
       What's the purpose of this constant?

##########
File path: modules/network-annotation-processor/src/integrationTest/resources/org/apache/ignite/network/processor/internal/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)

Review comment:
       Similar question - we should at least consider the possibility of generating this factory.

##########
File path: modules/network-annotation-processor/src/main/java/org/apache/ignite/network/processor/internal/AutoSerializableProcessor.java
##########
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+import org.apache.ignite.network.serialization.MessageDeserializer;
+import org.apache.ignite.network.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.serialization.MessageSerializationRegistry;
+import org.apache.ignite.network.serialization.MessageSerializer;
+
+/**
+ * Annotation processor for generating (de-)serializers for network messages marked with the {@link AutoSerializable}
+ * annotation.
+ */
+@SupportedSourceVersion(SourceVersion.RELEASE_11)
+public class AutoSerializableProcessor extends AbstractProcessor {
+    /** {@inheritDoc} */
+    @Override public Set<String> getSupportedAnnotationTypes() {
+        return Set.of(AutoSerializable.class.getName());
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        Set<TypeElement> annotatedElements = annotations.stream()
+            .map(roundEnv::getElementsAnnotatedWith)
+            .flatMap(Collection::stream)
+            .map(TypeElement.class::cast)
+            .collect(Collectors.toUnmodifiableSet());
+
+        if (annotatedElements.isEmpty()) {
+            return true;
+        }
+
+        try {
+            generateSources(annotatedElements);
+        } catch (IOException e) {
+            throw new IllegalStateException("IO exception during annotation processing", e);
+        }
+
+        return true;
+    }
+
+    /**
+     * Generates serialization-related classes for the given elements.
+     */
+    private void generateSources(Set<TypeElement> annotatedElements) throws IOException {
+        var factories = new HashMap<TypeElement, TypeSpec>();
+
+        for (var messageClass : annotatedElements) {
+            try {
+                if (isValidElement(messageClass)) {
+                    String packageName = ClassName.get(messageClass).packageName();
+
+                    TypeSpec serializer = generateSerializer(messageClass);
+                    writeToFile(packageName, serializer);
+
+                    TypeSpec deserializer = generateDeseralizer(messageClass);
+                    writeToFile(packageName, deserializer);
+
+                    TypeSpec factory = generateFactory(messageClass, serializer, deserializer);
+                    writeToFile(packageName, factory);
+
+                    factories.put(messageClass, factory);
+                } else {
+                    processingEnv.getMessager().printMessage(
+                        Diagnostic.Kind.ERROR,
+                        String.format(
+                            "%s annotation must only be present on interfaces that extend %s",
+                            AutoSerializable.class, NetworkMessage.class
+                        ),
+                        messageClass
+                    );
+                }
+            } catch (ProcessingException e) {
+                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), messageClass);
+            }
+        }
+
+        TypeSpec registryInitializer = generateRegistryInitializer(factories);
+        writeToFile(getParentPackage(annotatedElements), registryInitializer);
+    }
+
+    /**
+     * Generates a {@link MessageSerializer}.
+     */
+    private TypeSpec generateSerializer(TypeElement messageClass) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generating a MessageSerializer", messageClass);
+
+        return new MessageSerializerGenerator(processingEnv, messageClass).generateSerializer();
+    }
+
+    /**
+     * Generates a {@link MessageDeserializer}.
+     */
+    private TypeSpec generateDeseralizer(TypeElement messageClass) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generating a MessageDeserializer", messageClass);
+
+        return new MessageDeserializerGenerator(processingEnv, messageClass).generateDeserializer();
+    }
+
+    /**
+     * Generates a {@link MessageSerializationFactory}.
+     */
+    private TypeSpec generateFactory(TypeElement messageClass, TypeSpec serializer, TypeSpec deserializer) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generating a MessageSerializationFactory", messageClass);
+
+        return new SerializationFactoryGenerator(messageClass).generateFactory(serializer, deserializer);
+    }
+
+    /**
+     * Generates a class for registering all generated {@link MessageSerializationFactory} for the current module.
+     */
+    // TODO: refactor this method to use module names as part of the generated class,
+    //  see https://issues.apache.org/jira/browse/IGNITE-14715
+    private static TypeSpec generateRegistryInitializer(Map<TypeElement, TypeSpec> factoriesByMessageType) {
+        MethodSpec.Builder initializeMethod = MethodSpec.methodBuilder("initialize")
+            .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+            .addParameter(TypeName.get(MessageSerializationRegistry.class), "serializationRegistry");
+
+        factoriesByMessageType.forEach((messageClass, factory) -> {
+            var factoryPackage = ClassName.get(messageClass).packageName();
+            var factoryType = ClassName.get(factoryPackage, factory.name);
+
+            initializeMethod.addStatement("serializationRegistry.registerFactory($T.TYPE, new $T())", messageClass, factoryType);

Review comment:
       Oh, I see now why you need this constant. Very non-intuitive.

##########
File path: modules/network-annotation-processor/src/main/java/org/apache/ignite/network/processor/internal/AutoSerializableProcessor.java
##########
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+import org.apache.ignite.network.serialization.MessageDeserializer;
+import org.apache.ignite.network.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.serialization.MessageSerializationRegistry;
+import org.apache.ignite.network.serialization.MessageSerializer;
+
+/**
+ * Annotation processor for generating (de-)serializers for network messages marked with the {@link AutoSerializable}
+ * annotation.
+ */
+@SupportedSourceVersion(SourceVersion.RELEASE_11)
+public class AutoSerializableProcessor extends AbstractProcessor {
+    /** {@inheritDoc} */
+    @Override public Set<String> getSupportedAnnotationTypes() {
+        return Set.of(AutoSerializable.class.getName());
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        Set<TypeElement> annotatedElements = annotations.stream()
+            .map(roundEnv::getElementsAnnotatedWith)
+            .flatMap(Collection::stream)
+            .map(TypeElement.class::cast)
+            .collect(Collectors.toUnmodifiableSet());
+
+        if (annotatedElements.isEmpty()) {
+            return true;
+        }
+
+        try {
+            generateSources(annotatedElements);
+        } catch (IOException e) {
+            throw new IllegalStateException("IO exception during annotation processing", e);
+        }
+
+        return true;
+    }
+
+    /**
+     * Generates serialization-related classes for the given elements.
+     */
+    private void generateSources(Set<TypeElement> annotatedElements) throws IOException {
+        var factories = new HashMap<TypeElement, TypeSpec>();
+
+        for (var messageClass : annotatedElements) {
+            try {
+                if (isValidElement(messageClass)) {
+                    String packageName = ClassName.get(messageClass).packageName();
+
+                    TypeSpec serializer = generateSerializer(messageClass);
+                    writeToFile(packageName, serializer);
+
+                    TypeSpec deserializer = generateDeseralizer(messageClass);
+                    writeToFile(packageName, deserializer);
+
+                    TypeSpec factory = generateFactory(messageClass, serializer, deserializer);
+                    writeToFile(packageName, factory);
+
+                    factories.put(messageClass, factory);
+                } else {
+                    processingEnv.getMessager().printMessage(
+                        Diagnostic.Kind.ERROR,
+                        String.format(
+                            "%s annotation must only be present on interfaces that extend %s",
+                            AutoSerializable.class, NetworkMessage.class
+                        ),
+                        messageClass
+                    );
+                }
+            } catch (ProcessingException e) {
+                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), messageClass);
+            }
+        }
+
+        TypeSpec registryInitializer = generateRegistryInitializer(factories);
+        writeToFile(getParentPackage(annotatedElements), registryInitializer);
+    }
+
+    /**
+     * Generates a {@link MessageSerializer}.
+     */
+    private TypeSpec generateSerializer(TypeElement messageClass) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generating a MessageSerializer", messageClass);
+
+        return new MessageSerializerGenerator(processingEnv, messageClass).generateSerializer();
+    }
+
+    /**
+     * Generates a {@link MessageDeserializer}.
+     */
+    private TypeSpec generateDeseralizer(TypeElement messageClass) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generating a MessageDeserializer", messageClass);
+
+        return new MessageDeserializerGenerator(processingEnv, messageClass).generateDeserializer();
+    }
+
+    /**
+     * Generates a {@link MessageSerializationFactory}.
+     */
+    private TypeSpec generateFactory(TypeElement messageClass, TypeSpec serializer, TypeSpec deserializer) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Generating a MessageSerializationFactory", messageClass);
+
+        return new SerializationFactoryGenerator(messageClass).generateFactory(serializer, deserializer);
+    }
+
+    /**
+     * Generates a class for registering all generated {@link MessageSerializationFactory} for the current module.
+     */
+    // TODO: refactor this method to use module names as part of the generated class,
+    //  see https://issues.apache.org/jira/browse/IGNITE-14715
+    private static TypeSpec generateRegistryInitializer(Map<TypeElement, TypeSpec> factoriesByMessageType) {
+        MethodSpec.Builder initializeMethod = MethodSpec.methodBuilder("initialize")
+            .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+            .addParameter(TypeName.get(MessageSerializationRegistry.class), "serializationRegistry");
+
+        factoriesByMessageType.forEach((messageClass, factory) -> {
+            var factoryPackage = ClassName.get(messageClass).packageName();
+            var factoryType = ClassName.get(factoryPackage, factory.name);
+
+            initializeMethod.addStatement("serializationRegistry.registerFactory($T.TYPE, new $T())", messageClass, factoryType);
+        });
+
+        return TypeSpec.classBuilder("MessageSerializationRegistryInitializer")
+            .addModifiers(Modifier.PUBLIC)
+            .addMethod(initializeMethod.build())
+            .build();
+    }
+
+    /**
+     * Returns the longest common package name among the given elements' packages.
+     */
+    private String getParentPackage(Collection<TypeElement> messageClasses) {
+        List<String[]> packageNames = messageClasses.stream()
+            .map(processingEnv.getElementUtils()::getPackageOf)
+            .map(PackageElement::getQualifiedName)
+            .map(Name::toString)
+            .map(packageName -> packageName.split("\\."))
+            .collect(Collectors.toUnmodifiableList());
+
+        int minNameLength = packageNames.stream().mapToInt(arr -> arr.length).min().getAsInt();
+
+        var result = new StringJoiner(".");
+
+        for (int i = 0; i < minNameLength; ++i) {
+            var distinctSubPackageNames = new HashSet<String>();
+
+            for (String[] packageName : packageNames) {
+                distinctSubPackageNames.add(packageName[i]);
+            }
+
+            if (distinctSubPackageNames.size() == 1) {
+                result.add(distinctSubPackageNames.iterator().next());
+            } else {

Review comment:
       Wrong formatting

##########
File path: modules/network-annotation-processor/src/main/java/org/apache/ignite/network/processor/internal/BaseMethodNameResolver.java
##########
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.NetworkMessage;
+
+/**
+ * Class for resolving a "base" part of a (de-)serialization method based on the message type. This part is then used
+ * by concrete method resolvers by prepending a "read"/"write" prefix and adding call arguments.
+ *
+ * @see MessageReaderMethodResolver
+ * @see MessageWriterMethodResolver
+ */
+class BaseMethodNameResolver {
+    /** */
+    private final ProcessingEnvironment processingEnvironment;
+
+    /** */
+    BaseMethodNameResolver(ProcessingEnvironment processingEnvironment) {
+        this.processingEnvironment = processingEnvironment;
+    }
+
+    /**
+     * Resolves a "base" part of a (de-)serialization method.
+     */
+    String resolveBaseMethodName(TypeMirror parameterType) {
+        if (parameterType.getKind().isPrimitive()) {
+            return resolvePrimitiveMethodName(parameterType);
+        } else if (parameterType.getKind() == TypeKind.ARRAY) {

Review comment:
       you know the deal

##########
File path: modules/network-annotation-processor/src/main/java/org/apache/ignite/network/processor/internal/AutoSerializableProcessor.java
##########
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+import org.apache.ignite.network.serialization.MessageDeserializer;
+import org.apache.ignite.network.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.serialization.MessageSerializationRegistry;
+import org.apache.ignite.network.serialization.MessageSerializer;
+
+/**
+ * Annotation processor for generating (de-)serializers for network messages marked with the {@link AutoSerializable}
+ * annotation.
+ */
+@SupportedSourceVersion(SourceVersion.RELEASE_11)
+public class AutoSerializableProcessor extends AbstractProcessor {
+    /** {@inheritDoc} */
+    @Override public Set<String> getSupportedAnnotationTypes() {
+        return Set.of(AutoSerializable.class.getName());
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        Set<TypeElement> annotatedElements = annotations.stream()
+            .map(roundEnv::getElementsAnnotatedWith)
+            .flatMap(Collection::stream)
+            .map(TypeElement.class::cast)
+            .collect(Collectors.toUnmodifiableSet());
+
+        if (annotatedElements.isEmpty()) {
+            return true;
+        }
+
+        try {
+            generateSources(annotatedElements);
+        } catch (IOException e) {
+            throw new IllegalStateException("IO exception during annotation processing", e);
+        }
+
+        return true;
+    }
+
+    /**
+     * Generates serialization-related classes for the given elements.
+     */
+    private void generateSources(Set<TypeElement> annotatedElements) throws IOException {
+        var factories = new HashMap<TypeElement, TypeSpec>();
+
+        for (var messageClass : annotatedElements) {
+            try {
+                if (isValidElement(messageClass)) {
+                    String packageName = ClassName.get(messageClass).packageName();
+
+                    TypeSpec serializer = generateSerializer(messageClass);
+                    writeToFile(packageName, serializer);
+
+                    TypeSpec deserializer = generateDeseralizer(messageClass);
+                    writeToFile(packageName, deserializer);
+
+                    TypeSpec factory = generateFactory(messageClass, serializer, deserializer);
+                    writeToFile(packageName, factory);
+
+                    factories.put(messageClass, factory);
+                } else {

Review comment:
       Wrong formatting

##########
File path: modules/network-annotation-processor/src/integrationTest/resources/org/apache/ignite/network/processor/internal/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)
+public interface AllTypesMessage extends NetworkMessage {

Review comment:
       I don't see any support for arbitrary serializable fields. We will need it in the future, 100%

##########
File path: modules/network-api/pom.xml
##########
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ignite</groupId>
+        <artifactId>ignite-parent</artifactId>
+        <version>1</version>
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>ignite-network-api</artifactId>
+    <version>3.0.0-SNAPSHOT</version>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.ignite</groupId>
+            <artifactId>ignite-core</artifactId>
+        </dependency>
+
+        <dependency>

Review comment:
       Please add a comment declaring that following dependencies are test-only.

##########
File path: modules/network-annotation-processor/src/main/java/org/apache/ignite/network/processor/internal/AutoSerializableProcessor.java
##########
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringJoiner;
+import java.util.stream.Collectors;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+import org.apache.ignite.network.serialization.MessageDeserializer;
+import org.apache.ignite.network.serialization.MessageSerializationFactory;
+import org.apache.ignite.network.serialization.MessageSerializationRegistry;
+import org.apache.ignite.network.serialization.MessageSerializer;
+
+/**
+ * Annotation processor for generating (de-)serializers for network messages marked with the {@link AutoSerializable}
+ * annotation.
+ */
+@SupportedSourceVersion(SourceVersion.RELEASE_11)
+public class AutoSerializableProcessor extends AbstractProcessor {
+    /** {@inheritDoc} */
+    @Override public Set<String> getSupportedAnnotationTypes() {
+        return Set.of(AutoSerializable.class.getName());
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        Set<TypeElement> annotatedElements = annotations.stream()
+            .map(roundEnv::getElementsAnnotatedWith)
+            .flatMap(Collection::stream)
+            .map(TypeElement.class::cast)
+            .collect(Collectors.toUnmodifiableSet());
+
+        if (annotatedElements.isEmpty()) {
+            return true;
+        }
+
+        try {
+            generateSources(annotatedElements);
+        } catch (IOException e) {
+            throw new IllegalStateException("IO exception during annotation processing", e);
+        }
+
+        return true;
+    }
+
+    /**
+     * Generates serialization-related classes for the given elements.
+     */
+    private void generateSources(Set<TypeElement> annotatedElements) throws IOException {
+        var factories = new HashMap<TypeElement, TypeSpec>();
+
+        for (var messageClass : annotatedElements) {
+            try {
+                if (isValidElement(messageClass)) {
+                    String packageName = ClassName.get(messageClass).packageName();
+
+                    TypeSpec serializer = generateSerializer(messageClass);
+                    writeToFile(packageName, serializer);
+
+                    TypeSpec deserializer = generateDeseralizer(messageClass);
+                    writeToFile(packageName, deserializer);
+
+                    TypeSpec factory = generateFactory(messageClass, serializer, deserializer);
+                    writeToFile(packageName, factory);
+
+                    factories.put(messageClass, factory);
+                } else {
+                    processingEnv.getMessager().printMessage(
+                        Diagnostic.Kind.ERROR,
+                        String.format(
+                            "%s annotation must only be present on interfaces that extend %s",
+                            AutoSerializable.class, NetworkMessage.class
+                        ),
+                        messageClass
+                    );
+                }
+            } catch (ProcessingException e) {
+                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), messageClass);
+            }
+        }
+
+        TypeSpec registryInitializer = generateRegistryInitializer(factories);
+        writeToFile(getParentPackage(annotatedElements), registryInitializer);

Review comment:
       Can we put it to the same package where builder factory is located?

##########
File path: modules/network-annotation-processor/src/integrationTest/resources/org/apache/ignite/network/processor/internal/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.processor.internal;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.network.processor.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)
+public interface AllTypesMessage extends NetworkMessage {
+    short TYPE = 123;
+
+    byte a();
+
+    short b();
+
+    int c();
+
+    long d();
+
+    float e();
+
+    double f();
+
+    char g();
+
+    boolean h();
+
+    byte[] i();
+
+    short[] j();
+
+    int[] k();
+
+    long[] l();
+
+    float[] m();
+
+    double[] n();
+
+    char[] o();
+
+    boolean[] p();
+
+    String q();
+
+    BitSet r();
+
+    UUID s();
+
+    IgniteUuid t();
+
+    NetworkMessage u();
+
+    NetworkMessage[] v();
+
+    Collection<NetworkMessage> w();
+
+    Map<String, NetworkMessage> x();
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override public default short directType() {
+        return 5555;
+    }
+
+    interface Builder {
+        AllTypesMessage build();
+
+        Builder a(byte a);
+
+        Builder b(short b);
+
+        Builder c(int c);
+
+        Builder d(long d);
+
+        Builder e(float e);
+
+        Builder f(double f);
+
+        Builder g(char g);
+
+        Builder h(boolean h);
+
+        Builder i(byte[] i);
+
+        Builder j(short[] j);
+
+        Builder k(int[] k);
+
+        Builder l(long[] l);
+
+        Builder m(float[] m);
+
+        Builder n(double[] n);
+
+        Builder o(char[] o);
+
+        Builder p(boolean[] p);
+
+        Builder q(String q);
+
+        Builder r(BitSet r);
+
+        Builder s(UUID s);
+
+        Builder t(IgniteUuid t);
+
+        Builder u(NetworkMessage u);

Review comment:
       We might want to have directly marshallable classes that can't be used as messages. So we should think of other name for new superinterface.

##########
File path: modules/network/src/test/java/org/apache/ignite/network/internal/AllTypesMessageImpl.java
##########
@@ -0,0 +1,496 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.internal;
+
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.NetworkMessage;
+import org.apache.ignite.plugin.extensions.communication.MessageCollectionItemType;
+
+/**
+ * Message with all types supported by Direct Marshalling.
+ */
+class AllTypesMessageImpl implements AllTypesMessage, AllTypesMessage.Builder {

Review comment:
       Why do we need impl class if it's auto-generated?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [ignite-3] sashapolo commented on a change in pull request #130: IGNITE-14649 Annotation processor for network message (de-)serializers

Posted by GitBox <gi...@apache.org>.
sashapolo commented on a change in pull request #130:
URL: https://github.com/apache/ignite-3/pull/130#discussion_r637589306



##########
File path: modules/network-messages/src/integrationTest/resources/org/apache/ignite/network/messages/internal/processor/AllTypesMessage.java
##########
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.network.messages.internal.processor;
+
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.lang.IgniteUuid;
+import org.apache.ignite.network.messages.NetworkMessage;
+import org.apache.ignite.network.messages.annotations.AutoSerializable;
+
+@AutoSerializable(messageFactory = AllTypesMessageFactory.class)
+public interface AllTypesMessage extends NetworkMessage {
+    short TYPE = 123;
+
+    byte a();
+
+    short b();
+
+    int c();
+
+    long d();
+
+    float e();
+
+    double f();
+
+    char g();
+
+    boolean h();
+
+    byte[] i();
+
+    short[] j();
+
+    int[] k();
+
+    long[] l();
+
+    float[] m();
+
+    double[] n();
+
+    char[] o();
+
+    boolean[] p();
+
+    String q();
+
+    BitSet r();
+
+    UUID s();
+
+    IgniteUuid t();
+
+    NetworkMessage u();
+
+    NetworkMessage[] v();
+
+    Collection<NetworkMessage> w();
+
+    Map<String, NetworkMessage> x();
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override public default short directType() {
+        return 5555;
+    }
+
+    interface Builder {

Review comment:
       Can you elaborate, please?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org