From 5df7fa4577f117f0cc3e6705dbe1ed4103ef6fad Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sun, 1 Oct 2023 14:35:18 +0800 Subject: [PATCH 01/10] Add SimplePojo and compatibility unit tests --- .../converters/generated/dataobjects.proto | 11 ++ .../converter/SimplePojoProtoConverter.java | 131 ++++++++++++++++ .../test/codegen/converter/SimplePojo.java | 96 ++++++++++++ .../codegen/protobuf/CompatibilityTest.java | 140 ++++++++++++++++++ 4 files changed, 378 insertions(+) create mode 100644 vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java create mode 100644 vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java create mode 100644 vertx-codegen-protobuf/src/test/java/io/vertx/test/codegen/protobuf/CompatibilityTest.java diff --git a/vertx-codegen-protobuf/src/converters/generated/dataobjects.proto b/vertx-codegen-protobuf/src/converters/generated/dataobjects.proto index 2bddf194c..6cd8f8802 100644 --- a/vertx-codegen-protobuf/src/converters/generated/dataobjects.proto +++ b/vertx-codegen-protobuf/src/converters/generated/dataobjects.proto @@ -29,6 +29,17 @@ message RecursiveItem { RecursiveItem childC = 4; } +message SimplePojo { + int32 nullInteger = 1; + int32 zeroInteger = 2; + bool nullBoolean = 3; + bool zeroBoolean = 4; + string nullString = 5; + string zeroString = 6; + int32 primitiveInteger = 7; + bool primitiveBoolean = 8; +} + message User { string userName = 1; int32 age = 2; diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java new file mode 100644 index 000000000..758678801 --- /dev/null +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java @@ -0,0 +1,131 @@ +package io.vertx.test.codegen.converter; + +import com.google.protobuf.CodedOutputStream; +import com.google.protobuf.CodedInputStream; +import java.io.IOException; +import java.time.Instant; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.HashMap; +import java.util.Map; +import java.util.Arrays; +import io.vertx.core.json.JsonObject; +import io.vertx.codegen.protobuf.utils.ExpandableIntArray; +import io.vertx.codegen.protobuf.converters.*; + +public class SimplePojoProtoConverter { + + public static void fromProto(CodedInputStream input, SimplePojo obj) throws IOException { + int tag; + while ((tag = input.readTag()) != 0) { + switch (tag) { + case 8: { + obj.setNullInteger(input.readInt32()); + break; + } + case 16: { + obj.setZeroInteger(input.readInt32()); + break; + } + case 24: { + obj.setNullBoolean(input.readBool()); + break; + } + case 32: { + obj.setZeroBoolean(input.readBool()); + break; + } + case 42: { + obj.setNullString(input.readString()); + break; + } + case 50: { + obj.setZeroString(input.readString()); + break; + } + case 56: { + obj.setPrimitiveInteger(input.readInt32()); + break; + } + case 64: { + obj.setPrimitiveBoolean(input.readBool()); + break; + } + } + } + } + + public static void toProto(SimplePojo obj, CodedOutputStream output) throws IOException { + ExpandableIntArray cache = new ExpandableIntArray(16); + SimplePojoProtoConverter.computeSize(obj, cache, 0); + SimplePojoProtoConverter.toProto(obj, output, cache, 0); + } + + public static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIntArray cache, int index) throws IOException { + index = index + 1; + if (obj.getNullInteger() != null) { + output.writeInt32(1, obj.getNullInteger()); + } + if (obj.getZeroInteger() != null) { + output.writeInt32(2, obj.getZeroInteger()); + } + if (obj.getNullBoolean() != null) { + output.writeBool(3, obj.getNullBoolean()); + } + if (obj.getZeroBoolean() != null) { + output.writeBool(4, obj.getZeroBoolean()); + } + if (obj.getNullString() != null) { + output.writeString(5, obj.getNullString()); + } + if (obj.getZeroString() != null) { + output.writeString(6, obj.getZeroString()); + } + if (obj.getPrimitiveInteger() != 0) { + output.writeInt32(7, obj.getPrimitiveInteger()); + } + if (obj.isPrimitiveBoolean()) { + output.writeBool(8, obj.isPrimitiveBoolean()); + } + return index; + } + + public static int computeSize(SimplePojo obj) { + ExpandableIntArray cache = new ExpandableIntArray(16); + SimplePojoProtoConverter.computeSize(obj, cache, 0); + return cache.get(0); + } + + public static int computeSize(SimplePojo obj, ExpandableIntArray cache, final int baseIndex) { + int size = 0; + int index = baseIndex + 1; + if (obj.getNullInteger() != null) { + size += CodedOutputStream.computeInt32Size(1, obj.getNullInteger()); + } + if (obj.getZeroInteger() != null) { + size += CodedOutputStream.computeInt32Size(2, obj.getZeroInteger()); + } + if (obj.getNullBoolean() != null) { + size += CodedOutputStream.computeBoolSize(3, obj.getNullBoolean()); + } + if (obj.getZeroBoolean() != null) { + size += CodedOutputStream.computeBoolSize(4, obj.getZeroBoolean()); + } + if (obj.getNullString() != null) { + size += CodedOutputStream.computeStringSize(5, obj.getNullString()); + } + if (obj.getZeroString() != null) { + size += CodedOutputStream.computeStringSize(6, obj.getZeroString()); + } + if (obj.getPrimitiveInteger() != 0) { + size += CodedOutputStream.computeInt32Size(7, obj.getPrimitiveInteger()); + } + if (obj.isPrimitiveBoolean()) { + size += CodedOutputStream.computeBoolSize(8, obj.isPrimitiveBoolean()); + } + cache.set(baseIndex, size); + return index; + } + +} diff --git a/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java b/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java new file mode 100644 index 000000000..64c23e6d3 --- /dev/null +++ b/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java @@ -0,0 +1,96 @@ +package io.vertx.test.codegen.converter; + +import io.vertx.codegen.annotations.DataObject; +import io.vertx.codegen.protobuf.annotations.ProtobufGen; + +import java.util.Objects; + +@DataObject +@ProtobufGen +public class SimplePojo { + private Integer nullInteger; + private Integer zeroInteger; + private Boolean nullBoolean; + private Boolean zeroBoolean; + private String nullString; + private String ZeroString; + private int primitiveInteger; + private boolean primitiveBoolean; + + public Integer getNullInteger() { + return nullInteger; + } + + public void setNullInteger(Integer nullInteger) { + this.nullInteger = nullInteger; + } + + public Integer getZeroInteger() { + return zeroInteger; + } + + public void setZeroInteger(Integer zeroInteger) { + this.zeroInteger = zeroInteger; + } + + public Boolean getNullBoolean() { + return nullBoolean; + } + + public void setNullBoolean(Boolean nullBoolean) { + this.nullBoolean = nullBoolean; + } + + public Boolean getZeroBoolean() { + return zeroBoolean; + } + + public void setZeroBoolean(Boolean zeroBoolean) { + this.zeroBoolean = zeroBoolean; + } + + public String getNullString() { + return nullString; + } + + public void setNullString(String nullString) { + this.nullString = nullString; + } + + public String getZeroString() { + return ZeroString; + } + + public void setZeroString(String zeroString) { + this.ZeroString = zeroString; + } + + public int getPrimitiveInteger() { + return primitiveInteger; + } + + public void setPrimitiveInteger(int primitiveInteger) { + this.primitiveInteger = primitiveInteger; + } + + public boolean isPrimitiveBoolean() { + return primitiveBoolean; + } + + public void setPrimitiveBoolean(boolean primitiveBoolean) { + this.primitiveBoolean = primitiveBoolean; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SimplePojo that = (SimplePojo) o; + return primitiveInteger == that.primitiveInteger && primitiveBoolean == that.primitiveBoolean && Objects.equals(nullInteger, that.nullInteger) && Objects.equals(zeroInteger, that.zeroInteger) && Objects.equals(nullBoolean, that.nullBoolean) && Objects.equals(zeroBoolean, that.zeroBoolean) && Objects.equals(nullString, that.nullString) && Objects.equals(ZeroString, that.ZeroString); + } + + @Override + public int hashCode() { + return Objects.hash(nullInteger, zeroInteger, nullBoolean, zeroBoolean, nullString, ZeroString, primitiveInteger, primitiveBoolean); + } +} diff --git a/vertx-codegen-protobuf/src/test/java/io/vertx/test/codegen/protobuf/CompatibilityTest.java b/vertx-codegen-protobuf/src/test/java/io/vertx/test/codegen/protobuf/CompatibilityTest.java new file mode 100644 index 000000000..4d0aa4b2f --- /dev/null +++ b/vertx-codegen-protobuf/src/test/java/io/vertx/test/codegen/protobuf/CompatibilityTest.java @@ -0,0 +1,140 @@ +package io.vertx.test.codegen.protobuf; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import com.google.protobuf.InvalidProtocolBufferException; +import io.vertx.test.codegen.converter.SimplePojo; +import io.vertx.test.codegen.converter.SimplePojoProtoConverter; +import org.junit.Assert; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + + +public class CompatibilityTest { + @Test + public void testVertxConverter() throws IOException { + // Populate a POJO + SimplePojo pojo = new SimplePojo(); + pojo.setNullInteger(null); + pojo.setNullBoolean(null); + pojo.setNullString(null); + pojo.setZeroInteger(0); + pojo.setZeroBoolean(false); + pojo.setZeroString(""); + pojo.setPrimitiveInteger(0); + pojo.setPrimitiveBoolean(false); + + // Vertx Encode + byte[] encoded = vertxEncode(pojo); + + // Vertx Decode + SimplePojo decoded = vertxDecode(encoded); + + // Decoded is exactly the same with original pojo + Assert.assertEquals(pojo, decoded); + + Assert.assertEquals(null, decoded.getNullInteger()); + Assert.assertEquals(null, decoded.getNullBoolean()); + Assert.assertEquals(null, decoded.getNullString()); + Assert.assertEquals((Integer) 0, decoded.getZeroInteger()); + Assert.assertEquals(false, decoded.getZeroBoolean()); + Assert.assertEquals("", decoded.getZeroString()); + Assert.assertEquals(0, decoded.getPrimitiveInteger()); + Assert.assertEquals(false, decoded.isPrimitiveBoolean()); + + // Assert total size is equal to computed size + Assert.assertEquals(encoded.length, SimplePojoProtoConverter.computeSize(pojo)); + } + + @Test + public void testProtocDecode() throws IOException { + // Populate a POJO + SimplePojo pojo = new SimplePojo(); + pojo.setNullInteger(null); + pojo.setNullBoolean(null); + pojo.setNullString(null); + pojo.setZeroInteger(0); + pojo.setZeroBoolean(false); + pojo.setZeroString(""); + pojo.setPrimitiveInteger(0); + pojo.setPrimitiveBoolean(false); + + // Vertx Encode + byte[] encoded = vertxEncode(pojo); + + // Protoc Decode + io.vertx.protobuf.generated.SimplePojo decoded = protocDecode(encoded); + + Assert.assertEquals(0, decoded.getNullInteger()); // Integer in Google Protoc is not nullable + Assert.assertEquals(false, decoded.getNullBoolean()); // Boolean in Google Protoc is not nullable + Assert.assertEquals("", decoded.getNullString()); // String in Google Protoc is not nullable + Assert.assertEquals(0, decoded.getZeroInteger()); + Assert.assertEquals(false, decoded.getZeroBoolean()); + Assert.assertEquals("", decoded.getZeroString()); + Assert.assertEquals(0, decoded.getPrimitiveInteger()); + Assert.assertEquals(false, decoded.getPrimitiveBoolean()); + } + + @Test + public void testProtocEncode() throws IOException { + // Populate a Protoc generated POJO + io.vertx.protobuf.generated.SimplePojo pojo = io.vertx.protobuf.generated.SimplePojo.newBuilder() + .setNullInteger(0) // cannot set null integer, won't compile + .setNullBoolean(false) // cannot set null boolean, won't compile + .setNullString("") // cannot set null string, will throw NPE + .setZeroInteger(0) + .setZeroBoolean(false) + .setZeroString("") + .setPrimitiveInteger(0) + .setPrimitiveBoolean(false) + .build(); + + // Protoc Encode + byte[] encoded = protocEncode(pojo); + + // Vertx Decode + SimplePojo decoded = vertxDecode(encoded); + + Assert.assertEquals(null, decoded.getNullInteger()); + Assert.assertEquals(null, decoded.getNullBoolean()); + Assert.assertEquals(null, decoded.getNullString()); + Assert.assertEquals(null, decoded.getZeroInteger()); + Assert.assertEquals(null, decoded.getZeroBoolean()); + Assert.assertEquals(null, decoded.getZeroString()); + Assert.assertEquals(0, decoded.getPrimitiveInteger()); + Assert.assertEquals(false, decoded.isPrimitiveBoolean()); + } + + private byte[] vertxEncode(SimplePojo obj) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + CodedOutputStream output = CodedOutputStream.newInstance(baos); + SimplePojoProtoConverter.toProto(obj, output); + output.flush(); + byte[] encoded = baos.toByteArray(); + TestUtils.debug("Vertx encoded", encoded); + return encoded; + } + + private byte[] protocEncode(io.vertx.protobuf.generated.SimplePojo obj) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + CodedOutputStream output = CodedOutputStream.newInstance(baos); + obj.writeTo(output); + output.flush(); + byte[] encoded = baos.toByteArray(); + TestUtils.debug("Protoc encoded", encoded); + return encoded; + } + + private io.vertx.protobuf.generated.SimplePojo protocDecode(byte[] arr) throws InvalidProtocolBufferException { + return io.vertx.protobuf.generated.SimplePojo.parseFrom(arr); + } + + private SimplePojo vertxDecode(byte[] arr) throws IOException { + CodedInputStream input = CodedInputStream.newInstance(arr); + SimplePojo obj = new SimplePojo(); + SimplePojoProtoConverter.fromProto(input, obj); + return obj; + } +} From 31b4ca030b0a2828316234c1ec3e0348d5cb2b9e Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sun, 8 Oct 2023 11:51:21 +0800 Subject: [PATCH 02/10] Add compatibleMode flag --- .../converter/AddressProtoConverter.java | 33 ++++++-- .../RecursiveItemProtoConverter.java | 39 ++++++--- .../converter/SimplePojoProtoConverter.java | 42 ++++++++-- .../codegen/converter/UserProtoConverter.java | 57 ++++++++++--- .../generator/DataObjectProtobufGen.java | 80 ++++++++++++++++--- .../codegen/protobuf/CompatibilityTest.java | 20 ++--- 6 files changed, 217 insertions(+), 54 deletions(-) diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java index 863756ed3..6c3958307 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java @@ -17,6 +17,10 @@ public class AddressProtoConverter { public static void fromProto(CodedInputStream input, Address obj) throws IOException { + fromProto(input, obj, false); + } + + public static void fromProto(CodedInputStream input, Address obj, boolean compatibleMode) throws IOException { int tag; while ((tag = input.readTag()) != 0) { switch (tag) { @@ -34,15 +38,30 @@ public static void fromProto(CodedInputStream input, Address obj) throws IOExcep } } } + if (compatibleMode) { + if (obj.getName() == null) { + obj.setName(""); + } + if (obj.getLongitude() == null) { + obj.setLongitude(0f); + } + if (obj.getLatitude() == null) { + obj.setLatitude(0f); + } + } } public static void toProto(Address obj, CodedOutputStream output) throws IOException { + toProto(obj, output, false); + } + + public static void toProto(Address obj, CodedOutputStream output, boolean compatibleMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - AddressProtoConverter.computeSize(obj, cache, 0); - AddressProtoConverter.toProto(obj, output, cache, 0); + AddressProtoConverter.computeSize(obj, cache, 0, compatibleMode); + AddressProtoConverter.toProto(obj, output, cache, 0, compatibleMode); } - public static int toProto(Address obj, CodedOutputStream output, ExpandableIntArray cache, int index) throws IOException { + static int toProto(Address obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { index = index + 1; if (obj.getName() != null) { output.writeString(1, obj.getName()); @@ -57,12 +76,16 @@ public static int toProto(Address obj, CodedOutputStream output, ExpandableIntAr } public static int computeSize(Address obj) { + return computeSize(obj, false); + } + + public static int computeSize(Address obj, boolean compatibleMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - AddressProtoConverter.computeSize(obj, cache, 0); + AddressProtoConverter.computeSize(obj, cache, 0, compatibleMode); return cache.get(0); } - public static int computeSize(Address obj, ExpandableIntArray cache, final int baseIndex) { + static int computeSize(Address obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { int size = 0; int index = baseIndex + 1; if (obj.getName() != null) { diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java index 659e4273d..4c991d54f 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java @@ -17,6 +17,10 @@ public class RecursiveItemProtoConverter { public static void fromProto(CodedInputStream input, RecursiveItem obj) throws IOException { + fromProto(input, obj, false); + } + + public static void fromProto(CodedInputStream input, RecursiveItem obj, boolean compatibleMode) throws IOException { int tag; while ((tag = input.readTag()) != 0) { switch (tag) { @@ -53,15 +57,24 @@ public static void fromProto(CodedInputStream input, RecursiveItem obj) throws I } } } + if (compatibleMode) { + if (obj.getId() == null) { + obj.setId(""); + } + } } public static void toProto(RecursiveItem obj, CodedOutputStream output) throws IOException { + toProto(obj, output, false); + } + + public static void toProto(RecursiveItem obj, CodedOutputStream output, boolean compatibleMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - RecursiveItemProtoConverter.computeSize(obj, cache, 0); - RecursiveItemProtoConverter.toProto(obj, output, cache, 0); + RecursiveItemProtoConverter.computeSize(obj, cache, 0, compatibleMode); + RecursiveItemProtoConverter.toProto(obj, output, cache, 0, compatibleMode); } - public static int toProto(RecursiveItem obj, CodedOutputStream output, ExpandableIntArray cache, int index) throws IOException { + static int toProto(RecursiveItem obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { index = index + 1; if (obj.getId() != null) { output.writeString(1, obj.getId()); @@ -69,28 +82,32 @@ public static int toProto(RecursiveItem obj, CodedOutputStream output, Expandabl if (obj.getChildA() != null) { output.writeUInt32NoTag(18); output.writeUInt32NoTag(cache.get(index)); - index = RecursiveItemProtoConverter.toProto(obj.getChildA(), output, cache, index); + index = RecursiveItemProtoConverter.toProto(obj.getChildA(), output, cache, index, compatibleMode); } if (obj.getChildB() != null) { output.writeUInt32NoTag(26); output.writeUInt32NoTag(cache.get(index)); - index = RecursiveItemProtoConverter.toProto(obj.getChildB(), output, cache, index); + index = RecursiveItemProtoConverter.toProto(obj.getChildB(), output, cache, index, compatibleMode); } if (obj.getChildC() != null) { output.writeUInt32NoTag(34); output.writeUInt32NoTag(cache.get(index)); - index = RecursiveItemProtoConverter.toProto(obj.getChildC(), output, cache, index); + index = RecursiveItemProtoConverter.toProto(obj.getChildC(), output, cache, index, compatibleMode); } return index; } public static int computeSize(RecursiveItem obj) { + return computeSize(obj, false); + } + + public static int computeSize(RecursiveItem obj, boolean compatibleMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - RecursiveItemProtoConverter.computeSize(obj, cache, 0); + RecursiveItemProtoConverter.computeSize(obj, cache, 0, compatibleMode); return cache.get(0); } - public static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final int baseIndex) { + static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { int size = 0; int index = baseIndex + 1; if (obj.getId() != null) { @@ -99,7 +116,7 @@ public static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final if (obj.getChildA() != null) { size += CodedOutputStream.computeUInt32SizeNoTag(18); int savedIndex = index; - index = RecursiveItemProtoConverter.computeSize(obj.getChildA(), cache, index); + index = RecursiveItemProtoConverter.computeSize(obj.getChildA(), cache, index, compatibleMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; @@ -107,7 +124,7 @@ public static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final if (obj.getChildB() != null) { size += CodedOutputStream.computeUInt32SizeNoTag(26); int savedIndex = index; - index = RecursiveItemProtoConverter.computeSize(obj.getChildB(), cache, index); + index = RecursiveItemProtoConverter.computeSize(obj.getChildB(), cache, index, compatibleMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; @@ -115,7 +132,7 @@ public static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final if (obj.getChildC() != null) { size += CodedOutputStream.computeUInt32SizeNoTag(34); int savedIndex = index; - index = RecursiveItemProtoConverter.computeSize(obj.getChildC(), cache, index); + index = RecursiveItemProtoConverter.computeSize(obj.getChildC(), cache, index, compatibleMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java index 758678801..9691f8fa6 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java @@ -17,6 +17,10 @@ public class SimplePojoProtoConverter { public static void fromProto(CodedInputStream input, SimplePojo obj) throws IOException { + fromProto(input, obj, false); + } + + public static void fromProto(CodedInputStream input, SimplePojo obj, boolean compatibleMode) throws IOException { int tag; while ((tag = input.readTag()) != 0) { switch (tag) { @@ -54,15 +58,39 @@ public static void fromProto(CodedInputStream input, SimplePojo obj) throws IOEx } } } + if (compatibleMode) { + if (obj.getNullInteger() == null) { + obj.setNullInteger(0); + } + if (obj.getZeroInteger() == null) { + obj.setZeroInteger(0); + } + if (obj.getNullBoolean() == null) { + obj.setNullBoolean(false); + } + if (obj.getZeroBoolean() == null) { + obj.setZeroBoolean(false); + } + if (obj.getNullString() == null) { + obj.setNullString(""); + } + if (obj.getZeroString() == null) { + obj.setZeroString(""); + } + } } public static void toProto(SimplePojo obj, CodedOutputStream output) throws IOException { + toProto(obj, output, false); + } + + public static void toProto(SimplePojo obj, CodedOutputStream output, boolean compatibleMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - SimplePojoProtoConverter.computeSize(obj, cache, 0); - SimplePojoProtoConverter.toProto(obj, output, cache, 0); + SimplePojoProtoConverter.computeSize(obj, cache, 0, compatibleMode); + SimplePojoProtoConverter.toProto(obj, output, cache, 0, compatibleMode); } - public static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIntArray cache, int index) throws IOException { + static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { index = index + 1; if (obj.getNullInteger() != null) { output.writeInt32(1, obj.getNullInteger()); @@ -92,12 +120,16 @@ public static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIn } public static int computeSize(SimplePojo obj) { + return computeSize(obj, false); + } + + public static int computeSize(SimplePojo obj, boolean compatibleMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - SimplePojoProtoConverter.computeSize(obj, cache, 0); + SimplePojoProtoConverter.computeSize(obj, cache, 0, compatibleMode); return cache.get(0); } - public static int computeSize(SimplePojo obj, ExpandableIntArray cache, final int baseIndex) { + static int computeSize(SimplePojo obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { int size = 0; int index = baseIndex + 1; if (obj.getNullInteger() != null) { diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java index c1dd876e7..26222b5ab 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java @@ -17,6 +17,10 @@ public class UserProtoConverter { public static void fromProto(CodedInputStream input, User obj) throws IOException { + fromProto(input, obj, false); + } + + public static void fromProto(CodedInputStream input, User obj, boolean compatibleMode) throws IOException { int tag; while ((tag = input.readTag()) != 0) { switch (tag) { @@ -272,15 +276,42 @@ public static void fromProto(CodedInputStream input, User obj) throws IOExceptio } } } + if (compatibleMode) { + if (obj.getUserName() == null) { + obj.setUserName(""); + } + if (obj.getAge() == null) { + obj.setAge(0); + } + if (obj.getDoubleField() == null) { + obj.setDoubleField(0d); + } + if (obj.getFloatField() == null) { + obj.setFloatField(0f); + } + if (obj.getLongField() == null) { + obj.setLongField(0L); + } + if (obj.getBoolField() == null) { + obj.setBoolField(false); + } + if (obj.getShortField() == null) { + obj.setShortField((short)0); + } + } } public static void toProto(User obj, CodedOutputStream output) throws IOException { + toProto(obj, output, false); + } + + public static void toProto(User obj, CodedOutputStream output, boolean compatibleMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - UserProtoConverter.computeSize(obj, cache, 0); - UserProtoConverter.toProto(obj, output, cache, 0); + UserProtoConverter.computeSize(obj, cache, 0, compatibleMode); + UserProtoConverter.toProto(obj, output, cache, 0, compatibleMode); } - public static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, int index) throws IOException { + static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { index = index + 1; if (obj.getUserName() != null) { output.writeString(1, obj.getUserName()); @@ -308,7 +339,7 @@ public static int toProto(User obj, CodedOutputStream output, ExpandableIntArray for (Address element: obj.getStructListField()) { output.writeUInt32NoTag(34); output.writeUInt32NoTag(cache.get(index)); - index = AddressProtoConverter.toProto(element, output, cache, index); + index = AddressProtoConverter.toProto(element, output, cache, index, compatibleMode); } } if (obj.getZonedDateTimeListField() != null) { @@ -332,7 +363,7 @@ public static int toProto(User obj, CodedOutputStream output, ExpandableIntArray if (obj.getAddress() != null) { output.writeUInt32NoTag(58); output.writeUInt32NoTag(cache.get(index)); - index = AddressProtoConverter.toProto(obj.getAddress(), output, cache, index); + index = AddressProtoConverter.toProto(obj.getAddress(), output, cache, index, compatibleMode); } if (obj.getByteField() != null) { output.writeInt32(8, obj.getByteField()); @@ -405,7 +436,7 @@ public static int toProto(User obj, CodedOutputStream output, ExpandableIntArray output.writeString(1, entry.getKey()); output.writeUInt32NoTag(18); output.writeUInt32NoTag(elementSize); - index = AddressProtoConverter.toProto(entry.getValue(), output, cache, index); + index = AddressProtoConverter.toProto(entry.getValue(), output, cache, index, compatibleMode); } } if (obj.getJsonValueMap() != null) { @@ -511,12 +542,16 @@ public static int toProto(User obj, CodedOutputStream output, ExpandableIntArray } public static int computeSize(User obj) { + return computeSize(obj, false); + } + + public static int computeSize(User obj, boolean compatibleMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - UserProtoConverter.computeSize(obj, cache, 0); + UserProtoConverter.computeSize(obj, cache, 0, compatibleMode); return cache.get(0); } - public static int computeSize(User obj, ExpandableIntArray cache, final int baseIndex) { + static int computeSize(User obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { int size = 0; int index = baseIndex + 1; if (obj.getUserName() != null) { @@ -544,7 +579,7 @@ public static int computeSize(User obj, ExpandableIntArray cache, final int base for (Address element: obj.getStructListField()) { size += CodedOutputStream.computeUInt32SizeNoTag(34); int savedIndex = index; - index = AddressProtoConverter.computeSize(element, cache, index); + index = AddressProtoConverter.computeSize(element, cache, index, compatibleMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; @@ -578,7 +613,7 @@ public static int computeSize(User obj, ExpandableIntArray cache, final int base if (obj.getAddress() != null) { size += CodedOutputStream.computeUInt32SizeNoTag(58); int savedIndex = index; - index = AddressProtoConverter.computeSize(obj.getAddress(), cache, index); + index = AddressProtoConverter.computeSize(obj.getAddress(), cache, index, compatibleMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; @@ -639,7 +674,7 @@ public static int computeSize(User obj, ExpandableIntArray cache, final int base dataSize += CodedOutputStream.computeStringSize(1, entry.getKey()); // value int savedIndex = index; - index = AddressProtoConverter.computeSize(entry.getValue(), cache, index); + index = AddressProtoConverter.computeSize(entry.getValue(), cache, index, compatibleMode); int elementSize = cache.get(savedIndex); dataSize += CodedOutputStream.computeInt32SizeNoTag(18); dataSize += CodedOutputStream.computeInt32SizeNoTag(elementSize); diff --git a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java index 99bc6db30..8cac595a4 100644 --- a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java +++ b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java @@ -79,6 +79,10 @@ public String renderProto(DataObjectModel model, int index, int size, Map Date: Sat, 14 Oct 2023 13:58:33 +0800 Subject: [PATCH 03/10] implements compatibleMode --- .../converters/generated/dataobjects.proto | 12 +- .../converter/AddressProtoConverter.java | 36 +++-- .../RecursiveItemProtoConverter.java | 19 ++- .../converter/SimplePojoProtoConverter.java | 118 ++++++---------- .../codegen/converter/UserProtoConverter.java | 101 +++++++++----- .../test/codegen/converter/SimplePojo.java | 80 +++-------- .../generator/DataObjectProtobufGen.java | 86 ++++++------ .../protobuf/generator/ProtoProperty.java | 72 ++++++++++ .../codegen/protobuf/CompatibilityTest.java | 128 ++++++++++-------- 9 files changed, 359 insertions(+), 293 deletions(-) diff --git a/vertx-codegen-protobuf/src/converters/generated/dataobjects.proto b/vertx-codegen-protobuf/src/converters/generated/dataobjects.proto index 6cd8f8802..da0490223 100644 --- a/vertx-codegen-protobuf/src/converters/generated/dataobjects.proto +++ b/vertx-codegen-protobuf/src/converters/generated/dataobjects.proto @@ -30,14 +30,10 @@ message RecursiveItem { } message SimplePojo { - int32 nullInteger = 1; - int32 zeroInteger = 2; - bool nullBoolean = 3; - bool zeroBoolean = 4; - string nullString = 5; - string zeroString = 6; - int32 primitiveInteger = 7; - bool primitiveBoolean = 8; + int32 integerField = 1; + int64 longField = 2; + bool booleanField = 3; + string stringField = 4; } message User { diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java index 6c3958307..ba6fd0306 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java @@ -21,6 +21,11 @@ public static void fromProto(CodedInputStream input, Address obj) throws IOExcep } public static void fromProto(CodedInputStream input, Address obj, boolean compatibleMode) throws IOException { + if (compatibleMode) { + obj.setName(""); + obj.setLongitude(0f); + obj.setLatitude(0f); + } int tag; while ((tag = input.readTag()) != 0) { switch (tag) { @@ -37,18 +42,7 @@ public static void fromProto(CodedInputStream input, Address obj, boolean compat break; } } - } - if (compatibleMode) { - if (obj.getName() == null) { - obj.setName(""); - } - if (obj.getLongitude() == null) { - obj.setLongitude(0f); - } - if (obj.getLatitude() == null) { - obj.setLatitude(0f); - } - } + } // while loop } public static void toProto(Address obj, CodedOutputStream output) throws IOException { @@ -63,13 +57,25 @@ public static void toProto(Address obj, CodedOutputStream output, boolean compat static int toProto(Address obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { index = index + 1; - if (obj.getName() != null) { + // name + if (compatibleMode && obj.getName() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getName() != null) || (compatibleMode && !obj.getName().isEmpty())) { output.writeString(1, obj.getName()); } - if (obj.getLongitude() != null) { + // longitude + if (compatibleMode && obj.getLongitude() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getLongitude() != null) || (compatibleMode && obj.getLongitude() != 0f)) { output.writeFloat(2, obj.getLongitude()); } - if (obj.getLatitude() != null) { + // latitude + if (compatibleMode && obj.getLatitude() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getLatitude() != null) || (compatibleMode && obj.getLatitude() != 0f)) { output.writeFloat(3, obj.getLatitude()); } return index; diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java index 4c991d54f..389ec41fd 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java @@ -21,6 +21,9 @@ public static void fromProto(CodedInputStream input, RecursiveItem obj) throws I } public static void fromProto(CodedInputStream input, RecursiveItem obj, boolean compatibleMode) throws IOException { + if (compatibleMode) { + obj.setId(""); + } int tag; while ((tag = input.readTag()) != 0) { switch (tag) { @@ -56,12 +59,7 @@ public static void fromProto(CodedInputStream input, RecursiveItem obj, boolean break; } } - } - if (compatibleMode) { - if (obj.getId() == null) { - obj.setId(""); - } - } + } // while loop } public static void toProto(RecursiveItem obj, CodedOutputStream output) throws IOException { @@ -76,19 +74,26 @@ public static void toProto(RecursiveItem obj, CodedOutputStream output, boolean static int toProto(RecursiveItem obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { index = index + 1; - if (obj.getId() != null) { + // id + if (compatibleMode && obj.getId() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getId() != null) || (compatibleMode && !obj.getId().isEmpty())) { output.writeString(1, obj.getId()); } + // childA if (obj.getChildA() != null) { output.writeUInt32NoTag(18); output.writeUInt32NoTag(cache.get(index)); index = RecursiveItemProtoConverter.toProto(obj.getChildA(), output, cache, index, compatibleMode); } + // childB if (obj.getChildB() != null) { output.writeUInt32NoTag(26); output.writeUInt32NoTag(cache.get(index)); index = RecursiveItemProtoConverter.toProto(obj.getChildB(), output, cache, index, compatibleMode); } + // childC if (obj.getChildC() != null) { output.writeUInt32NoTag(34); output.writeUInt32NoTag(cache.get(index)); diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java index 9691f8fa6..3bd3e353e 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java @@ -21,63 +21,33 @@ public static void fromProto(CodedInputStream input, SimplePojo obj) throws IOEx } public static void fromProto(CodedInputStream input, SimplePojo obj, boolean compatibleMode) throws IOException { + if (compatibleMode) { + obj.setIntegerField(0); + obj.setLongField(0L); + obj.setBooleanField(false); + obj.setStringField(""); + } int tag; while ((tag = input.readTag()) != 0) { switch (tag) { case 8: { - obj.setNullInteger(input.readInt32()); + obj.setIntegerField(input.readInt32()); break; } case 16: { - obj.setZeroInteger(input.readInt32()); + obj.setLongField(input.readInt64()); break; } case 24: { - obj.setNullBoolean(input.readBool()); - break; - } - case 32: { - obj.setZeroBoolean(input.readBool()); + obj.setBooleanField(input.readBool()); break; } - case 42: { - obj.setNullString(input.readString()); + case 34: { + obj.setStringField(input.readString()); break; } - case 50: { - obj.setZeroString(input.readString()); - break; - } - case 56: { - obj.setPrimitiveInteger(input.readInt32()); - break; - } - case 64: { - obj.setPrimitiveBoolean(input.readBool()); - break; - } - } - } - if (compatibleMode) { - if (obj.getNullInteger() == null) { - obj.setNullInteger(0); } - if (obj.getZeroInteger() == null) { - obj.setZeroInteger(0); - } - if (obj.getNullBoolean() == null) { - obj.setNullBoolean(false); - } - if (obj.getZeroBoolean() == null) { - obj.setZeroBoolean(false); - } - if (obj.getNullString() == null) { - obj.setNullString(""); - } - if (obj.getZeroString() == null) { - obj.setZeroString(""); - } - } + } // while loop } public static void toProto(SimplePojo obj, CodedOutputStream output) throws IOException { @@ -92,29 +62,33 @@ public static void toProto(SimplePojo obj, CodedOutputStream output, boolean com static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { index = index + 1; - if (obj.getNullInteger() != null) { - output.writeInt32(1, obj.getNullInteger()); + // integerField + if (compatibleMode && obj.getIntegerField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); } - if (obj.getZeroInteger() != null) { - output.writeInt32(2, obj.getZeroInteger()); + if ((!compatibleMode && obj.getIntegerField() != null) || (compatibleMode && obj.getIntegerField() != 0)) { + output.writeInt32(1, obj.getIntegerField()); } - if (obj.getNullBoolean() != null) { - output.writeBool(3, obj.getNullBoolean()); + // longField + if (compatibleMode && obj.getLongField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); } - if (obj.getZeroBoolean() != null) { - output.writeBool(4, obj.getZeroBoolean()); + if ((!compatibleMode && obj.getLongField() != null) || (compatibleMode && obj.getLongField() != 0L)) { + output.writeInt64(2, obj.getLongField()); } - if (obj.getNullString() != null) { - output.writeString(5, obj.getNullString()); + // booleanField + if (compatibleMode && obj.getBooleanField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); } - if (obj.getZeroString() != null) { - output.writeString(6, obj.getZeroString()); + if ((!compatibleMode && obj.getBooleanField() != null) || (compatibleMode && !obj.getBooleanField())) { + output.writeBool(3, obj.getBooleanField()); } - if (obj.getPrimitiveInteger() != 0) { - output.writeInt32(7, obj.getPrimitiveInteger()); + // stringField + if (compatibleMode && obj.getStringField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); } - if (obj.isPrimitiveBoolean()) { - output.writeBool(8, obj.isPrimitiveBoolean()); + if ((!compatibleMode && obj.getStringField() != null) || (compatibleMode && !obj.getStringField().isEmpty())) { + output.writeString(4, obj.getStringField()); } return index; } @@ -132,29 +106,17 @@ public static int computeSize(SimplePojo obj, boolean compatibleMode) { static int computeSize(SimplePojo obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { int size = 0; int index = baseIndex + 1; - if (obj.getNullInteger() != null) { - size += CodedOutputStream.computeInt32Size(1, obj.getNullInteger()); - } - if (obj.getZeroInteger() != null) { - size += CodedOutputStream.computeInt32Size(2, obj.getZeroInteger()); - } - if (obj.getNullBoolean() != null) { - size += CodedOutputStream.computeBoolSize(3, obj.getNullBoolean()); - } - if (obj.getZeroBoolean() != null) { - size += CodedOutputStream.computeBoolSize(4, obj.getZeroBoolean()); - } - if (obj.getNullString() != null) { - size += CodedOutputStream.computeStringSize(5, obj.getNullString()); + if (obj.getIntegerField() != null) { + size += CodedOutputStream.computeInt32Size(1, obj.getIntegerField()); } - if (obj.getZeroString() != null) { - size += CodedOutputStream.computeStringSize(6, obj.getZeroString()); + if (obj.getLongField() != null) { + size += CodedOutputStream.computeInt64Size(2, obj.getLongField()); } - if (obj.getPrimitiveInteger() != 0) { - size += CodedOutputStream.computeInt32Size(7, obj.getPrimitiveInteger()); + if (obj.getBooleanField() != null) { + size += CodedOutputStream.computeBoolSize(3, obj.getBooleanField()); } - if (obj.isPrimitiveBoolean()) { - size += CodedOutputStream.computeBoolSize(8, obj.isPrimitiveBoolean()); + if (obj.getStringField() != null) { + size += CodedOutputStream.computeStringSize(4, obj.getStringField()); } cache.set(baseIndex, size); return index; diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java index 26222b5ab..502f19cea 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java @@ -21,6 +21,15 @@ public static void fromProto(CodedInputStream input, User obj) throws IOExceptio } public static void fromProto(CodedInputStream input, User obj, boolean compatibleMode) throws IOException { + if (compatibleMode) { + obj.setUserName(""); + obj.setAge(0); + obj.setDoubleField(0d); + obj.setFloatField(0f); + obj.setLongField(0L); + obj.setBoolField(false); + obj.setShortField((short)0); + } int tag; while ((tag = input.readTag()) != 0) { switch (tag) { @@ -275,30 +284,7 @@ public static void fromProto(CodedInputStream input, User obj, boolean compatibl break; } } - } - if (compatibleMode) { - if (obj.getUserName() == null) { - obj.setUserName(""); - } - if (obj.getAge() == null) { - obj.setAge(0); - } - if (obj.getDoubleField() == null) { - obj.setDoubleField(0d); - } - if (obj.getFloatField() == null) { - obj.setFloatField(0f); - } - if (obj.getLongField() == null) { - obj.setLongField(0L); - } - if (obj.getBoolField() == null) { - obj.setBoolField(false); - } - if (obj.getShortField() == null) { - obj.setShortField((short)0); - } - } + } // while loop } public static void toProto(User obj, CodedOutputStream output) throws IOException { @@ -313,12 +299,21 @@ public static void toProto(User obj, CodedOutputStream output, boolean compatibl static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { index = index + 1; - if (obj.getUserName() != null) { + // userName + if (compatibleMode && obj.getUserName() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getUserName() != null) || (compatibleMode && !obj.getUserName().isEmpty())) { output.writeString(1, obj.getUserName()); } - if (obj.getAge() != null) { + // age + if (compatibleMode && obj.getAge() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getAge() != null) || (compatibleMode && obj.getAge() != 0)) { output.writeInt32(2, obj.getAge()); } + // integerListField if (obj.getIntegerListField() != null) { // list | tag | data size | value[0] | value[1] | value[2] | if (obj.getIntegerListField().size() > 0) { @@ -333,6 +328,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, } } } + // structListField if (obj.getStructListField() != null) { // list[0] | tag | data size | value | // list[1] | tag | data size | value | @@ -342,6 +338,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, index = AddressProtoConverter.toProto(element, output, cache, index, compatibleMode); } } + // zonedDateTimeListField if (obj.getZonedDateTimeListField() != null) { // list[0] | tag | data size | value | // list[1] | tag | data size | value | @@ -351,6 +348,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, ZonedDateTimeProtoConverter.toProto(element, output); } } + // jsonListField if (obj.getJsonListField() != null) { // list[0] | tag | data size | value | // list[1] | tag | data size | value | @@ -360,32 +358,56 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, VertxStructProtoConverter.toProto(element, output); } } + // address if (obj.getAddress() != null) { output.writeUInt32NoTag(58); output.writeUInt32NoTag(cache.get(index)); index = AddressProtoConverter.toProto(obj.getAddress(), output, cache, index, compatibleMode); } + // byteField if (obj.getByteField() != null) { output.writeInt32(8, obj.getByteField()); } - if (obj.getDoubleField() != null) { + // doubleField + if (compatibleMode && obj.getDoubleField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getDoubleField() != null) || (compatibleMode && obj.getDoubleField() != 0d)) { output.writeDouble(9, obj.getDoubleField()); } - if (obj.getFloatField() != null) { + // floatField + if (compatibleMode && obj.getFloatField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getFloatField() != null) || (compatibleMode && obj.getFloatField() != 0f)) { output.writeFloat(10, obj.getFloatField()); } - if (obj.getLongField() != null) { + // longField + if (compatibleMode && obj.getLongField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getLongField() != null) || (compatibleMode && obj.getLongField() != 0L)) { output.writeInt64(11, obj.getLongField()); } - if (obj.getBoolField() != null) { + // boolField + if (compatibleMode && obj.getBoolField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getBoolField() != null) || (compatibleMode && !obj.getBoolField())) { output.writeBool(12, obj.getBoolField()); } - if (obj.getShortField() != null) { + // shortField + if (compatibleMode && obj.getShortField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getShortField() != null) || (compatibleMode && obj.getShortField() != (short)0)) { output.writeInt32(13, obj.getShortField()); } + // charField if (obj.getCharField() != null) { output.writeInt32(14, obj.getCharField()); } + // stringValueMap if (obj.getStringValueMap() != null) { // map[0] | tag | data size | key | value | // map[1] | tag | data size | key | value | @@ -402,6 +424,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, output.writeString(2, entry.getValue()); } } + // integerValueMap if (obj.getIntegerValueMap() != null) { // map[0] | tag | data size | key | value | // map[1] | tag | data size | key | value | @@ -418,6 +441,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, output.writeInt32(2, entry.getValue()); } } + // structValueMap if (obj.getStructValueMap() != null) { // map[0] | tag | data size | key | value | // map[1] | tag | data size | key | value | @@ -439,6 +463,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, index = AddressProtoConverter.toProto(entry.getValue(), output, cache, index, compatibleMode); } } + // jsonValueMap if (obj.getJsonValueMap() != null) { // map[0] | tag | data size | key | value | // map[1] | tag | data size | key | value | @@ -460,6 +485,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, VertxStructProtoConverter.toProto(entry.getValue(), output); } } + // zonedDateTimeValueMap if (obj.getZonedDateTimeValueMap() != null) { // map[0] | tag | data size | key | value | // map[1] | tag | data size | key | value | @@ -481,50 +507,63 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, ZonedDateTimeProtoConverter.toProto(entry.getValue(), output); } } + // zonedDateTimeField if (obj.getZonedDateTimeField() != null) { output.writeUInt32NoTag(162); output.writeUInt32NoTag(ZonedDateTimeProtoConverter.computeSize(obj.getZonedDateTimeField())); ZonedDateTimeProtoConverter.toProto(obj.getZonedDateTimeField(), output); } + // instantField if (obj.getInstantField() != null) { output.writeUInt32NoTag(170); output.writeUInt32NoTag(InstantProtoConverter.computeSize(obj.getInstantField())); InstantProtoConverter.toProto(obj.getInstantField(), output); } + // jsonObjectField if (obj.getJsonObjectField() != null) { output.writeUInt32NoTag(178); output.writeUInt32NoTag(VertxStructProtoConverter.computeSize(obj.getJsonObjectField())); VertxStructProtoConverter.toProto(obj.getJsonObjectField(), output); } + // jsonArrayField if (obj.getJsonArrayField() != null) { output.writeUInt32NoTag(186); output.writeUInt32NoTag(VertxStructListProtoConverter.computeSize(obj.getJsonArrayField())); VertxStructListProtoConverter.toProto(obj.getJsonArrayField(), output); } + // primitiveBoolean if (obj.isPrimitiveBoolean()) { output.writeBool(24, obj.isPrimitiveBoolean()); } + // primitiveByte if (obj.getPrimitiveByte() != 0) { output.writeInt32(25, obj.getPrimitiveByte()); } + // primitiveShort if (obj.getPrimitiveShort() != 0) { output.writeInt32(26, obj.getPrimitiveShort()); } + // primitiveInt if (obj.getPrimitiveInt() != 0) { output.writeInt32(27, obj.getPrimitiveInt()); } + // primitiveLong if (obj.getPrimitiveLong() != 0) { output.writeInt64(28, obj.getPrimitiveLong()); } + // primitiveFloat if (obj.getPrimitiveFloat() != 0) { output.writeFloat(29, obj.getPrimitiveFloat()); } + // primitiveDouble if (obj.getPrimitiveDouble() != 0) { output.writeDouble(30, obj.getPrimitiveDouble()); } + // primitiveChar if (obj.getPrimitiveChar() != 0) { output.writeInt32(31, obj.getPrimitiveChar()); } + // enumType if (obj.getEnumType() != null) { switch (obj.getEnumType()) { case A: diff --git a/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java b/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java index 64c23e6d3..6797552f4 100644 --- a/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java +++ b/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java @@ -8,77 +8,41 @@ @DataObject @ProtobufGen public class SimplePojo { - private Integer nullInteger; - private Integer zeroInteger; - private Boolean nullBoolean; - private Boolean zeroBoolean; - private String nullString; - private String ZeroString; - private int primitiveInteger; - private boolean primitiveBoolean; + private Integer integerField; + private Long LongField; + private Boolean booleanField; + private String stringField; - public Integer getNullInteger() { - return nullInteger; + public Integer getIntegerField() { + return integerField; } - public void setNullInteger(Integer nullInteger) { - this.nullInteger = nullInteger; + public void setIntegerField(Integer integerField) { + this.integerField = integerField; } - public Integer getZeroInteger() { - return zeroInteger; + public Long getLongField() { + return LongField; } - public void setZeroInteger(Integer zeroInteger) { - this.zeroInteger = zeroInteger; + public void setLongField(Long longField) { + LongField = longField; } - public Boolean getNullBoolean() { - return nullBoolean; + public Boolean getBooleanField() { + return booleanField; } - public void setNullBoolean(Boolean nullBoolean) { - this.nullBoolean = nullBoolean; + public void setBooleanField(Boolean booleanField) { + this.booleanField = booleanField; } - public Boolean getZeroBoolean() { - return zeroBoolean; + public String getStringField() { + return stringField; } - public void setZeroBoolean(Boolean zeroBoolean) { - this.zeroBoolean = zeroBoolean; - } - - public String getNullString() { - return nullString; - } - - public void setNullString(String nullString) { - this.nullString = nullString; - } - - public String getZeroString() { - return ZeroString; - } - - public void setZeroString(String zeroString) { - this.ZeroString = zeroString; - } - - public int getPrimitiveInteger() { - return primitiveInteger; - } - - public void setPrimitiveInteger(int primitiveInteger) { - this.primitiveInteger = primitiveInteger; - } - - public boolean isPrimitiveBoolean() { - return primitiveBoolean; - } - - public void setPrimitiveBoolean(boolean primitiveBoolean) { - this.primitiveBoolean = primitiveBoolean; + public void setStringField(String stringField) { + this.stringField = stringField; } @Override @@ -86,11 +50,11 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; SimplePojo that = (SimplePojo) o; - return primitiveInteger == that.primitiveInteger && primitiveBoolean == that.primitiveBoolean && Objects.equals(nullInteger, that.nullInteger) && Objects.equals(zeroInteger, that.zeroInteger) && Objects.equals(nullBoolean, that.nullBoolean) && Objects.equals(zeroBoolean, that.zeroBoolean) && Objects.equals(nullString, that.nullString) && Objects.equals(ZeroString, that.ZeroString); + return Objects.equals(integerField, that.integerField) && Objects.equals(LongField, that.LongField) && Objects.equals(booleanField, that.booleanField) && Objects.equals(stringField, that.stringField); } @Override public int hashCode() { - return Objects.hash(nullInteger, zeroInteger, nullBoolean, zeroBoolean, nullString, ZeroString, primitiveInteger, primitiveBoolean); + return Objects.hash(integerField, LongField, booleanField, stringField); } } diff --git a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java index 8cac595a4..cdad2ef6e 100644 --- a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java +++ b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java @@ -83,6 +83,24 @@ public String renderProto(DataObjectModel model, int index, int size, Map Date: Sat, 14 Oct 2023 15:39:28 +0800 Subject: [PATCH 04/10] add ProtobufEncodingMode enum --- .../converter/AddressProtoConverter.java | 25 +++++---- .../RecursiveItemProtoConverter.java | 37 +++++++------ .../converter/SimplePojoProtoConverter.java | 25 +++++---- .../codegen/converter/UserProtoConverter.java | 37 +++++++------ .../protobuf/ProtobufEncodingMode.java | 19 +++++++ .../generator/DataObjectProtobufGen.java | 37 +++++++------ .../codegen/protobuf/CompatibilityTest.java | 55 ++++++++++--------- 7 files changed, 135 insertions(+), 100 deletions(-) create mode 100644 vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/ProtobufEncodingMode.java diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java index ba6fd0306..60fc1f6e2 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Arrays; +import io.vertx.codegen.protobuf.ProtobufEncodingMode; import io.vertx.core.json.JsonObject; import io.vertx.codegen.protobuf.utils.ExpandableIntArray; import io.vertx.codegen.protobuf.converters.*; @@ -17,10 +18,11 @@ public class AddressProtoConverter { public static void fromProto(CodedInputStream input, Address obj) throws IOException { - fromProto(input, obj, false); + fromProto(input, obj, ProtobufEncodingMode.VERTX_NULLABLE); } - public static void fromProto(CodedInputStream input, Address obj, boolean compatibleMode) throws IOException { + public static void fromProto(CodedInputStream input, Address obj, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; if (compatibleMode) { obj.setName(""); obj.setLongitude(0f); @@ -46,16 +48,17 @@ public static void fromProto(CodedInputStream input, Address obj, boolean compat } public static void toProto(Address obj, CodedOutputStream output) throws IOException { - toProto(obj, output, false); + toProto(obj, output, ProtobufEncodingMode.VERTX_NULLABLE); } - public static void toProto(Address obj, CodedOutputStream output, boolean compatibleMode) throws IOException { + public static void toProto(Address obj, CodedOutputStream output, ProtobufEncodingMode encodingMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - AddressProtoConverter.computeSize(obj, cache, 0, compatibleMode); - AddressProtoConverter.toProto(obj, output, cache, 0, compatibleMode); + AddressProtoConverter.computeSize(obj, cache, 0, encodingMode); + AddressProtoConverter.toProto(obj, output, cache, 0, encodingMode); } - static int toProto(Address obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { + static int toProto(Address obj, CodedOutputStream output, ExpandableIntArray cache, int index, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; index = index + 1; // name if (compatibleMode && obj.getName() == null) { @@ -82,16 +85,16 @@ static int toProto(Address obj, CodedOutputStream output, ExpandableIntArray cac } public static int computeSize(Address obj) { - return computeSize(obj, false); + return computeSize(obj, ProtobufEncodingMode.VERTX_NULLABLE); } - public static int computeSize(Address obj, boolean compatibleMode) { + public static int computeSize(Address obj, ProtobufEncodingMode encodingMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - AddressProtoConverter.computeSize(obj, cache, 0, compatibleMode); + AddressProtoConverter.computeSize(obj, cache, 0, encodingMode); return cache.get(0); } - static int computeSize(Address obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { + static int computeSize(Address obj, ExpandableIntArray cache, final int baseIndex, ProtobufEncodingMode encodingMode) { int size = 0; int index = baseIndex + 1; if (obj.getName() != null) { diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java index 389ec41fd..eb9eaf51f 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Arrays; +import io.vertx.codegen.protobuf.ProtobufEncodingMode; import io.vertx.core.json.JsonObject; import io.vertx.codegen.protobuf.utils.ExpandableIntArray; import io.vertx.codegen.protobuf.converters.*; @@ -17,10 +18,11 @@ public class RecursiveItemProtoConverter { public static void fromProto(CodedInputStream input, RecursiveItem obj) throws IOException { - fromProto(input, obj, false); + fromProto(input, obj, ProtobufEncodingMode.VERTX_NULLABLE); } - public static void fromProto(CodedInputStream input, RecursiveItem obj, boolean compatibleMode) throws IOException { + public static void fromProto(CodedInputStream input, RecursiveItem obj, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; if (compatibleMode) { obj.setId(""); } @@ -63,16 +65,17 @@ public static void fromProto(CodedInputStream input, RecursiveItem obj, boolean } public static void toProto(RecursiveItem obj, CodedOutputStream output) throws IOException { - toProto(obj, output, false); + toProto(obj, output, ProtobufEncodingMode.VERTX_NULLABLE); } - public static void toProto(RecursiveItem obj, CodedOutputStream output, boolean compatibleMode) throws IOException { + public static void toProto(RecursiveItem obj, CodedOutputStream output, ProtobufEncodingMode encodingMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - RecursiveItemProtoConverter.computeSize(obj, cache, 0, compatibleMode); - RecursiveItemProtoConverter.toProto(obj, output, cache, 0, compatibleMode); + RecursiveItemProtoConverter.computeSize(obj, cache, 0, encodingMode); + RecursiveItemProtoConverter.toProto(obj, output, cache, 0, encodingMode); } - static int toProto(RecursiveItem obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { + static int toProto(RecursiveItem obj, CodedOutputStream output, ExpandableIntArray cache, int index, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; index = index + 1; // id if (compatibleMode && obj.getId() == null) { @@ -85,34 +88,34 @@ static int toProto(RecursiveItem obj, CodedOutputStream output, ExpandableIntArr if (obj.getChildA() != null) { output.writeUInt32NoTag(18); output.writeUInt32NoTag(cache.get(index)); - index = RecursiveItemProtoConverter.toProto(obj.getChildA(), output, cache, index, compatibleMode); + index = RecursiveItemProtoConverter.toProto(obj.getChildA(), output, cache, index, encodingMode); } // childB if (obj.getChildB() != null) { output.writeUInt32NoTag(26); output.writeUInt32NoTag(cache.get(index)); - index = RecursiveItemProtoConverter.toProto(obj.getChildB(), output, cache, index, compatibleMode); + index = RecursiveItemProtoConverter.toProto(obj.getChildB(), output, cache, index, encodingMode); } // childC if (obj.getChildC() != null) { output.writeUInt32NoTag(34); output.writeUInt32NoTag(cache.get(index)); - index = RecursiveItemProtoConverter.toProto(obj.getChildC(), output, cache, index, compatibleMode); + index = RecursiveItemProtoConverter.toProto(obj.getChildC(), output, cache, index, encodingMode); } return index; } public static int computeSize(RecursiveItem obj) { - return computeSize(obj, false); + return computeSize(obj, ProtobufEncodingMode.VERTX_NULLABLE); } - public static int computeSize(RecursiveItem obj, boolean compatibleMode) { + public static int computeSize(RecursiveItem obj, ProtobufEncodingMode encodingMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - RecursiveItemProtoConverter.computeSize(obj, cache, 0, compatibleMode); + RecursiveItemProtoConverter.computeSize(obj, cache, 0, encodingMode); return cache.get(0); } - static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { + static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final int baseIndex, ProtobufEncodingMode encodingMode) { int size = 0; int index = baseIndex + 1; if (obj.getId() != null) { @@ -121,7 +124,7 @@ static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final int ba if (obj.getChildA() != null) { size += CodedOutputStream.computeUInt32SizeNoTag(18); int savedIndex = index; - index = RecursiveItemProtoConverter.computeSize(obj.getChildA(), cache, index, compatibleMode); + index = RecursiveItemProtoConverter.computeSize(obj.getChildA(), cache, index, encodingMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; @@ -129,7 +132,7 @@ static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final int ba if (obj.getChildB() != null) { size += CodedOutputStream.computeUInt32SizeNoTag(26); int savedIndex = index; - index = RecursiveItemProtoConverter.computeSize(obj.getChildB(), cache, index, compatibleMode); + index = RecursiveItemProtoConverter.computeSize(obj.getChildB(), cache, index, encodingMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; @@ -137,7 +140,7 @@ static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final int ba if (obj.getChildC() != null) { size += CodedOutputStream.computeUInt32SizeNoTag(34); int savedIndex = index; - index = RecursiveItemProtoConverter.computeSize(obj.getChildC(), cache, index, compatibleMode); + index = RecursiveItemProtoConverter.computeSize(obj.getChildC(), cache, index, encodingMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java index 3bd3e353e..bea7a12f3 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Arrays; +import io.vertx.codegen.protobuf.ProtobufEncodingMode; import io.vertx.core.json.JsonObject; import io.vertx.codegen.protobuf.utils.ExpandableIntArray; import io.vertx.codegen.protobuf.converters.*; @@ -17,10 +18,11 @@ public class SimplePojoProtoConverter { public static void fromProto(CodedInputStream input, SimplePojo obj) throws IOException { - fromProto(input, obj, false); + fromProto(input, obj, ProtobufEncodingMode.VERTX_NULLABLE); } - public static void fromProto(CodedInputStream input, SimplePojo obj, boolean compatibleMode) throws IOException { + public static void fromProto(CodedInputStream input, SimplePojo obj, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; if (compatibleMode) { obj.setIntegerField(0); obj.setLongField(0L); @@ -51,16 +53,17 @@ public static void fromProto(CodedInputStream input, SimplePojo obj, boolean com } public static void toProto(SimplePojo obj, CodedOutputStream output) throws IOException { - toProto(obj, output, false); + toProto(obj, output, ProtobufEncodingMode.VERTX_NULLABLE); } - public static void toProto(SimplePojo obj, CodedOutputStream output, boolean compatibleMode) throws IOException { + public static void toProto(SimplePojo obj, CodedOutputStream output, ProtobufEncodingMode encodingMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - SimplePojoProtoConverter.computeSize(obj, cache, 0, compatibleMode); - SimplePojoProtoConverter.toProto(obj, output, cache, 0, compatibleMode); + SimplePojoProtoConverter.computeSize(obj, cache, 0, encodingMode); + SimplePojoProtoConverter.toProto(obj, output, cache, 0, encodingMode); } - static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { + static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIntArray cache, int index, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; index = index + 1; // integerField if (compatibleMode && obj.getIntegerField() == null) { @@ -94,16 +97,16 @@ static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIntArray } public static int computeSize(SimplePojo obj) { - return computeSize(obj, false); + return computeSize(obj, ProtobufEncodingMode.VERTX_NULLABLE); } - public static int computeSize(SimplePojo obj, boolean compatibleMode) { + public static int computeSize(SimplePojo obj, ProtobufEncodingMode encodingMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - SimplePojoProtoConverter.computeSize(obj, cache, 0, compatibleMode); + SimplePojoProtoConverter.computeSize(obj, cache, 0, encodingMode); return cache.get(0); } - static int computeSize(SimplePojo obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { + static int computeSize(SimplePojo obj, ExpandableIntArray cache, final int baseIndex, ProtobufEncodingMode encodingMode) { int size = 0; int index = baseIndex + 1; if (obj.getIntegerField() != null) { diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java index 502f19cea..d715ae87a 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Arrays; +import io.vertx.codegen.protobuf.ProtobufEncodingMode; import io.vertx.core.json.JsonObject; import io.vertx.codegen.protobuf.utils.ExpandableIntArray; import io.vertx.codegen.protobuf.converters.*; @@ -17,10 +18,11 @@ public class UserProtoConverter { public static void fromProto(CodedInputStream input, User obj) throws IOException { - fromProto(input, obj, false); + fromProto(input, obj, ProtobufEncodingMode.VERTX_NULLABLE); } - public static void fromProto(CodedInputStream input, User obj, boolean compatibleMode) throws IOException { + public static void fromProto(CodedInputStream input, User obj, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; if (compatibleMode) { obj.setUserName(""); obj.setAge(0); @@ -288,16 +290,17 @@ public static void fromProto(CodedInputStream input, User obj, boolean compatibl } public static void toProto(User obj, CodedOutputStream output) throws IOException { - toProto(obj, output, false); + toProto(obj, output, ProtobufEncodingMode.VERTX_NULLABLE); } - public static void toProto(User obj, CodedOutputStream output, boolean compatibleMode) throws IOException { + public static void toProto(User obj, CodedOutputStream output, ProtobufEncodingMode encodingMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - UserProtoConverter.computeSize(obj, cache, 0, compatibleMode); - UserProtoConverter.toProto(obj, output, cache, 0, compatibleMode); + UserProtoConverter.computeSize(obj, cache, 0, encodingMode); + UserProtoConverter.toProto(obj, output, cache, 0, encodingMode); } - static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { + static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, int index, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; index = index + 1; // userName if (compatibleMode && obj.getUserName() == null) { @@ -335,7 +338,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, for (Address element: obj.getStructListField()) { output.writeUInt32NoTag(34); output.writeUInt32NoTag(cache.get(index)); - index = AddressProtoConverter.toProto(element, output, cache, index, compatibleMode); + index = AddressProtoConverter.toProto(element, output, cache, index, encodingMode); } } // zonedDateTimeListField @@ -362,7 +365,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, if (obj.getAddress() != null) { output.writeUInt32NoTag(58); output.writeUInt32NoTag(cache.get(index)); - index = AddressProtoConverter.toProto(obj.getAddress(), output, cache, index, compatibleMode); + index = AddressProtoConverter.toProto(obj.getAddress(), output, cache, index, encodingMode); } // byteField if (obj.getByteField() != null) { @@ -460,7 +463,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, output.writeString(1, entry.getKey()); output.writeUInt32NoTag(18); output.writeUInt32NoTag(elementSize); - index = AddressProtoConverter.toProto(entry.getValue(), output, cache, index, compatibleMode); + index = AddressProtoConverter.toProto(entry.getValue(), output, cache, index, encodingMode); } } // jsonValueMap @@ -581,16 +584,16 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, } public static int computeSize(User obj) { - return computeSize(obj, false); + return computeSize(obj, ProtobufEncodingMode.VERTX_NULLABLE); } - public static int computeSize(User obj, boolean compatibleMode) { + public static int computeSize(User obj, ProtobufEncodingMode encodingMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - UserProtoConverter.computeSize(obj, cache, 0, compatibleMode); + UserProtoConverter.computeSize(obj, cache, 0, encodingMode); return cache.get(0); } - static int computeSize(User obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { + static int computeSize(User obj, ExpandableIntArray cache, final int baseIndex, ProtobufEncodingMode encodingMode) { int size = 0; int index = baseIndex + 1; if (obj.getUserName() != null) { @@ -618,7 +621,7 @@ static int computeSize(User obj, ExpandableIntArray cache, final int baseIndex, for (Address element: obj.getStructListField()) { size += CodedOutputStream.computeUInt32SizeNoTag(34); int savedIndex = index; - index = AddressProtoConverter.computeSize(element, cache, index, compatibleMode); + index = AddressProtoConverter.computeSize(element, cache, index, encodingMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; @@ -652,7 +655,7 @@ static int computeSize(User obj, ExpandableIntArray cache, final int baseIndex, if (obj.getAddress() != null) { size += CodedOutputStream.computeUInt32SizeNoTag(58); int savedIndex = index; - index = AddressProtoConverter.computeSize(obj.getAddress(), cache, index, compatibleMode); + index = AddressProtoConverter.computeSize(obj.getAddress(), cache, index, encodingMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; @@ -713,7 +716,7 @@ static int computeSize(User obj, ExpandableIntArray cache, final int baseIndex, dataSize += CodedOutputStream.computeStringSize(1, entry.getKey()); // value int savedIndex = index; - index = AddressProtoConverter.computeSize(entry.getValue(), cache, index, compatibleMode); + index = AddressProtoConverter.computeSize(entry.getValue(), cache, index, encodingMode); int elementSize = cache.get(savedIndex); dataSize += CodedOutputStream.computeInt32SizeNoTag(18); dataSize += CodedOutputStream.computeInt32SizeNoTag(elementSize); diff --git a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/ProtobufEncodingMode.java b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/ProtobufEncodingMode.java new file mode 100644 index 000000000..a35b9284c --- /dev/null +++ b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/ProtobufEncodingMode.java @@ -0,0 +1,19 @@ +package io.vertx.codegen.protobuf; + +/** + * Enumeration representing different encoding modes for Protocol Buffers encoding. + */ +public enum ProtobufEncodingMode { + /** + * In this encoding mode, the converter uses a non-standard protobuf encoding to allow boxed types + * (e.g., Integer, Double) and String to be nullable. This encoding mode is intended for use when + * communicating with another Vert.x converter that supports nullable values. + */ + VERTX_NULLABLE, + + /** + * In this encoding mode, the converter uses the standard protobuf encoding, which is compatible with + * Google's protobuf decoder. Null values are not allowed for boxed types and String in this mode. + */ + GOOGLE_COMPATIBLE, +} diff --git a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java index cdad2ef6e..eb9d760c2 100644 --- a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java +++ b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java @@ -66,6 +66,7 @@ public String renderProto(DataObjectModel model, int index, int size, Map Date: Sun, 1 Oct 2023 14:35:18 +0800 Subject: [PATCH 05/10] Add SimplePojo and compatibility unit tests --- .../converters/generated/dataobjects.proto | 11 ++ .../converter/SimplePojoProtoConverter.java | 131 ++++++++++++++++ .../test/codegen/converter/SimplePojo.java | 96 ++++++++++++ .../codegen/protobuf/CompatibilityTest.java | 140 ++++++++++++++++++ 4 files changed, 378 insertions(+) create mode 100644 vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java create mode 100644 vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java create mode 100644 vertx-codegen-protobuf/src/test/java/io/vertx/test/codegen/protobuf/CompatibilityTest.java diff --git a/vertx-codegen-protobuf/src/converters/generated/dataobjects.proto b/vertx-codegen-protobuf/src/converters/generated/dataobjects.proto index b210ad988..e36634328 100644 --- a/vertx-codegen-protobuf/src/converters/generated/dataobjects.proto +++ b/vertx-codegen-protobuf/src/converters/generated/dataobjects.proto @@ -43,6 +43,17 @@ message RecursiveItem { RecursiveItem childC = 4; } +message SimplePojo { + int32 nullInteger = 1; + int32 zeroInteger = 2; + bool nullBoolean = 3; + bool zeroBoolean = 4; + string nullString = 5; + string zeroString = 6; + int32 primitiveInteger = 7; + bool primitiveBoolean = 8; +} + message User { string userName = 1; int32 age = 2; diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java new file mode 100644 index 000000000..758678801 --- /dev/null +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java @@ -0,0 +1,131 @@ +package io.vertx.test.codegen.converter; + +import com.google.protobuf.CodedOutputStream; +import com.google.protobuf.CodedInputStream; +import java.io.IOException; +import java.time.Instant; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.HashMap; +import java.util.Map; +import java.util.Arrays; +import io.vertx.core.json.JsonObject; +import io.vertx.codegen.protobuf.utils.ExpandableIntArray; +import io.vertx.codegen.protobuf.converters.*; + +public class SimplePojoProtoConverter { + + public static void fromProto(CodedInputStream input, SimplePojo obj) throws IOException { + int tag; + while ((tag = input.readTag()) != 0) { + switch (tag) { + case 8: { + obj.setNullInteger(input.readInt32()); + break; + } + case 16: { + obj.setZeroInteger(input.readInt32()); + break; + } + case 24: { + obj.setNullBoolean(input.readBool()); + break; + } + case 32: { + obj.setZeroBoolean(input.readBool()); + break; + } + case 42: { + obj.setNullString(input.readString()); + break; + } + case 50: { + obj.setZeroString(input.readString()); + break; + } + case 56: { + obj.setPrimitiveInteger(input.readInt32()); + break; + } + case 64: { + obj.setPrimitiveBoolean(input.readBool()); + break; + } + } + } + } + + public static void toProto(SimplePojo obj, CodedOutputStream output) throws IOException { + ExpandableIntArray cache = new ExpandableIntArray(16); + SimplePojoProtoConverter.computeSize(obj, cache, 0); + SimplePojoProtoConverter.toProto(obj, output, cache, 0); + } + + public static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIntArray cache, int index) throws IOException { + index = index + 1; + if (obj.getNullInteger() != null) { + output.writeInt32(1, obj.getNullInteger()); + } + if (obj.getZeroInteger() != null) { + output.writeInt32(2, obj.getZeroInteger()); + } + if (obj.getNullBoolean() != null) { + output.writeBool(3, obj.getNullBoolean()); + } + if (obj.getZeroBoolean() != null) { + output.writeBool(4, obj.getZeroBoolean()); + } + if (obj.getNullString() != null) { + output.writeString(5, obj.getNullString()); + } + if (obj.getZeroString() != null) { + output.writeString(6, obj.getZeroString()); + } + if (obj.getPrimitiveInteger() != 0) { + output.writeInt32(7, obj.getPrimitiveInteger()); + } + if (obj.isPrimitiveBoolean()) { + output.writeBool(8, obj.isPrimitiveBoolean()); + } + return index; + } + + public static int computeSize(SimplePojo obj) { + ExpandableIntArray cache = new ExpandableIntArray(16); + SimplePojoProtoConverter.computeSize(obj, cache, 0); + return cache.get(0); + } + + public static int computeSize(SimplePojo obj, ExpandableIntArray cache, final int baseIndex) { + int size = 0; + int index = baseIndex + 1; + if (obj.getNullInteger() != null) { + size += CodedOutputStream.computeInt32Size(1, obj.getNullInteger()); + } + if (obj.getZeroInteger() != null) { + size += CodedOutputStream.computeInt32Size(2, obj.getZeroInteger()); + } + if (obj.getNullBoolean() != null) { + size += CodedOutputStream.computeBoolSize(3, obj.getNullBoolean()); + } + if (obj.getZeroBoolean() != null) { + size += CodedOutputStream.computeBoolSize(4, obj.getZeroBoolean()); + } + if (obj.getNullString() != null) { + size += CodedOutputStream.computeStringSize(5, obj.getNullString()); + } + if (obj.getZeroString() != null) { + size += CodedOutputStream.computeStringSize(6, obj.getZeroString()); + } + if (obj.getPrimitiveInteger() != 0) { + size += CodedOutputStream.computeInt32Size(7, obj.getPrimitiveInteger()); + } + if (obj.isPrimitiveBoolean()) { + size += CodedOutputStream.computeBoolSize(8, obj.isPrimitiveBoolean()); + } + cache.set(baseIndex, size); + return index; + } + +} diff --git a/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java b/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java new file mode 100644 index 000000000..64c23e6d3 --- /dev/null +++ b/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java @@ -0,0 +1,96 @@ +package io.vertx.test.codegen.converter; + +import io.vertx.codegen.annotations.DataObject; +import io.vertx.codegen.protobuf.annotations.ProtobufGen; + +import java.util.Objects; + +@DataObject +@ProtobufGen +public class SimplePojo { + private Integer nullInteger; + private Integer zeroInteger; + private Boolean nullBoolean; + private Boolean zeroBoolean; + private String nullString; + private String ZeroString; + private int primitiveInteger; + private boolean primitiveBoolean; + + public Integer getNullInteger() { + return nullInteger; + } + + public void setNullInteger(Integer nullInteger) { + this.nullInteger = nullInteger; + } + + public Integer getZeroInteger() { + return zeroInteger; + } + + public void setZeroInteger(Integer zeroInteger) { + this.zeroInteger = zeroInteger; + } + + public Boolean getNullBoolean() { + return nullBoolean; + } + + public void setNullBoolean(Boolean nullBoolean) { + this.nullBoolean = nullBoolean; + } + + public Boolean getZeroBoolean() { + return zeroBoolean; + } + + public void setZeroBoolean(Boolean zeroBoolean) { + this.zeroBoolean = zeroBoolean; + } + + public String getNullString() { + return nullString; + } + + public void setNullString(String nullString) { + this.nullString = nullString; + } + + public String getZeroString() { + return ZeroString; + } + + public void setZeroString(String zeroString) { + this.ZeroString = zeroString; + } + + public int getPrimitiveInteger() { + return primitiveInteger; + } + + public void setPrimitiveInteger(int primitiveInteger) { + this.primitiveInteger = primitiveInteger; + } + + public boolean isPrimitiveBoolean() { + return primitiveBoolean; + } + + public void setPrimitiveBoolean(boolean primitiveBoolean) { + this.primitiveBoolean = primitiveBoolean; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SimplePojo that = (SimplePojo) o; + return primitiveInteger == that.primitiveInteger && primitiveBoolean == that.primitiveBoolean && Objects.equals(nullInteger, that.nullInteger) && Objects.equals(zeroInteger, that.zeroInteger) && Objects.equals(nullBoolean, that.nullBoolean) && Objects.equals(zeroBoolean, that.zeroBoolean) && Objects.equals(nullString, that.nullString) && Objects.equals(ZeroString, that.ZeroString); + } + + @Override + public int hashCode() { + return Objects.hash(nullInteger, zeroInteger, nullBoolean, zeroBoolean, nullString, ZeroString, primitiveInteger, primitiveBoolean); + } +} diff --git a/vertx-codegen-protobuf/src/test/java/io/vertx/test/codegen/protobuf/CompatibilityTest.java b/vertx-codegen-protobuf/src/test/java/io/vertx/test/codegen/protobuf/CompatibilityTest.java new file mode 100644 index 000000000..4d0aa4b2f --- /dev/null +++ b/vertx-codegen-protobuf/src/test/java/io/vertx/test/codegen/protobuf/CompatibilityTest.java @@ -0,0 +1,140 @@ +package io.vertx.test.codegen.protobuf; + +import com.google.protobuf.CodedInputStream; +import com.google.protobuf.CodedOutputStream; +import com.google.protobuf.InvalidProtocolBufferException; +import io.vertx.test.codegen.converter.SimplePojo; +import io.vertx.test.codegen.converter.SimplePojoProtoConverter; +import org.junit.Assert; +import org.junit.Test; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + + +public class CompatibilityTest { + @Test + public void testVertxConverter() throws IOException { + // Populate a POJO + SimplePojo pojo = new SimplePojo(); + pojo.setNullInteger(null); + pojo.setNullBoolean(null); + pojo.setNullString(null); + pojo.setZeroInteger(0); + pojo.setZeroBoolean(false); + pojo.setZeroString(""); + pojo.setPrimitiveInteger(0); + pojo.setPrimitiveBoolean(false); + + // Vertx Encode + byte[] encoded = vertxEncode(pojo); + + // Vertx Decode + SimplePojo decoded = vertxDecode(encoded); + + // Decoded is exactly the same with original pojo + Assert.assertEquals(pojo, decoded); + + Assert.assertEquals(null, decoded.getNullInteger()); + Assert.assertEquals(null, decoded.getNullBoolean()); + Assert.assertEquals(null, decoded.getNullString()); + Assert.assertEquals((Integer) 0, decoded.getZeroInteger()); + Assert.assertEquals(false, decoded.getZeroBoolean()); + Assert.assertEquals("", decoded.getZeroString()); + Assert.assertEquals(0, decoded.getPrimitiveInteger()); + Assert.assertEquals(false, decoded.isPrimitiveBoolean()); + + // Assert total size is equal to computed size + Assert.assertEquals(encoded.length, SimplePojoProtoConverter.computeSize(pojo)); + } + + @Test + public void testProtocDecode() throws IOException { + // Populate a POJO + SimplePojo pojo = new SimplePojo(); + pojo.setNullInteger(null); + pojo.setNullBoolean(null); + pojo.setNullString(null); + pojo.setZeroInteger(0); + pojo.setZeroBoolean(false); + pojo.setZeroString(""); + pojo.setPrimitiveInteger(0); + pojo.setPrimitiveBoolean(false); + + // Vertx Encode + byte[] encoded = vertxEncode(pojo); + + // Protoc Decode + io.vertx.protobuf.generated.SimplePojo decoded = protocDecode(encoded); + + Assert.assertEquals(0, decoded.getNullInteger()); // Integer in Google Protoc is not nullable + Assert.assertEquals(false, decoded.getNullBoolean()); // Boolean in Google Protoc is not nullable + Assert.assertEquals("", decoded.getNullString()); // String in Google Protoc is not nullable + Assert.assertEquals(0, decoded.getZeroInteger()); + Assert.assertEquals(false, decoded.getZeroBoolean()); + Assert.assertEquals("", decoded.getZeroString()); + Assert.assertEquals(0, decoded.getPrimitiveInteger()); + Assert.assertEquals(false, decoded.getPrimitiveBoolean()); + } + + @Test + public void testProtocEncode() throws IOException { + // Populate a Protoc generated POJO + io.vertx.protobuf.generated.SimplePojo pojo = io.vertx.protobuf.generated.SimplePojo.newBuilder() + .setNullInteger(0) // cannot set null integer, won't compile + .setNullBoolean(false) // cannot set null boolean, won't compile + .setNullString("") // cannot set null string, will throw NPE + .setZeroInteger(0) + .setZeroBoolean(false) + .setZeroString("") + .setPrimitiveInteger(0) + .setPrimitiveBoolean(false) + .build(); + + // Protoc Encode + byte[] encoded = protocEncode(pojo); + + // Vertx Decode + SimplePojo decoded = vertxDecode(encoded); + + Assert.assertEquals(null, decoded.getNullInteger()); + Assert.assertEquals(null, decoded.getNullBoolean()); + Assert.assertEquals(null, decoded.getNullString()); + Assert.assertEquals(null, decoded.getZeroInteger()); + Assert.assertEquals(null, decoded.getZeroBoolean()); + Assert.assertEquals(null, decoded.getZeroString()); + Assert.assertEquals(0, decoded.getPrimitiveInteger()); + Assert.assertEquals(false, decoded.isPrimitiveBoolean()); + } + + private byte[] vertxEncode(SimplePojo obj) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + CodedOutputStream output = CodedOutputStream.newInstance(baos); + SimplePojoProtoConverter.toProto(obj, output); + output.flush(); + byte[] encoded = baos.toByteArray(); + TestUtils.debug("Vertx encoded", encoded); + return encoded; + } + + private byte[] protocEncode(io.vertx.protobuf.generated.SimplePojo obj) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + CodedOutputStream output = CodedOutputStream.newInstance(baos); + obj.writeTo(output); + output.flush(); + byte[] encoded = baos.toByteArray(); + TestUtils.debug("Protoc encoded", encoded); + return encoded; + } + + private io.vertx.protobuf.generated.SimplePojo protocDecode(byte[] arr) throws InvalidProtocolBufferException { + return io.vertx.protobuf.generated.SimplePojo.parseFrom(arr); + } + + private SimplePojo vertxDecode(byte[] arr) throws IOException { + CodedInputStream input = CodedInputStream.newInstance(arr); + SimplePojo obj = new SimplePojo(); + SimplePojoProtoConverter.fromProto(input, obj); + return obj; + } +} From 7f7bf6779065459ba5813519273ec40c15f785ad Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sun, 8 Oct 2023 11:51:21 +0800 Subject: [PATCH 06/10] Add compatibleMode flag --- .../converter/AddressProtoConverter.java | 33 ++++++-- .../RecursiveItemProtoConverter.java | 39 ++++++--- .../converter/SimplePojoProtoConverter.java | 42 ++++++++-- .../codegen/converter/UserProtoConverter.java | 57 ++++++++++--- .../generator/DataObjectProtobufGen.java | 80 ++++++++++++++++--- .../codegen/protobuf/CompatibilityTest.java | 20 ++--- 6 files changed, 217 insertions(+), 54 deletions(-) diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java index 863756ed3..6c3958307 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java @@ -17,6 +17,10 @@ public class AddressProtoConverter { public static void fromProto(CodedInputStream input, Address obj) throws IOException { + fromProto(input, obj, false); + } + + public static void fromProto(CodedInputStream input, Address obj, boolean compatibleMode) throws IOException { int tag; while ((tag = input.readTag()) != 0) { switch (tag) { @@ -34,15 +38,30 @@ public static void fromProto(CodedInputStream input, Address obj) throws IOExcep } } } + if (compatibleMode) { + if (obj.getName() == null) { + obj.setName(""); + } + if (obj.getLongitude() == null) { + obj.setLongitude(0f); + } + if (obj.getLatitude() == null) { + obj.setLatitude(0f); + } + } } public static void toProto(Address obj, CodedOutputStream output) throws IOException { + toProto(obj, output, false); + } + + public static void toProto(Address obj, CodedOutputStream output, boolean compatibleMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - AddressProtoConverter.computeSize(obj, cache, 0); - AddressProtoConverter.toProto(obj, output, cache, 0); + AddressProtoConverter.computeSize(obj, cache, 0, compatibleMode); + AddressProtoConverter.toProto(obj, output, cache, 0, compatibleMode); } - public static int toProto(Address obj, CodedOutputStream output, ExpandableIntArray cache, int index) throws IOException { + static int toProto(Address obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { index = index + 1; if (obj.getName() != null) { output.writeString(1, obj.getName()); @@ -57,12 +76,16 @@ public static int toProto(Address obj, CodedOutputStream output, ExpandableIntAr } public static int computeSize(Address obj) { + return computeSize(obj, false); + } + + public static int computeSize(Address obj, boolean compatibleMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - AddressProtoConverter.computeSize(obj, cache, 0); + AddressProtoConverter.computeSize(obj, cache, 0, compatibleMode); return cache.get(0); } - public static int computeSize(Address obj, ExpandableIntArray cache, final int baseIndex) { + static int computeSize(Address obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { int size = 0; int index = baseIndex + 1; if (obj.getName() != null) { diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java index 659e4273d..4c991d54f 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java @@ -17,6 +17,10 @@ public class RecursiveItemProtoConverter { public static void fromProto(CodedInputStream input, RecursiveItem obj) throws IOException { + fromProto(input, obj, false); + } + + public static void fromProto(CodedInputStream input, RecursiveItem obj, boolean compatibleMode) throws IOException { int tag; while ((tag = input.readTag()) != 0) { switch (tag) { @@ -53,15 +57,24 @@ public static void fromProto(CodedInputStream input, RecursiveItem obj) throws I } } } + if (compatibleMode) { + if (obj.getId() == null) { + obj.setId(""); + } + } } public static void toProto(RecursiveItem obj, CodedOutputStream output) throws IOException { + toProto(obj, output, false); + } + + public static void toProto(RecursiveItem obj, CodedOutputStream output, boolean compatibleMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - RecursiveItemProtoConverter.computeSize(obj, cache, 0); - RecursiveItemProtoConverter.toProto(obj, output, cache, 0); + RecursiveItemProtoConverter.computeSize(obj, cache, 0, compatibleMode); + RecursiveItemProtoConverter.toProto(obj, output, cache, 0, compatibleMode); } - public static int toProto(RecursiveItem obj, CodedOutputStream output, ExpandableIntArray cache, int index) throws IOException { + static int toProto(RecursiveItem obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { index = index + 1; if (obj.getId() != null) { output.writeString(1, obj.getId()); @@ -69,28 +82,32 @@ public static int toProto(RecursiveItem obj, CodedOutputStream output, Expandabl if (obj.getChildA() != null) { output.writeUInt32NoTag(18); output.writeUInt32NoTag(cache.get(index)); - index = RecursiveItemProtoConverter.toProto(obj.getChildA(), output, cache, index); + index = RecursiveItemProtoConverter.toProto(obj.getChildA(), output, cache, index, compatibleMode); } if (obj.getChildB() != null) { output.writeUInt32NoTag(26); output.writeUInt32NoTag(cache.get(index)); - index = RecursiveItemProtoConverter.toProto(obj.getChildB(), output, cache, index); + index = RecursiveItemProtoConverter.toProto(obj.getChildB(), output, cache, index, compatibleMode); } if (obj.getChildC() != null) { output.writeUInt32NoTag(34); output.writeUInt32NoTag(cache.get(index)); - index = RecursiveItemProtoConverter.toProto(obj.getChildC(), output, cache, index); + index = RecursiveItemProtoConverter.toProto(obj.getChildC(), output, cache, index, compatibleMode); } return index; } public static int computeSize(RecursiveItem obj) { + return computeSize(obj, false); + } + + public static int computeSize(RecursiveItem obj, boolean compatibleMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - RecursiveItemProtoConverter.computeSize(obj, cache, 0); + RecursiveItemProtoConverter.computeSize(obj, cache, 0, compatibleMode); return cache.get(0); } - public static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final int baseIndex) { + static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { int size = 0; int index = baseIndex + 1; if (obj.getId() != null) { @@ -99,7 +116,7 @@ public static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final if (obj.getChildA() != null) { size += CodedOutputStream.computeUInt32SizeNoTag(18); int savedIndex = index; - index = RecursiveItemProtoConverter.computeSize(obj.getChildA(), cache, index); + index = RecursiveItemProtoConverter.computeSize(obj.getChildA(), cache, index, compatibleMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; @@ -107,7 +124,7 @@ public static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final if (obj.getChildB() != null) { size += CodedOutputStream.computeUInt32SizeNoTag(26); int savedIndex = index; - index = RecursiveItemProtoConverter.computeSize(obj.getChildB(), cache, index); + index = RecursiveItemProtoConverter.computeSize(obj.getChildB(), cache, index, compatibleMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; @@ -115,7 +132,7 @@ public static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final if (obj.getChildC() != null) { size += CodedOutputStream.computeUInt32SizeNoTag(34); int savedIndex = index; - index = RecursiveItemProtoConverter.computeSize(obj.getChildC(), cache, index); + index = RecursiveItemProtoConverter.computeSize(obj.getChildC(), cache, index, compatibleMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java index 758678801..9691f8fa6 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java @@ -17,6 +17,10 @@ public class SimplePojoProtoConverter { public static void fromProto(CodedInputStream input, SimplePojo obj) throws IOException { + fromProto(input, obj, false); + } + + public static void fromProto(CodedInputStream input, SimplePojo obj, boolean compatibleMode) throws IOException { int tag; while ((tag = input.readTag()) != 0) { switch (tag) { @@ -54,15 +58,39 @@ public static void fromProto(CodedInputStream input, SimplePojo obj) throws IOEx } } } + if (compatibleMode) { + if (obj.getNullInteger() == null) { + obj.setNullInteger(0); + } + if (obj.getZeroInteger() == null) { + obj.setZeroInteger(0); + } + if (obj.getNullBoolean() == null) { + obj.setNullBoolean(false); + } + if (obj.getZeroBoolean() == null) { + obj.setZeroBoolean(false); + } + if (obj.getNullString() == null) { + obj.setNullString(""); + } + if (obj.getZeroString() == null) { + obj.setZeroString(""); + } + } } public static void toProto(SimplePojo obj, CodedOutputStream output) throws IOException { + toProto(obj, output, false); + } + + public static void toProto(SimplePojo obj, CodedOutputStream output, boolean compatibleMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - SimplePojoProtoConverter.computeSize(obj, cache, 0); - SimplePojoProtoConverter.toProto(obj, output, cache, 0); + SimplePojoProtoConverter.computeSize(obj, cache, 0, compatibleMode); + SimplePojoProtoConverter.toProto(obj, output, cache, 0, compatibleMode); } - public static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIntArray cache, int index) throws IOException { + static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { index = index + 1; if (obj.getNullInteger() != null) { output.writeInt32(1, obj.getNullInteger()); @@ -92,12 +120,16 @@ public static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIn } public static int computeSize(SimplePojo obj) { + return computeSize(obj, false); + } + + public static int computeSize(SimplePojo obj, boolean compatibleMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - SimplePojoProtoConverter.computeSize(obj, cache, 0); + SimplePojoProtoConverter.computeSize(obj, cache, 0, compatibleMode); return cache.get(0); } - public static int computeSize(SimplePojo obj, ExpandableIntArray cache, final int baseIndex) { + static int computeSize(SimplePojo obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { int size = 0; int index = baseIndex + 1; if (obj.getNullInteger() != null) { diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java index c1dd876e7..26222b5ab 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java @@ -17,6 +17,10 @@ public class UserProtoConverter { public static void fromProto(CodedInputStream input, User obj) throws IOException { + fromProto(input, obj, false); + } + + public static void fromProto(CodedInputStream input, User obj, boolean compatibleMode) throws IOException { int tag; while ((tag = input.readTag()) != 0) { switch (tag) { @@ -272,15 +276,42 @@ public static void fromProto(CodedInputStream input, User obj) throws IOExceptio } } } + if (compatibleMode) { + if (obj.getUserName() == null) { + obj.setUserName(""); + } + if (obj.getAge() == null) { + obj.setAge(0); + } + if (obj.getDoubleField() == null) { + obj.setDoubleField(0d); + } + if (obj.getFloatField() == null) { + obj.setFloatField(0f); + } + if (obj.getLongField() == null) { + obj.setLongField(0L); + } + if (obj.getBoolField() == null) { + obj.setBoolField(false); + } + if (obj.getShortField() == null) { + obj.setShortField((short)0); + } + } } public static void toProto(User obj, CodedOutputStream output) throws IOException { + toProto(obj, output, false); + } + + public static void toProto(User obj, CodedOutputStream output, boolean compatibleMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - UserProtoConverter.computeSize(obj, cache, 0); - UserProtoConverter.toProto(obj, output, cache, 0); + UserProtoConverter.computeSize(obj, cache, 0, compatibleMode); + UserProtoConverter.toProto(obj, output, cache, 0, compatibleMode); } - public static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, int index) throws IOException { + static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { index = index + 1; if (obj.getUserName() != null) { output.writeString(1, obj.getUserName()); @@ -308,7 +339,7 @@ public static int toProto(User obj, CodedOutputStream output, ExpandableIntArray for (Address element: obj.getStructListField()) { output.writeUInt32NoTag(34); output.writeUInt32NoTag(cache.get(index)); - index = AddressProtoConverter.toProto(element, output, cache, index); + index = AddressProtoConverter.toProto(element, output, cache, index, compatibleMode); } } if (obj.getZonedDateTimeListField() != null) { @@ -332,7 +363,7 @@ public static int toProto(User obj, CodedOutputStream output, ExpandableIntArray if (obj.getAddress() != null) { output.writeUInt32NoTag(58); output.writeUInt32NoTag(cache.get(index)); - index = AddressProtoConverter.toProto(obj.getAddress(), output, cache, index); + index = AddressProtoConverter.toProto(obj.getAddress(), output, cache, index, compatibleMode); } if (obj.getByteField() != null) { output.writeInt32(8, obj.getByteField()); @@ -405,7 +436,7 @@ public static int toProto(User obj, CodedOutputStream output, ExpandableIntArray output.writeString(1, entry.getKey()); output.writeUInt32NoTag(18); output.writeUInt32NoTag(elementSize); - index = AddressProtoConverter.toProto(entry.getValue(), output, cache, index); + index = AddressProtoConverter.toProto(entry.getValue(), output, cache, index, compatibleMode); } } if (obj.getJsonValueMap() != null) { @@ -511,12 +542,16 @@ public static int toProto(User obj, CodedOutputStream output, ExpandableIntArray } public static int computeSize(User obj) { + return computeSize(obj, false); + } + + public static int computeSize(User obj, boolean compatibleMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - UserProtoConverter.computeSize(obj, cache, 0); + UserProtoConverter.computeSize(obj, cache, 0, compatibleMode); return cache.get(0); } - public static int computeSize(User obj, ExpandableIntArray cache, final int baseIndex) { + static int computeSize(User obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { int size = 0; int index = baseIndex + 1; if (obj.getUserName() != null) { @@ -544,7 +579,7 @@ public static int computeSize(User obj, ExpandableIntArray cache, final int base for (Address element: obj.getStructListField()) { size += CodedOutputStream.computeUInt32SizeNoTag(34); int savedIndex = index; - index = AddressProtoConverter.computeSize(element, cache, index); + index = AddressProtoConverter.computeSize(element, cache, index, compatibleMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; @@ -578,7 +613,7 @@ public static int computeSize(User obj, ExpandableIntArray cache, final int base if (obj.getAddress() != null) { size += CodedOutputStream.computeUInt32SizeNoTag(58); int savedIndex = index; - index = AddressProtoConverter.computeSize(obj.getAddress(), cache, index); + index = AddressProtoConverter.computeSize(obj.getAddress(), cache, index, compatibleMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; @@ -639,7 +674,7 @@ public static int computeSize(User obj, ExpandableIntArray cache, final int base dataSize += CodedOutputStream.computeStringSize(1, entry.getKey()); // value int savedIndex = index; - index = AddressProtoConverter.computeSize(entry.getValue(), cache, index); + index = AddressProtoConverter.computeSize(entry.getValue(), cache, index, compatibleMode); int elementSize = cache.get(savedIndex); dataSize += CodedOutputStream.computeInt32SizeNoTag(18); dataSize += CodedOutputStream.computeInt32SizeNoTag(elementSize); diff --git a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java index 876719f7c..d962431bc 100644 --- a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java +++ b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java @@ -90,6 +90,10 @@ public String renderProto(DataObjectModel model, int index, int size, Map Date: Sat, 14 Oct 2023 13:58:33 +0800 Subject: [PATCH 07/10] implements compatibleMode --- .../converters/generated/dataobjects.proto | 12 +- .../converter/AddressProtoConverter.java | 36 +++-- .../RecursiveItemProtoConverter.java | 19 ++- .../converter/SimplePojoProtoConverter.java | 118 ++++++---------- .../codegen/converter/UserProtoConverter.java | 101 +++++++++----- .../test/codegen/converter/SimplePojo.java | 80 +++-------- .../generator/DataObjectProtobufGen.java | 86 ++++++------ .../protobuf/generator/ProtoProperty.java | 72 ++++++++++ .../codegen/protobuf/CompatibilityTest.java | 128 ++++++++++-------- 9 files changed, 359 insertions(+), 293 deletions(-) diff --git a/vertx-codegen-protobuf/src/converters/generated/dataobjects.proto b/vertx-codegen-protobuf/src/converters/generated/dataobjects.proto index e36634328..a5fc0eb34 100644 --- a/vertx-codegen-protobuf/src/converters/generated/dataobjects.proto +++ b/vertx-codegen-protobuf/src/converters/generated/dataobjects.proto @@ -44,14 +44,10 @@ message RecursiveItem { } message SimplePojo { - int32 nullInteger = 1; - int32 zeroInteger = 2; - bool nullBoolean = 3; - bool zeroBoolean = 4; - string nullString = 5; - string zeroString = 6; - int32 primitiveInteger = 7; - bool primitiveBoolean = 8; + int32 integerField = 1; + int64 longField = 2; + bool booleanField = 3; + string stringField = 4; } message User { diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java index 6c3958307..ba6fd0306 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java @@ -21,6 +21,11 @@ public static void fromProto(CodedInputStream input, Address obj) throws IOExcep } public static void fromProto(CodedInputStream input, Address obj, boolean compatibleMode) throws IOException { + if (compatibleMode) { + obj.setName(""); + obj.setLongitude(0f); + obj.setLatitude(0f); + } int tag; while ((tag = input.readTag()) != 0) { switch (tag) { @@ -37,18 +42,7 @@ public static void fromProto(CodedInputStream input, Address obj, boolean compat break; } } - } - if (compatibleMode) { - if (obj.getName() == null) { - obj.setName(""); - } - if (obj.getLongitude() == null) { - obj.setLongitude(0f); - } - if (obj.getLatitude() == null) { - obj.setLatitude(0f); - } - } + } // while loop } public static void toProto(Address obj, CodedOutputStream output) throws IOException { @@ -63,13 +57,25 @@ public static void toProto(Address obj, CodedOutputStream output, boolean compat static int toProto(Address obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { index = index + 1; - if (obj.getName() != null) { + // name + if (compatibleMode && obj.getName() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getName() != null) || (compatibleMode && !obj.getName().isEmpty())) { output.writeString(1, obj.getName()); } - if (obj.getLongitude() != null) { + // longitude + if (compatibleMode && obj.getLongitude() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getLongitude() != null) || (compatibleMode && obj.getLongitude() != 0f)) { output.writeFloat(2, obj.getLongitude()); } - if (obj.getLatitude() != null) { + // latitude + if (compatibleMode && obj.getLatitude() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getLatitude() != null) || (compatibleMode && obj.getLatitude() != 0f)) { output.writeFloat(3, obj.getLatitude()); } return index; diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java index 4c991d54f..389ec41fd 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java @@ -21,6 +21,9 @@ public static void fromProto(CodedInputStream input, RecursiveItem obj) throws I } public static void fromProto(CodedInputStream input, RecursiveItem obj, boolean compatibleMode) throws IOException { + if (compatibleMode) { + obj.setId(""); + } int tag; while ((tag = input.readTag()) != 0) { switch (tag) { @@ -56,12 +59,7 @@ public static void fromProto(CodedInputStream input, RecursiveItem obj, boolean break; } } - } - if (compatibleMode) { - if (obj.getId() == null) { - obj.setId(""); - } - } + } // while loop } public static void toProto(RecursiveItem obj, CodedOutputStream output) throws IOException { @@ -76,19 +74,26 @@ public static void toProto(RecursiveItem obj, CodedOutputStream output, boolean static int toProto(RecursiveItem obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { index = index + 1; - if (obj.getId() != null) { + // id + if (compatibleMode && obj.getId() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getId() != null) || (compatibleMode && !obj.getId().isEmpty())) { output.writeString(1, obj.getId()); } + // childA if (obj.getChildA() != null) { output.writeUInt32NoTag(18); output.writeUInt32NoTag(cache.get(index)); index = RecursiveItemProtoConverter.toProto(obj.getChildA(), output, cache, index, compatibleMode); } + // childB if (obj.getChildB() != null) { output.writeUInt32NoTag(26); output.writeUInt32NoTag(cache.get(index)); index = RecursiveItemProtoConverter.toProto(obj.getChildB(), output, cache, index, compatibleMode); } + // childC if (obj.getChildC() != null) { output.writeUInt32NoTag(34); output.writeUInt32NoTag(cache.get(index)); diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java index 9691f8fa6..3bd3e353e 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java @@ -21,63 +21,33 @@ public static void fromProto(CodedInputStream input, SimplePojo obj) throws IOEx } public static void fromProto(CodedInputStream input, SimplePojo obj, boolean compatibleMode) throws IOException { + if (compatibleMode) { + obj.setIntegerField(0); + obj.setLongField(0L); + obj.setBooleanField(false); + obj.setStringField(""); + } int tag; while ((tag = input.readTag()) != 0) { switch (tag) { case 8: { - obj.setNullInteger(input.readInt32()); + obj.setIntegerField(input.readInt32()); break; } case 16: { - obj.setZeroInteger(input.readInt32()); + obj.setLongField(input.readInt64()); break; } case 24: { - obj.setNullBoolean(input.readBool()); - break; - } - case 32: { - obj.setZeroBoolean(input.readBool()); + obj.setBooleanField(input.readBool()); break; } - case 42: { - obj.setNullString(input.readString()); + case 34: { + obj.setStringField(input.readString()); break; } - case 50: { - obj.setZeroString(input.readString()); - break; - } - case 56: { - obj.setPrimitiveInteger(input.readInt32()); - break; - } - case 64: { - obj.setPrimitiveBoolean(input.readBool()); - break; - } - } - } - if (compatibleMode) { - if (obj.getNullInteger() == null) { - obj.setNullInteger(0); } - if (obj.getZeroInteger() == null) { - obj.setZeroInteger(0); - } - if (obj.getNullBoolean() == null) { - obj.setNullBoolean(false); - } - if (obj.getZeroBoolean() == null) { - obj.setZeroBoolean(false); - } - if (obj.getNullString() == null) { - obj.setNullString(""); - } - if (obj.getZeroString() == null) { - obj.setZeroString(""); - } - } + } // while loop } public static void toProto(SimplePojo obj, CodedOutputStream output) throws IOException { @@ -92,29 +62,33 @@ public static void toProto(SimplePojo obj, CodedOutputStream output, boolean com static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { index = index + 1; - if (obj.getNullInteger() != null) { - output.writeInt32(1, obj.getNullInteger()); + // integerField + if (compatibleMode && obj.getIntegerField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); } - if (obj.getZeroInteger() != null) { - output.writeInt32(2, obj.getZeroInteger()); + if ((!compatibleMode && obj.getIntegerField() != null) || (compatibleMode && obj.getIntegerField() != 0)) { + output.writeInt32(1, obj.getIntegerField()); } - if (obj.getNullBoolean() != null) { - output.writeBool(3, obj.getNullBoolean()); + // longField + if (compatibleMode && obj.getLongField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); } - if (obj.getZeroBoolean() != null) { - output.writeBool(4, obj.getZeroBoolean()); + if ((!compatibleMode && obj.getLongField() != null) || (compatibleMode && obj.getLongField() != 0L)) { + output.writeInt64(2, obj.getLongField()); } - if (obj.getNullString() != null) { - output.writeString(5, obj.getNullString()); + // booleanField + if (compatibleMode && obj.getBooleanField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); } - if (obj.getZeroString() != null) { - output.writeString(6, obj.getZeroString()); + if ((!compatibleMode && obj.getBooleanField() != null) || (compatibleMode && !obj.getBooleanField())) { + output.writeBool(3, obj.getBooleanField()); } - if (obj.getPrimitiveInteger() != 0) { - output.writeInt32(7, obj.getPrimitiveInteger()); + // stringField + if (compatibleMode && obj.getStringField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); } - if (obj.isPrimitiveBoolean()) { - output.writeBool(8, obj.isPrimitiveBoolean()); + if ((!compatibleMode && obj.getStringField() != null) || (compatibleMode && !obj.getStringField().isEmpty())) { + output.writeString(4, obj.getStringField()); } return index; } @@ -132,29 +106,17 @@ public static int computeSize(SimplePojo obj, boolean compatibleMode) { static int computeSize(SimplePojo obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { int size = 0; int index = baseIndex + 1; - if (obj.getNullInteger() != null) { - size += CodedOutputStream.computeInt32Size(1, obj.getNullInteger()); - } - if (obj.getZeroInteger() != null) { - size += CodedOutputStream.computeInt32Size(2, obj.getZeroInteger()); - } - if (obj.getNullBoolean() != null) { - size += CodedOutputStream.computeBoolSize(3, obj.getNullBoolean()); - } - if (obj.getZeroBoolean() != null) { - size += CodedOutputStream.computeBoolSize(4, obj.getZeroBoolean()); - } - if (obj.getNullString() != null) { - size += CodedOutputStream.computeStringSize(5, obj.getNullString()); + if (obj.getIntegerField() != null) { + size += CodedOutputStream.computeInt32Size(1, obj.getIntegerField()); } - if (obj.getZeroString() != null) { - size += CodedOutputStream.computeStringSize(6, obj.getZeroString()); + if (obj.getLongField() != null) { + size += CodedOutputStream.computeInt64Size(2, obj.getLongField()); } - if (obj.getPrimitiveInteger() != 0) { - size += CodedOutputStream.computeInt32Size(7, obj.getPrimitiveInteger()); + if (obj.getBooleanField() != null) { + size += CodedOutputStream.computeBoolSize(3, obj.getBooleanField()); } - if (obj.isPrimitiveBoolean()) { - size += CodedOutputStream.computeBoolSize(8, obj.isPrimitiveBoolean()); + if (obj.getStringField() != null) { + size += CodedOutputStream.computeStringSize(4, obj.getStringField()); } cache.set(baseIndex, size); return index; diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java index 26222b5ab..502f19cea 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java @@ -21,6 +21,15 @@ public static void fromProto(CodedInputStream input, User obj) throws IOExceptio } public static void fromProto(CodedInputStream input, User obj, boolean compatibleMode) throws IOException { + if (compatibleMode) { + obj.setUserName(""); + obj.setAge(0); + obj.setDoubleField(0d); + obj.setFloatField(0f); + obj.setLongField(0L); + obj.setBoolField(false); + obj.setShortField((short)0); + } int tag; while ((tag = input.readTag()) != 0) { switch (tag) { @@ -275,30 +284,7 @@ public static void fromProto(CodedInputStream input, User obj, boolean compatibl break; } } - } - if (compatibleMode) { - if (obj.getUserName() == null) { - obj.setUserName(""); - } - if (obj.getAge() == null) { - obj.setAge(0); - } - if (obj.getDoubleField() == null) { - obj.setDoubleField(0d); - } - if (obj.getFloatField() == null) { - obj.setFloatField(0f); - } - if (obj.getLongField() == null) { - obj.setLongField(0L); - } - if (obj.getBoolField() == null) { - obj.setBoolField(false); - } - if (obj.getShortField() == null) { - obj.setShortField((short)0); - } - } + } // while loop } public static void toProto(User obj, CodedOutputStream output) throws IOException { @@ -313,12 +299,21 @@ public static void toProto(User obj, CodedOutputStream output, boolean compatibl static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { index = index + 1; - if (obj.getUserName() != null) { + // userName + if (compatibleMode && obj.getUserName() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getUserName() != null) || (compatibleMode && !obj.getUserName().isEmpty())) { output.writeString(1, obj.getUserName()); } - if (obj.getAge() != null) { + // age + if (compatibleMode && obj.getAge() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getAge() != null) || (compatibleMode && obj.getAge() != 0)) { output.writeInt32(2, obj.getAge()); } + // integerListField if (obj.getIntegerListField() != null) { // list | tag | data size | value[0] | value[1] | value[2] | if (obj.getIntegerListField().size() > 0) { @@ -333,6 +328,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, } } } + // structListField if (obj.getStructListField() != null) { // list[0] | tag | data size | value | // list[1] | tag | data size | value | @@ -342,6 +338,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, index = AddressProtoConverter.toProto(element, output, cache, index, compatibleMode); } } + // zonedDateTimeListField if (obj.getZonedDateTimeListField() != null) { // list[0] | tag | data size | value | // list[1] | tag | data size | value | @@ -351,6 +348,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, ZonedDateTimeProtoConverter.toProto(element, output); } } + // jsonListField if (obj.getJsonListField() != null) { // list[0] | tag | data size | value | // list[1] | tag | data size | value | @@ -360,32 +358,56 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, VertxStructProtoConverter.toProto(element, output); } } + // address if (obj.getAddress() != null) { output.writeUInt32NoTag(58); output.writeUInt32NoTag(cache.get(index)); index = AddressProtoConverter.toProto(obj.getAddress(), output, cache, index, compatibleMode); } + // byteField if (obj.getByteField() != null) { output.writeInt32(8, obj.getByteField()); } - if (obj.getDoubleField() != null) { + // doubleField + if (compatibleMode && obj.getDoubleField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getDoubleField() != null) || (compatibleMode && obj.getDoubleField() != 0d)) { output.writeDouble(9, obj.getDoubleField()); } - if (obj.getFloatField() != null) { + // floatField + if (compatibleMode && obj.getFloatField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getFloatField() != null) || (compatibleMode && obj.getFloatField() != 0f)) { output.writeFloat(10, obj.getFloatField()); } - if (obj.getLongField() != null) { + // longField + if (compatibleMode && obj.getLongField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getLongField() != null) || (compatibleMode && obj.getLongField() != 0L)) { output.writeInt64(11, obj.getLongField()); } - if (obj.getBoolField() != null) { + // boolField + if (compatibleMode && obj.getBoolField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getBoolField() != null) || (compatibleMode && !obj.getBoolField())) { output.writeBool(12, obj.getBoolField()); } - if (obj.getShortField() != null) { + // shortField + if (compatibleMode && obj.getShortField() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getShortField() != null) || (compatibleMode && obj.getShortField() != (short)0)) { output.writeInt32(13, obj.getShortField()); } + // charField if (obj.getCharField() != null) { output.writeInt32(14, obj.getCharField()); } + // stringValueMap if (obj.getStringValueMap() != null) { // map[0] | tag | data size | key | value | // map[1] | tag | data size | key | value | @@ -402,6 +424,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, output.writeString(2, entry.getValue()); } } + // integerValueMap if (obj.getIntegerValueMap() != null) { // map[0] | tag | data size | key | value | // map[1] | tag | data size | key | value | @@ -418,6 +441,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, output.writeInt32(2, entry.getValue()); } } + // structValueMap if (obj.getStructValueMap() != null) { // map[0] | tag | data size | key | value | // map[1] | tag | data size | key | value | @@ -439,6 +463,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, index = AddressProtoConverter.toProto(entry.getValue(), output, cache, index, compatibleMode); } } + // jsonValueMap if (obj.getJsonValueMap() != null) { // map[0] | tag | data size | key | value | // map[1] | tag | data size | key | value | @@ -460,6 +485,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, VertxStructProtoConverter.toProto(entry.getValue(), output); } } + // zonedDateTimeValueMap if (obj.getZonedDateTimeValueMap() != null) { // map[0] | tag | data size | key | value | // map[1] | tag | data size | key | value | @@ -481,50 +507,63 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, ZonedDateTimeProtoConverter.toProto(entry.getValue(), output); } } + // zonedDateTimeField if (obj.getZonedDateTimeField() != null) { output.writeUInt32NoTag(162); output.writeUInt32NoTag(ZonedDateTimeProtoConverter.computeSize(obj.getZonedDateTimeField())); ZonedDateTimeProtoConverter.toProto(obj.getZonedDateTimeField(), output); } + // instantField if (obj.getInstantField() != null) { output.writeUInt32NoTag(170); output.writeUInt32NoTag(InstantProtoConverter.computeSize(obj.getInstantField())); InstantProtoConverter.toProto(obj.getInstantField(), output); } + // jsonObjectField if (obj.getJsonObjectField() != null) { output.writeUInt32NoTag(178); output.writeUInt32NoTag(VertxStructProtoConverter.computeSize(obj.getJsonObjectField())); VertxStructProtoConverter.toProto(obj.getJsonObjectField(), output); } + // jsonArrayField if (obj.getJsonArrayField() != null) { output.writeUInt32NoTag(186); output.writeUInt32NoTag(VertxStructListProtoConverter.computeSize(obj.getJsonArrayField())); VertxStructListProtoConverter.toProto(obj.getJsonArrayField(), output); } + // primitiveBoolean if (obj.isPrimitiveBoolean()) { output.writeBool(24, obj.isPrimitiveBoolean()); } + // primitiveByte if (obj.getPrimitiveByte() != 0) { output.writeInt32(25, obj.getPrimitiveByte()); } + // primitiveShort if (obj.getPrimitiveShort() != 0) { output.writeInt32(26, obj.getPrimitiveShort()); } + // primitiveInt if (obj.getPrimitiveInt() != 0) { output.writeInt32(27, obj.getPrimitiveInt()); } + // primitiveLong if (obj.getPrimitiveLong() != 0) { output.writeInt64(28, obj.getPrimitiveLong()); } + // primitiveFloat if (obj.getPrimitiveFloat() != 0) { output.writeFloat(29, obj.getPrimitiveFloat()); } + // primitiveDouble if (obj.getPrimitiveDouble() != 0) { output.writeDouble(30, obj.getPrimitiveDouble()); } + // primitiveChar if (obj.getPrimitiveChar() != 0) { output.writeInt32(31, obj.getPrimitiveChar()); } + // enumType if (obj.getEnumType() != null) { switch (obj.getEnumType()) { case A: diff --git a/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java b/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java index 64c23e6d3..6797552f4 100644 --- a/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java +++ b/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java @@ -8,77 +8,41 @@ @DataObject @ProtobufGen public class SimplePojo { - private Integer nullInteger; - private Integer zeroInteger; - private Boolean nullBoolean; - private Boolean zeroBoolean; - private String nullString; - private String ZeroString; - private int primitiveInteger; - private boolean primitiveBoolean; + private Integer integerField; + private Long LongField; + private Boolean booleanField; + private String stringField; - public Integer getNullInteger() { - return nullInteger; + public Integer getIntegerField() { + return integerField; } - public void setNullInteger(Integer nullInteger) { - this.nullInteger = nullInteger; + public void setIntegerField(Integer integerField) { + this.integerField = integerField; } - public Integer getZeroInteger() { - return zeroInteger; + public Long getLongField() { + return LongField; } - public void setZeroInteger(Integer zeroInteger) { - this.zeroInteger = zeroInteger; + public void setLongField(Long longField) { + LongField = longField; } - public Boolean getNullBoolean() { - return nullBoolean; + public Boolean getBooleanField() { + return booleanField; } - public void setNullBoolean(Boolean nullBoolean) { - this.nullBoolean = nullBoolean; + public void setBooleanField(Boolean booleanField) { + this.booleanField = booleanField; } - public Boolean getZeroBoolean() { - return zeroBoolean; + public String getStringField() { + return stringField; } - public void setZeroBoolean(Boolean zeroBoolean) { - this.zeroBoolean = zeroBoolean; - } - - public String getNullString() { - return nullString; - } - - public void setNullString(String nullString) { - this.nullString = nullString; - } - - public String getZeroString() { - return ZeroString; - } - - public void setZeroString(String zeroString) { - this.ZeroString = zeroString; - } - - public int getPrimitiveInteger() { - return primitiveInteger; - } - - public void setPrimitiveInteger(int primitiveInteger) { - this.primitiveInteger = primitiveInteger; - } - - public boolean isPrimitiveBoolean() { - return primitiveBoolean; - } - - public void setPrimitiveBoolean(boolean primitiveBoolean) { - this.primitiveBoolean = primitiveBoolean; + public void setStringField(String stringField) { + this.stringField = stringField; } @Override @@ -86,11 +50,11 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; SimplePojo that = (SimplePojo) o; - return primitiveInteger == that.primitiveInteger && primitiveBoolean == that.primitiveBoolean && Objects.equals(nullInteger, that.nullInteger) && Objects.equals(zeroInteger, that.zeroInteger) && Objects.equals(nullBoolean, that.nullBoolean) && Objects.equals(zeroBoolean, that.zeroBoolean) && Objects.equals(nullString, that.nullString) && Objects.equals(ZeroString, that.ZeroString); + return Objects.equals(integerField, that.integerField) && Objects.equals(LongField, that.LongField) && Objects.equals(booleanField, that.booleanField) && Objects.equals(stringField, that.stringField); } @Override public int hashCode() { - return Objects.hash(nullInteger, zeroInteger, nullBoolean, zeroBoolean, nullString, ZeroString, primitiveInteger, primitiveBoolean); + return Objects.hash(integerField, LongField, booleanField, stringField); } } diff --git a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java index d962431bc..d38fed10c 100644 --- a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java +++ b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java @@ -94,6 +94,24 @@ public String renderProto(DataObjectModel model, int index, int size, Map Date: Sat, 14 Oct 2023 15:39:28 +0800 Subject: [PATCH 08/10] add ProtobufEncodingMode enum --- .../converter/AddressProtoConverter.java | 25 +++++---- .../RecursiveItemProtoConverter.java | 37 +++++++------ .../converter/SimplePojoProtoConverter.java | 25 +++++---- .../codegen/converter/UserProtoConverter.java | 37 +++++++------ .../protobuf/ProtobufEncodingMode.java | 19 +++++++ .../generator/DataObjectProtobufGen.java | 37 +++++++------ .../codegen/protobuf/CompatibilityTest.java | 55 ++++++++++--------- 7 files changed, 135 insertions(+), 100 deletions(-) create mode 100644 vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/ProtobufEncodingMode.java diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java index ba6fd0306..60fc1f6e2 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Arrays; +import io.vertx.codegen.protobuf.ProtobufEncodingMode; import io.vertx.core.json.JsonObject; import io.vertx.codegen.protobuf.utils.ExpandableIntArray; import io.vertx.codegen.protobuf.converters.*; @@ -17,10 +18,11 @@ public class AddressProtoConverter { public static void fromProto(CodedInputStream input, Address obj) throws IOException { - fromProto(input, obj, false); + fromProto(input, obj, ProtobufEncodingMode.VERTX_NULLABLE); } - public static void fromProto(CodedInputStream input, Address obj, boolean compatibleMode) throws IOException { + public static void fromProto(CodedInputStream input, Address obj, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; if (compatibleMode) { obj.setName(""); obj.setLongitude(0f); @@ -46,16 +48,17 @@ public static void fromProto(CodedInputStream input, Address obj, boolean compat } public static void toProto(Address obj, CodedOutputStream output) throws IOException { - toProto(obj, output, false); + toProto(obj, output, ProtobufEncodingMode.VERTX_NULLABLE); } - public static void toProto(Address obj, CodedOutputStream output, boolean compatibleMode) throws IOException { + public static void toProto(Address obj, CodedOutputStream output, ProtobufEncodingMode encodingMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - AddressProtoConverter.computeSize(obj, cache, 0, compatibleMode); - AddressProtoConverter.toProto(obj, output, cache, 0, compatibleMode); + AddressProtoConverter.computeSize(obj, cache, 0, encodingMode); + AddressProtoConverter.toProto(obj, output, cache, 0, encodingMode); } - static int toProto(Address obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { + static int toProto(Address obj, CodedOutputStream output, ExpandableIntArray cache, int index, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; index = index + 1; // name if (compatibleMode && obj.getName() == null) { @@ -82,16 +85,16 @@ static int toProto(Address obj, CodedOutputStream output, ExpandableIntArray cac } public static int computeSize(Address obj) { - return computeSize(obj, false); + return computeSize(obj, ProtobufEncodingMode.VERTX_NULLABLE); } - public static int computeSize(Address obj, boolean compatibleMode) { + public static int computeSize(Address obj, ProtobufEncodingMode encodingMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - AddressProtoConverter.computeSize(obj, cache, 0, compatibleMode); + AddressProtoConverter.computeSize(obj, cache, 0, encodingMode); return cache.get(0); } - static int computeSize(Address obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { + static int computeSize(Address obj, ExpandableIntArray cache, final int baseIndex, ProtobufEncodingMode encodingMode) { int size = 0; int index = baseIndex + 1; if (obj.getName() != null) { diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java index 389ec41fd..eb9eaf51f 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Arrays; +import io.vertx.codegen.protobuf.ProtobufEncodingMode; import io.vertx.core.json.JsonObject; import io.vertx.codegen.protobuf.utils.ExpandableIntArray; import io.vertx.codegen.protobuf.converters.*; @@ -17,10 +18,11 @@ public class RecursiveItemProtoConverter { public static void fromProto(CodedInputStream input, RecursiveItem obj) throws IOException { - fromProto(input, obj, false); + fromProto(input, obj, ProtobufEncodingMode.VERTX_NULLABLE); } - public static void fromProto(CodedInputStream input, RecursiveItem obj, boolean compatibleMode) throws IOException { + public static void fromProto(CodedInputStream input, RecursiveItem obj, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; if (compatibleMode) { obj.setId(""); } @@ -63,16 +65,17 @@ public static void fromProto(CodedInputStream input, RecursiveItem obj, boolean } public static void toProto(RecursiveItem obj, CodedOutputStream output) throws IOException { - toProto(obj, output, false); + toProto(obj, output, ProtobufEncodingMode.VERTX_NULLABLE); } - public static void toProto(RecursiveItem obj, CodedOutputStream output, boolean compatibleMode) throws IOException { + public static void toProto(RecursiveItem obj, CodedOutputStream output, ProtobufEncodingMode encodingMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - RecursiveItemProtoConverter.computeSize(obj, cache, 0, compatibleMode); - RecursiveItemProtoConverter.toProto(obj, output, cache, 0, compatibleMode); + RecursiveItemProtoConverter.computeSize(obj, cache, 0, encodingMode); + RecursiveItemProtoConverter.toProto(obj, output, cache, 0, encodingMode); } - static int toProto(RecursiveItem obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { + static int toProto(RecursiveItem obj, CodedOutputStream output, ExpandableIntArray cache, int index, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; index = index + 1; // id if (compatibleMode && obj.getId() == null) { @@ -85,34 +88,34 @@ static int toProto(RecursiveItem obj, CodedOutputStream output, ExpandableIntArr if (obj.getChildA() != null) { output.writeUInt32NoTag(18); output.writeUInt32NoTag(cache.get(index)); - index = RecursiveItemProtoConverter.toProto(obj.getChildA(), output, cache, index, compatibleMode); + index = RecursiveItemProtoConverter.toProto(obj.getChildA(), output, cache, index, encodingMode); } // childB if (obj.getChildB() != null) { output.writeUInt32NoTag(26); output.writeUInt32NoTag(cache.get(index)); - index = RecursiveItemProtoConverter.toProto(obj.getChildB(), output, cache, index, compatibleMode); + index = RecursiveItemProtoConverter.toProto(obj.getChildB(), output, cache, index, encodingMode); } // childC if (obj.getChildC() != null) { output.writeUInt32NoTag(34); output.writeUInt32NoTag(cache.get(index)); - index = RecursiveItemProtoConverter.toProto(obj.getChildC(), output, cache, index, compatibleMode); + index = RecursiveItemProtoConverter.toProto(obj.getChildC(), output, cache, index, encodingMode); } return index; } public static int computeSize(RecursiveItem obj) { - return computeSize(obj, false); + return computeSize(obj, ProtobufEncodingMode.VERTX_NULLABLE); } - public static int computeSize(RecursiveItem obj, boolean compatibleMode) { + public static int computeSize(RecursiveItem obj, ProtobufEncodingMode encodingMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - RecursiveItemProtoConverter.computeSize(obj, cache, 0, compatibleMode); + RecursiveItemProtoConverter.computeSize(obj, cache, 0, encodingMode); return cache.get(0); } - static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { + static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final int baseIndex, ProtobufEncodingMode encodingMode) { int size = 0; int index = baseIndex + 1; if (obj.getId() != null) { @@ -121,7 +124,7 @@ static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final int ba if (obj.getChildA() != null) { size += CodedOutputStream.computeUInt32SizeNoTag(18); int savedIndex = index; - index = RecursiveItemProtoConverter.computeSize(obj.getChildA(), cache, index, compatibleMode); + index = RecursiveItemProtoConverter.computeSize(obj.getChildA(), cache, index, encodingMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; @@ -129,7 +132,7 @@ static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final int ba if (obj.getChildB() != null) { size += CodedOutputStream.computeUInt32SizeNoTag(26); int savedIndex = index; - index = RecursiveItemProtoConverter.computeSize(obj.getChildB(), cache, index, compatibleMode); + index = RecursiveItemProtoConverter.computeSize(obj.getChildB(), cache, index, encodingMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; @@ -137,7 +140,7 @@ static int computeSize(RecursiveItem obj, ExpandableIntArray cache, final int ba if (obj.getChildC() != null) { size += CodedOutputStream.computeUInt32SizeNoTag(34); int savedIndex = index; - index = RecursiveItemProtoConverter.computeSize(obj.getChildC(), cache, index, compatibleMode); + index = RecursiveItemProtoConverter.computeSize(obj.getChildC(), cache, index, encodingMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java index 3bd3e353e..bea7a12f3 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Arrays; +import io.vertx.codegen.protobuf.ProtobufEncodingMode; import io.vertx.core.json.JsonObject; import io.vertx.codegen.protobuf.utils.ExpandableIntArray; import io.vertx.codegen.protobuf.converters.*; @@ -17,10 +18,11 @@ public class SimplePojoProtoConverter { public static void fromProto(CodedInputStream input, SimplePojo obj) throws IOException { - fromProto(input, obj, false); + fromProto(input, obj, ProtobufEncodingMode.VERTX_NULLABLE); } - public static void fromProto(CodedInputStream input, SimplePojo obj, boolean compatibleMode) throws IOException { + public static void fromProto(CodedInputStream input, SimplePojo obj, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; if (compatibleMode) { obj.setIntegerField(0); obj.setLongField(0L); @@ -51,16 +53,17 @@ public static void fromProto(CodedInputStream input, SimplePojo obj, boolean com } public static void toProto(SimplePojo obj, CodedOutputStream output) throws IOException { - toProto(obj, output, false); + toProto(obj, output, ProtobufEncodingMode.VERTX_NULLABLE); } - public static void toProto(SimplePojo obj, CodedOutputStream output, boolean compatibleMode) throws IOException { + public static void toProto(SimplePojo obj, CodedOutputStream output, ProtobufEncodingMode encodingMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - SimplePojoProtoConverter.computeSize(obj, cache, 0, compatibleMode); - SimplePojoProtoConverter.toProto(obj, output, cache, 0, compatibleMode); + SimplePojoProtoConverter.computeSize(obj, cache, 0, encodingMode); + SimplePojoProtoConverter.toProto(obj, output, cache, 0, encodingMode); } - static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { + static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIntArray cache, int index, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; index = index + 1; // integerField if (compatibleMode && obj.getIntegerField() == null) { @@ -94,16 +97,16 @@ static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIntArray } public static int computeSize(SimplePojo obj) { - return computeSize(obj, false); + return computeSize(obj, ProtobufEncodingMode.VERTX_NULLABLE); } - public static int computeSize(SimplePojo obj, boolean compatibleMode) { + public static int computeSize(SimplePojo obj, ProtobufEncodingMode encodingMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - SimplePojoProtoConverter.computeSize(obj, cache, 0, compatibleMode); + SimplePojoProtoConverter.computeSize(obj, cache, 0, encodingMode); return cache.get(0); } - static int computeSize(SimplePojo obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { + static int computeSize(SimplePojo obj, ExpandableIntArray cache, final int baseIndex, ProtobufEncodingMode encodingMode) { int size = 0; int index = baseIndex + 1; if (obj.getIntegerField() != null) { diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java index 502f19cea..d715ae87a 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Arrays; +import io.vertx.codegen.protobuf.ProtobufEncodingMode; import io.vertx.core.json.JsonObject; import io.vertx.codegen.protobuf.utils.ExpandableIntArray; import io.vertx.codegen.protobuf.converters.*; @@ -17,10 +18,11 @@ public class UserProtoConverter { public static void fromProto(CodedInputStream input, User obj) throws IOException { - fromProto(input, obj, false); + fromProto(input, obj, ProtobufEncodingMode.VERTX_NULLABLE); } - public static void fromProto(CodedInputStream input, User obj, boolean compatibleMode) throws IOException { + public static void fromProto(CodedInputStream input, User obj, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; if (compatibleMode) { obj.setUserName(""); obj.setAge(0); @@ -288,16 +290,17 @@ public static void fromProto(CodedInputStream input, User obj, boolean compatibl } public static void toProto(User obj, CodedOutputStream output) throws IOException { - toProto(obj, output, false); + toProto(obj, output, ProtobufEncodingMode.VERTX_NULLABLE); } - public static void toProto(User obj, CodedOutputStream output, boolean compatibleMode) throws IOException { + public static void toProto(User obj, CodedOutputStream output, ProtobufEncodingMode encodingMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - UserProtoConverter.computeSize(obj, cache, 0, compatibleMode); - UserProtoConverter.toProto(obj, output, cache, 0, compatibleMode); + UserProtoConverter.computeSize(obj, cache, 0, encodingMode); + UserProtoConverter.toProto(obj, output, cache, 0, encodingMode); } - static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, int index, boolean compatibleMode) throws IOException { + static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, int index, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; index = index + 1; // userName if (compatibleMode && obj.getUserName() == null) { @@ -335,7 +338,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, for (Address element: obj.getStructListField()) { output.writeUInt32NoTag(34); output.writeUInt32NoTag(cache.get(index)); - index = AddressProtoConverter.toProto(element, output, cache, index, compatibleMode); + index = AddressProtoConverter.toProto(element, output, cache, index, encodingMode); } } // zonedDateTimeListField @@ -362,7 +365,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, if (obj.getAddress() != null) { output.writeUInt32NoTag(58); output.writeUInt32NoTag(cache.get(index)); - index = AddressProtoConverter.toProto(obj.getAddress(), output, cache, index, compatibleMode); + index = AddressProtoConverter.toProto(obj.getAddress(), output, cache, index, encodingMode); } // byteField if (obj.getByteField() != null) { @@ -460,7 +463,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, output.writeString(1, entry.getKey()); output.writeUInt32NoTag(18); output.writeUInt32NoTag(elementSize); - index = AddressProtoConverter.toProto(entry.getValue(), output, cache, index, compatibleMode); + index = AddressProtoConverter.toProto(entry.getValue(), output, cache, index, encodingMode); } } // jsonValueMap @@ -581,16 +584,16 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, } public static int computeSize(User obj) { - return computeSize(obj, false); + return computeSize(obj, ProtobufEncodingMode.VERTX_NULLABLE); } - public static int computeSize(User obj, boolean compatibleMode) { + public static int computeSize(User obj, ProtobufEncodingMode encodingMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - UserProtoConverter.computeSize(obj, cache, 0, compatibleMode); + UserProtoConverter.computeSize(obj, cache, 0, encodingMode); return cache.get(0); } - static int computeSize(User obj, ExpandableIntArray cache, final int baseIndex, boolean compatibleMode) { + static int computeSize(User obj, ExpandableIntArray cache, final int baseIndex, ProtobufEncodingMode encodingMode) { int size = 0; int index = baseIndex + 1; if (obj.getUserName() != null) { @@ -618,7 +621,7 @@ static int computeSize(User obj, ExpandableIntArray cache, final int baseIndex, for (Address element: obj.getStructListField()) { size += CodedOutputStream.computeUInt32SizeNoTag(34); int savedIndex = index; - index = AddressProtoConverter.computeSize(element, cache, index, compatibleMode); + index = AddressProtoConverter.computeSize(element, cache, index, encodingMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; @@ -652,7 +655,7 @@ static int computeSize(User obj, ExpandableIntArray cache, final int baseIndex, if (obj.getAddress() != null) { size += CodedOutputStream.computeUInt32SizeNoTag(58); int savedIndex = index; - index = AddressProtoConverter.computeSize(obj.getAddress(), cache, index, compatibleMode); + index = AddressProtoConverter.computeSize(obj.getAddress(), cache, index, encodingMode); int dataSize = cache.get(savedIndex); size += CodedOutputStream.computeUInt32SizeNoTag(dataSize); size += dataSize; @@ -713,7 +716,7 @@ static int computeSize(User obj, ExpandableIntArray cache, final int baseIndex, dataSize += CodedOutputStream.computeStringSize(1, entry.getKey()); // value int savedIndex = index; - index = AddressProtoConverter.computeSize(entry.getValue(), cache, index, compatibleMode); + index = AddressProtoConverter.computeSize(entry.getValue(), cache, index, encodingMode); int elementSize = cache.get(savedIndex); dataSize += CodedOutputStream.computeInt32SizeNoTag(18); dataSize += CodedOutputStream.computeInt32SizeNoTag(elementSize); diff --git a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/ProtobufEncodingMode.java b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/ProtobufEncodingMode.java new file mode 100644 index 000000000..a35b9284c --- /dev/null +++ b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/ProtobufEncodingMode.java @@ -0,0 +1,19 @@ +package io.vertx.codegen.protobuf; + +/** + * Enumeration representing different encoding modes for Protocol Buffers encoding. + */ +public enum ProtobufEncodingMode { + /** + * In this encoding mode, the converter uses a non-standard protobuf encoding to allow boxed types + * (e.g., Integer, Double) and String to be nullable. This encoding mode is intended for use when + * communicating with another Vert.x converter that supports nullable values. + */ + VERTX_NULLABLE, + + /** + * In this encoding mode, the converter uses the standard protobuf encoding, which is compatible with + * Google's protobuf decoder. Null values are not allowed for boxed types and String in this mode. + */ + GOOGLE_COMPATIBLE, +} diff --git a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java index d38fed10c..9303c8755 100644 --- a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java +++ b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java @@ -72,6 +72,7 @@ public String renderProto(DataObjectModel model, int index, int size, Map Date: Fri, 20 Oct 2023 20:19:13 +0800 Subject: [PATCH 09/10] resolve some merge conflict --- .../codegen/converter/BookProtoConverter.java | 57 +++++++++++++++---- .../converter/PersonProtoConverter.java | 37 +++++++++--- .../test/codegen/converter/SimplePojo.java | 3 +- 3 files changed, 79 insertions(+), 18 deletions(-) diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/BookProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/BookProtoConverter.java index 0b617d0c9..c7962d8d7 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/BookProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/BookProtoConverter.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Arrays; +import io.vertx.codegen.protobuf.ProtobufEncodingMode; import io.vertx.core.json.JsonObject; import io.vertx.codegen.protobuf.utils.ExpandableIntArray; import io.vertx.codegen.protobuf.converters.*; @@ -17,6 +18,17 @@ public class BookProtoConverter { public static void fromProto(CodedInputStream input, Book obj) throws IOException { + fromProto(input, obj, ProtobufEncodingMode.VERTX_NULLABLE); + } + + public static void fromProto(CodedInputStream input, Book obj, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; + if (compatibleMode) { + obj.setName(""); + obj.setAuthor(""); + obj.setIsbn(""); + obj.setGenre(""); + } int tag; while ((tag = input.readTag()) != 0) { switch (tag) { @@ -37,39 +49,64 @@ public static void fromProto(CodedInputStream input, Book obj) throws IOExceptio break; } } - } + } // while loop } public static void toProto(Book obj, CodedOutputStream output) throws IOException { + toProto(obj, output, ProtobufEncodingMode.VERTX_NULLABLE); + } + + public static void toProto(Book obj, CodedOutputStream output, ProtobufEncodingMode encodingMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - BookProtoConverter.computeSize(obj, cache, 0); - BookProtoConverter.toProto(obj, output, cache, 0); + BookProtoConverter.computeSize(obj, cache, 0, encodingMode); + BookProtoConverter.toProto(obj, output, cache, 0, encodingMode); } - public static int toProto(Book obj, CodedOutputStream output, ExpandableIntArray cache, int index) throws IOException { + static int toProto(Book obj, CodedOutputStream output, ExpandableIntArray cache, int index, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; index = index + 1; - if (obj.getName() != null) { + // name + if (compatibleMode && obj.getName() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getName() != null) || (compatibleMode && !obj.getName().isEmpty())) { output.writeString(1, obj.getName()); } - if (obj.getAuthor() != null) { + // author + if (compatibleMode && obj.getAuthor() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getAuthor() != null) || (compatibleMode && !obj.getAuthor().isEmpty())) { output.writeString(3, obj.getAuthor()); } - if (obj.getIsbn() != null) { + // isbn + if (compatibleMode && obj.getIsbn() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getIsbn() != null) || (compatibleMode && !obj.getIsbn().isEmpty())) { output.writeString(10, obj.getIsbn()); } - if (obj.getGenre() != null) { + // genre + if (compatibleMode && obj.getGenre() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getGenre() != null) || (compatibleMode && !obj.getGenre().isEmpty())) { output.writeString(20, obj.getGenre()); } return index; } public static int computeSize(Book obj) { + return computeSize(obj, ProtobufEncodingMode.VERTX_NULLABLE); + } + + public static int computeSize(Book obj, ProtobufEncodingMode encodingMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - BookProtoConverter.computeSize(obj, cache, 0); + BookProtoConverter.computeSize(obj, cache, 0, encodingMode); return cache.get(0); } - public static int computeSize(Book obj, ExpandableIntArray cache, final int baseIndex) { + static int computeSize(Book obj, ExpandableIntArray cache, final int baseIndex, ProtobufEncodingMode encodingMode) { int size = 0; int index = baseIndex + 1; if (obj.getName() != null) { diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/PersonProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/PersonProtoConverter.java index 46002f198..39165d1bd 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/PersonProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/PersonProtoConverter.java @@ -10,6 +10,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Arrays; +import io.vertx.codegen.protobuf.ProtobufEncodingMode; import io.vertx.core.json.JsonObject; import io.vertx.codegen.protobuf.utils.ExpandableIntArray; import io.vertx.codegen.protobuf.converters.*; @@ -17,6 +18,14 @@ public class PersonProtoConverter { public static void fromProto(CodedInputStream input, Person obj) throws IOException { + fromProto(input, obj, ProtobufEncodingMode.VERTX_NULLABLE); + } + + public static void fromProto(CodedInputStream input, Person obj, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; + if (compatibleMode) { + obj.setName(""); + } int tag; while ((tag = input.readTag()) != 0) { switch (tag) { @@ -29,20 +38,30 @@ public static void fromProto(CodedInputStream input, Person obj) throws IOExcept break; } } - } + } // while loop } public static void toProto(Person obj, CodedOutputStream output) throws IOException { + toProto(obj, output, ProtobufEncodingMode.VERTX_NULLABLE); + } + + public static void toProto(Person obj, CodedOutputStream output, ProtobufEncodingMode encodingMode) throws IOException { ExpandableIntArray cache = new ExpandableIntArray(16); - PersonProtoConverter.computeSize(obj, cache, 0); - PersonProtoConverter.toProto(obj, output, cache, 0); + PersonProtoConverter.computeSize(obj, cache, 0, encodingMode); + PersonProtoConverter.toProto(obj, output, cache, 0, encodingMode); } - public static int toProto(Person obj, CodedOutputStream output, ExpandableIntArray cache, int index) throws IOException { + static int toProto(Person obj, CodedOutputStream output, ExpandableIntArray cache, int index, ProtobufEncodingMode encodingMode) throws IOException { + boolean compatibleMode = encodingMode == ProtobufEncodingMode.GOOGLE_COMPATIBLE; index = index + 1; - if (obj.getName() != null) { + // name + if (compatibleMode && obj.getName() == null) { + throw new IllegalArgumentException("Null values are not allowed for boxed types in compatibility mode"); + } + if ((!compatibleMode && obj.getName() != null) || (compatibleMode && !obj.getName().isEmpty())) { output.writeString(2, obj.getName()); } + // age if (obj.getAge() != 0) { output.writeInt32(4, obj.getAge()); } @@ -50,12 +69,16 @@ public static int toProto(Person obj, CodedOutputStream output, ExpandableIntArr } public static int computeSize(Person obj) { + return computeSize(obj, ProtobufEncodingMode.VERTX_NULLABLE); + } + + public static int computeSize(Person obj, ProtobufEncodingMode encodingMode) { ExpandableIntArray cache = new ExpandableIntArray(16); - PersonProtoConverter.computeSize(obj, cache, 0); + PersonProtoConverter.computeSize(obj, cache, 0, encodingMode); return cache.get(0); } - public static int computeSize(Person obj, ExpandableIntArray cache, final int baseIndex) { + static int computeSize(Person obj, ExpandableIntArray cache, final int baseIndex, ProtobufEncodingMode encodingMode) { int size = 0; int index = baseIndex + 1; if (obj.getName() != null) { diff --git a/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java b/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java index 6797552f4..7ec210e7d 100644 --- a/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java +++ b/vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/SimplePojo.java @@ -1,12 +1,13 @@ package io.vertx.test.codegen.converter; import io.vertx.codegen.annotations.DataObject; +import io.vertx.codegen.protobuf.annotations.FieldNumberStrategy; import io.vertx.codegen.protobuf.annotations.ProtobufGen; import java.util.Objects; @DataObject -@ProtobufGen +@ProtobufGen(fieldNumberStrategy = FieldNumberStrategy.COMPACT) public class SimplePojo { private Integer integerField; private Long LongField; From 39a50a1ced96b6156d6d3c73df6c94f7ae6f2767 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Fri, 20 Oct 2023 20:22:11 +0800 Subject: [PATCH 10/10] rename VERTX_NULLABLE to VERTX --- .../vertx/test/codegen/converter/AddressProtoConverter.java | 6 +++--- .../io/vertx/test/codegen/converter/BookProtoConverter.java | 6 +++--- .../vertx/test/codegen/converter/PersonProtoConverter.java | 6 +++--- .../test/codegen/converter/RecursiveItemProtoConverter.java | 6 +++--- .../test/codegen/converter/SimplePojoProtoConverter.java | 6 +++--- .../io/vertx/test/codegen/converter/UserProtoConverter.java | 6 +++--- .../io/vertx/codegen/protobuf/ProtobufEncodingMode.java | 2 +- .../codegen/protobuf/generator/DataObjectProtobufGen.java | 6 +++--- .../io/vertx/test/codegen/protobuf/CompatibilityTest.java | 6 +++--- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java index 60fc1f6e2..3e210a732 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/AddressProtoConverter.java @@ -18,7 +18,7 @@ public class AddressProtoConverter { public static void fromProto(CodedInputStream input, Address obj) throws IOException { - fromProto(input, obj, ProtobufEncodingMode.VERTX_NULLABLE); + fromProto(input, obj, ProtobufEncodingMode.VERTX); } public static void fromProto(CodedInputStream input, Address obj, ProtobufEncodingMode encodingMode) throws IOException { @@ -48,7 +48,7 @@ public static void fromProto(CodedInputStream input, Address obj, ProtobufEncodi } public static void toProto(Address obj, CodedOutputStream output) throws IOException { - toProto(obj, output, ProtobufEncodingMode.VERTX_NULLABLE); + toProto(obj, output, ProtobufEncodingMode.VERTX); } public static void toProto(Address obj, CodedOutputStream output, ProtobufEncodingMode encodingMode) throws IOException { @@ -85,7 +85,7 @@ static int toProto(Address obj, CodedOutputStream output, ExpandableIntArray cac } public static int computeSize(Address obj) { - return computeSize(obj, ProtobufEncodingMode.VERTX_NULLABLE); + return computeSize(obj, ProtobufEncodingMode.VERTX); } public static int computeSize(Address obj, ProtobufEncodingMode encodingMode) { diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/BookProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/BookProtoConverter.java index c7962d8d7..cdfefae5f 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/BookProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/BookProtoConverter.java @@ -18,7 +18,7 @@ public class BookProtoConverter { public static void fromProto(CodedInputStream input, Book obj) throws IOException { - fromProto(input, obj, ProtobufEncodingMode.VERTX_NULLABLE); + fromProto(input, obj, ProtobufEncodingMode.VERTX); } public static void fromProto(CodedInputStream input, Book obj, ProtobufEncodingMode encodingMode) throws IOException { @@ -53,7 +53,7 @@ public static void fromProto(CodedInputStream input, Book obj, ProtobufEncodingM } public static void toProto(Book obj, CodedOutputStream output) throws IOException { - toProto(obj, output, ProtobufEncodingMode.VERTX_NULLABLE); + toProto(obj, output, ProtobufEncodingMode.VERTX); } public static void toProto(Book obj, CodedOutputStream output, ProtobufEncodingMode encodingMode) throws IOException { @@ -97,7 +97,7 @@ static int toProto(Book obj, CodedOutputStream output, ExpandableIntArray cache, } public static int computeSize(Book obj) { - return computeSize(obj, ProtobufEncodingMode.VERTX_NULLABLE); + return computeSize(obj, ProtobufEncodingMode.VERTX); } public static int computeSize(Book obj, ProtobufEncodingMode encodingMode) { diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/PersonProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/PersonProtoConverter.java index 39165d1bd..6b752d547 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/PersonProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/PersonProtoConverter.java @@ -18,7 +18,7 @@ public class PersonProtoConverter { public static void fromProto(CodedInputStream input, Person obj) throws IOException { - fromProto(input, obj, ProtobufEncodingMode.VERTX_NULLABLE); + fromProto(input, obj, ProtobufEncodingMode.VERTX); } public static void fromProto(CodedInputStream input, Person obj, ProtobufEncodingMode encodingMode) throws IOException { @@ -42,7 +42,7 @@ public static void fromProto(CodedInputStream input, Person obj, ProtobufEncodin } public static void toProto(Person obj, CodedOutputStream output) throws IOException { - toProto(obj, output, ProtobufEncodingMode.VERTX_NULLABLE); + toProto(obj, output, ProtobufEncodingMode.VERTX); } public static void toProto(Person obj, CodedOutputStream output, ProtobufEncodingMode encodingMode) throws IOException { @@ -69,7 +69,7 @@ static int toProto(Person obj, CodedOutputStream output, ExpandableIntArray cach } public static int computeSize(Person obj) { - return computeSize(obj, ProtobufEncodingMode.VERTX_NULLABLE); + return computeSize(obj, ProtobufEncodingMode.VERTX); } public static int computeSize(Person obj, ProtobufEncodingMode encodingMode) { diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java index eb9eaf51f..86be31240 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/RecursiveItemProtoConverter.java @@ -18,7 +18,7 @@ public class RecursiveItemProtoConverter { public static void fromProto(CodedInputStream input, RecursiveItem obj) throws IOException { - fromProto(input, obj, ProtobufEncodingMode.VERTX_NULLABLE); + fromProto(input, obj, ProtobufEncodingMode.VERTX); } public static void fromProto(CodedInputStream input, RecursiveItem obj, ProtobufEncodingMode encodingMode) throws IOException { @@ -65,7 +65,7 @@ public static void fromProto(CodedInputStream input, RecursiveItem obj, Protobuf } public static void toProto(RecursiveItem obj, CodedOutputStream output) throws IOException { - toProto(obj, output, ProtobufEncodingMode.VERTX_NULLABLE); + toProto(obj, output, ProtobufEncodingMode.VERTX); } public static void toProto(RecursiveItem obj, CodedOutputStream output, ProtobufEncodingMode encodingMode) throws IOException { @@ -106,7 +106,7 @@ static int toProto(RecursiveItem obj, CodedOutputStream output, ExpandableIntArr } public static int computeSize(RecursiveItem obj) { - return computeSize(obj, ProtobufEncodingMode.VERTX_NULLABLE); + return computeSize(obj, ProtobufEncodingMode.VERTX); } public static int computeSize(RecursiveItem obj, ProtobufEncodingMode encodingMode) { diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java index bea7a12f3..decb01c7a 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/SimplePojoProtoConverter.java @@ -18,7 +18,7 @@ public class SimplePojoProtoConverter { public static void fromProto(CodedInputStream input, SimplePojo obj) throws IOException { - fromProto(input, obj, ProtobufEncodingMode.VERTX_NULLABLE); + fromProto(input, obj, ProtobufEncodingMode.VERTX); } public static void fromProto(CodedInputStream input, SimplePojo obj, ProtobufEncodingMode encodingMode) throws IOException { @@ -53,7 +53,7 @@ public static void fromProto(CodedInputStream input, SimplePojo obj, ProtobufEnc } public static void toProto(SimplePojo obj, CodedOutputStream output) throws IOException { - toProto(obj, output, ProtobufEncodingMode.VERTX_NULLABLE); + toProto(obj, output, ProtobufEncodingMode.VERTX); } public static void toProto(SimplePojo obj, CodedOutputStream output, ProtobufEncodingMode encodingMode) throws IOException { @@ -97,7 +97,7 @@ static int toProto(SimplePojo obj, CodedOutputStream output, ExpandableIntArray } public static int computeSize(SimplePojo obj) { - return computeSize(obj, ProtobufEncodingMode.VERTX_NULLABLE); + return computeSize(obj, ProtobufEncodingMode.VERTX); } public static int computeSize(SimplePojo obj, ProtobufEncodingMode encodingMode) { diff --git a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java index d715ae87a..5eae5c42e 100644 --- a/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java +++ b/vertx-codegen-protobuf/src/converters/generated/io/vertx/test/codegen/converter/UserProtoConverter.java @@ -18,7 +18,7 @@ public class UserProtoConverter { public static void fromProto(CodedInputStream input, User obj) throws IOException { - fromProto(input, obj, ProtobufEncodingMode.VERTX_NULLABLE); + fromProto(input, obj, ProtobufEncodingMode.VERTX); } public static void fromProto(CodedInputStream input, User obj, ProtobufEncodingMode encodingMode) throws IOException { @@ -290,7 +290,7 @@ public static void fromProto(CodedInputStream input, User obj, ProtobufEncodingM } public static void toProto(User obj, CodedOutputStream output) throws IOException { - toProto(obj, output, ProtobufEncodingMode.VERTX_NULLABLE); + toProto(obj, output, ProtobufEncodingMode.VERTX); } public static void toProto(User obj, CodedOutputStream output, ProtobufEncodingMode encodingMode) throws IOException { @@ -584,7 +584,7 @@ static int toProto(User obj, CodedOutputStream output, ExpandableIntArray cache, } public static int computeSize(User obj) { - return computeSize(obj, ProtobufEncodingMode.VERTX_NULLABLE); + return computeSize(obj, ProtobufEncodingMode.VERTX); } public static int computeSize(User obj, ProtobufEncodingMode encodingMode) { diff --git a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/ProtobufEncodingMode.java b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/ProtobufEncodingMode.java index a35b9284c..f8de5156d 100644 --- a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/ProtobufEncodingMode.java +++ b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/ProtobufEncodingMode.java @@ -9,7 +9,7 @@ public enum ProtobufEncodingMode { * (e.g., Integer, Double) and String to be nullable. This encoding mode is intended for use when * communicating with another Vert.x converter that supports nullable values. */ - VERTX_NULLABLE, + VERTX, /** * In this encoding mode, the converter uses the standard protobuf encoding, which is compatible with diff --git a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java index 9303c8755..a02b2ef22 100644 --- a/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java +++ b/vertx-codegen-protobuf/src/main/java/io/vertx/codegen/protobuf/generator/DataObjectProtobufGen.java @@ -91,7 +91,7 @@ public String renderProto(DataObjectModel model, int index, int size, Map