-
Notifications
You must be signed in to change notification settings - Fork 92
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce mechanism for specifying protobuf field numbers
Previously, field numbers were always assigned automatically during protobuf schema generation, based on declaration order of properties in a data class. It is very easy to modify the data class in a way that changes field numbers unintentionally, which introduces a breaking change to the protobuf schema. This commit introduces the annotation `@ProtobufField` as a mechanism for explicitly providing field numbers, as well as a `FieldNumberStrategy` enum (used in `@ProtobufGen.fieldNumberStrategy`) to select how field numbers should be assigned. There's a manual strategy and two automatic strategies. Further, `@ProtobufGen.reservedFieldNumbers` and `reservedFieldNames` allow specifying reserved field numbers / names, similarly to the protobuf language itself. Reserved field numbers and names are verified at compile time. The fields in the protobuf schema are generated in the field number order, not in the property declaration order. The serialization/deserialization code in generated converters also uses field number order. This is to make sure that a Vert.x-generated and `protoc`-generated serializers produce outputs that are not just mutually _compatible_, but also binary _identical_.
- Loading branch information
Showing
19 changed files
with
818 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
...protobuf/src/converters/generated/io/vertx/test/codegen/converter/BookProtoConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
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 BookProtoConverter { | ||
|
||
public static void fromProto(CodedInputStream input, Book obj) throws IOException { | ||
int tag; | ||
while ((tag = input.readTag()) != 0) { | ||
switch (tag) { | ||
case 10: { | ||
obj.setName(input.readString()); | ||
break; | ||
} | ||
case 26: { | ||
obj.setAuthor(input.readString()); | ||
break; | ||
} | ||
case 82: { | ||
obj.setIsbn(input.readString()); | ||
break; | ||
} | ||
case 162: { | ||
obj.setGenre(input.readString()); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
public static void toProto(Book obj, CodedOutputStream output) throws IOException { | ||
ExpandableIntArray cache = new ExpandableIntArray(16); | ||
BookProtoConverter.computeSize(obj, cache, 0); | ||
BookProtoConverter.toProto(obj, output, cache, 0); | ||
} | ||
|
||
public static int toProto(Book obj, CodedOutputStream output, ExpandableIntArray cache, int index) throws IOException { | ||
index = index + 1; | ||
if (obj.getName() != null) { | ||
output.writeString(1, obj.getName()); | ||
} | ||
if (obj.getAuthor() != null) { | ||
output.writeString(3, obj.getAuthor()); | ||
} | ||
if (obj.getIsbn() != null) { | ||
output.writeString(10, obj.getIsbn()); | ||
} | ||
if (obj.getGenre() != null) { | ||
output.writeString(20, obj.getGenre()); | ||
} | ||
return index; | ||
} | ||
|
||
public static int computeSize(Book obj) { | ||
ExpandableIntArray cache = new ExpandableIntArray(16); | ||
BookProtoConverter.computeSize(obj, cache, 0); | ||
return cache.get(0); | ||
} | ||
|
||
public static int computeSize(Book obj, ExpandableIntArray cache, final int baseIndex) { | ||
int size = 0; | ||
int index = baseIndex + 1; | ||
if (obj.getName() != null) { | ||
size += CodedOutputStream.computeStringSize(1, obj.getName()); | ||
} | ||
if (obj.getAuthor() != null) { | ||
size += CodedOutputStream.computeStringSize(3, obj.getAuthor()); | ||
} | ||
if (obj.getIsbn() != null) { | ||
size += CodedOutputStream.computeStringSize(10, obj.getIsbn()); | ||
} | ||
if (obj.getGenre() != null) { | ||
size += CodedOutputStream.computeStringSize(20, obj.getGenre()); | ||
} | ||
cache.set(baseIndex, size); | ||
return index; | ||
} | ||
|
||
} |
71 changes: 71 additions & 0 deletions
71
...otobuf/src/converters/generated/io/vertx/test/codegen/converter/PersonProtoConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
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 PersonProtoConverter { | ||
|
||
public static void fromProto(CodedInputStream input, Person obj) throws IOException { | ||
int tag; | ||
while ((tag = input.readTag()) != 0) { | ||
switch (tag) { | ||
case 18: { | ||
obj.setName(input.readString()); | ||
break; | ||
} | ||
case 32: { | ||
obj.setAge(input.readInt32()); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
public static void toProto(Person obj, CodedOutputStream output) throws IOException { | ||
ExpandableIntArray cache = new ExpandableIntArray(16); | ||
PersonProtoConverter.computeSize(obj, cache, 0); | ||
PersonProtoConverter.toProto(obj, output, cache, 0); | ||
} | ||
|
||
public static int toProto(Person obj, CodedOutputStream output, ExpandableIntArray cache, int index) throws IOException { | ||
index = index + 1; | ||
if (obj.getName() != null) { | ||
output.writeString(2, obj.getName()); | ||
} | ||
if (obj.getAge() != 0) { | ||
output.writeInt32(4, obj.getAge()); | ||
} | ||
return index; | ||
} | ||
|
||
public static int computeSize(Person obj) { | ||
ExpandableIntArray cache = new ExpandableIntArray(16); | ||
PersonProtoConverter.computeSize(obj, cache, 0); | ||
return cache.get(0); | ||
} | ||
|
||
public static int computeSize(Person obj, ExpandableIntArray cache, final int baseIndex) { | ||
int size = 0; | ||
int index = baseIndex + 1; | ||
if (obj.getName() != null) { | ||
size += CodedOutputStream.computeStringSize(2, obj.getName()); | ||
} | ||
if (obj.getAge() != 0) { | ||
size += CodedOutputStream.computeInt32Size(4, obj.getAge()); | ||
} | ||
cache.set(baseIndex, size); | ||
return index; | ||
} | ||
|
||
} |
3 changes: 2 additions & 1 deletion
3
vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/Address.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/Book.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
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.ProtobufField; | ||
import io.vertx.codegen.protobuf.annotations.ProtobufGen; | ||
|
||
import java.util.Objects; | ||
|
||
@DataObject | ||
@ProtobufGen(fieldNumberStrategy = FieldNumberStrategy.SEGMENTED, reservedFieldNumbers = 2, reservedFieldNames = "title") | ||
public class Book { | ||
private String name; | ||
private String author; | ||
@ProtobufField(10) | ||
private String isbn; | ||
@ProtobufField(20) | ||
private String genre; | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public void setName(String name) { | ||
this.name = name; | ||
} | ||
|
||
public String getAuthor() { | ||
return author; | ||
} | ||
|
||
public void setAuthor(String author) { | ||
this.author = author; | ||
} | ||
|
||
public String getIsbn() { | ||
return isbn; | ||
} | ||
|
||
public void setIsbn(String isbn) { | ||
this.isbn = isbn; | ||
} | ||
|
||
public String getGenre() { | ||
return genre; | ||
} | ||
|
||
public void setGenre(String genre) { | ||
this.genre = genre; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
Book book = (Book) o; | ||
return Objects.equals(name, book.name) && Objects.equals(author, book.author) && Objects.equals(isbn, book.isbn) && Objects.equals(genre, book.genre); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(name, author, isbn, genre); | ||
} | ||
} |
4 changes: 3 additions & 1 deletion
4
vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/EnumType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
vertx-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/Person.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
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.ProtobufField; | ||
import io.vertx.codegen.protobuf.annotations.ProtobufGen; | ||
|
||
import java.util.Objects; | ||
|
||
@DataObject | ||
@ProtobufGen(fieldNumberStrategy = FieldNumberStrategy.MANUAL) | ||
public class Person { | ||
@ProtobufField(2) | ||
private String name; | ||
@ProtobufField(4) | ||
private int age; | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public void setName(String name) { | ||
this.name = name; | ||
} | ||
|
||
public int getAge() { | ||
return age; | ||
} | ||
|
||
public void setAge(int age) { | ||
this.age = age; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
Person person = (Person) o; | ||
return Objects.equals(name, person.name) && Objects.equals(age, person.age); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(name, age); | ||
} | ||
} |
3 changes: 2 additions & 1 deletion
3
...x-codegen-protobuf/src/converters/java/io/vertx/test/codegen/converter/RecursiveItem.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.