Skip to content

Commit

Permalink
Add includingDefaultValueFields option with specific fields (#29)
Browse files Browse the repository at this point in the history
  • Loading branch information
chokoswitch authored Feb 9, 2024
1 parent a8e4616 commit 49b7c0b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription.ForLoadedType;
Expand Down Expand Up @@ -274,18 +275,21 @@ private enum LocalVariable implements VariableHandle {
private final Class<? extends Message> messageClass;
private final Descriptor descriptor;
private final boolean includeDefaults;
private final Set<FieldDescriptor> fieldsToAlwaysOutput;
private final boolean printingEnumsAsInts;
private final boolean sortingMapKeys;

DoWrite(
Message prototype,
boolean includeDefaults,
Set<FieldDescriptor> fieldsToAlwaysOutput,
boolean printingEnumsAsInts,
boolean sortingMapKeys) {
this.prototype = prototype;
this.messageClass = prototype.getClass();
this.descriptor = prototype.getDescriptorForType();
this.includeDefaults = includeDefaults;
this.fieldsToAlwaysOutput = fieldsToAlwaysOutput;
this.printingEnumsAsInts = printingEnumsAsInts;
this.sortingMapKeys = sortingMapKeys;
}
Expand Down Expand Up @@ -335,7 +339,7 @@ public Size apply(
// if (message.getBarCount() != 0) {
// ...
// }
if (!includeDefaults
if ((!includeDefaults && !fieldsToAlwaysOutput.contains(f))
// Only print one-of fields if they're actually set (the default of a one-of is an empty
// one-of).
|| field.isInOneof()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,21 @@
import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.curioswitch.common.protobuf.json.WellKnownTypeMarshaller.AnyMarshaller;
Expand Down Expand Up @@ -127,6 +131,7 @@ public SerializableString getEscapeSequence(int ch) {
private final MarshallerRegistry registry;

private final boolean includingDefaultValueFields;
private final Set<FieldDescriptor> fieldsToAlwaysOutput;
private final boolean preservingProtoFieldNames;
private final boolean omittingInsignificantWhitespace;
private final boolean ignoringUnknownFields;
Expand All @@ -137,6 +142,7 @@ private MessageMarshaller(
MarshallerRegistry registry,
boolean omittingInsignificantWhitespace,
boolean includingDefaultValueFields,
Set<FieldDescriptor> fieldsToAlwaysOutput,
boolean preservingProtoFieldNames,
boolean ignoringUnknownFields,
boolean printingEnumsAsInts,
Expand All @@ -145,6 +151,7 @@ private MessageMarshaller(
this.registry = registry;
this.omittingInsignificantWhitespace = omittingInsignificantWhitespace;
this.includingDefaultValueFields = includingDefaultValueFields;
this.fieldsToAlwaysOutput = fieldsToAlwaysOutput;
this.preservingProtoFieldNames = preservingProtoFieldNames;
this.ignoringUnknownFields = ignoringUnknownFields;
this.printingEnumsAsInts = printingEnumsAsInts;
Expand Down Expand Up @@ -289,6 +296,7 @@ public Builder toBuilder() {
registry.getBuiltParsers(),
omittingInsignificantWhitespace,
includingDefaultValueFields,
fieldsToAlwaysOutput,
preservingProtoFieldNames,
ignoringUnknownFields,
printingEnumsAsInts,
Expand All @@ -308,6 +316,7 @@ List<? extends Message> registeredPrototypes() {
public static final class Builder {

private boolean includingDefaultValueFields;
private Set<FieldDescriptor> fieldsToAlwaysOutput = Collections.emptySet();
private boolean preservingProtoFieldNames;
private boolean omittingInsignificantWhitespace;
private boolean ignoringUnknownFields;
Expand Down Expand Up @@ -357,11 +366,35 @@ public Builder register(Class<? extends Message> messageClass) {

/**
* Set whether unset fields will be serialized with their default values. Empty repeated fields
* and map fields will be printed as well. The new Printer clones all other configurations from
* the current.
* and map fields will be printed as well.
*/
public Builder includingDefaultValueFields(boolean includingDefaultValueFields) {
this.includingDefaultValueFields = includingDefaultValueFields;
this.fieldsToAlwaysOutput = Collections.emptySet();
return this;
}

/**
* Sets fields which should always be serialized with their default values, even if unset. Empty
* repeated fields and map fields will be printed as well, if they match. Call {@link
* #includingDefaultValueFields} with {@code true} to unconditionally include all fields.
*/
public Builder includingDefaultValueFields(FieldDescriptor... fieldsToAlwaysOutput) {
requireNonNull(fieldsToAlwaysOutput, "fieldsToAlwaysOutput");
includingDefaultValueFields(Arrays.asList(fieldsToAlwaysOutput));
return this;
}

/**
* Sets fields which should always be serialized with their default values, even if unset. Empty
* repeated fields and map fields will be printed as well, if they match. Call {@link
* #includingDefaultValueFields} with {@code true} to unconditionally include all fields.
*/
public Builder includingDefaultValueFields(Iterable<FieldDescriptor> fieldsToAlwaysOutput) {
requireNonNull(fieldsToAlwaysOutput, "fieldsToAlwaysOutput");
this.includingDefaultValueFields = false;
this.fieldsToAlwaysOutput = new HashSet<>();
fieldsToAlwaysOutput.forEach(this.fieldsToAlwaysOutput::add);
return this;
}

Expand Down Expand Up @@ -461,6 +494,7 @@ public MessageMarshaller build() {
TypeSpecificMarshaller.buildAndAdd(
prototype,
includingDefaultValueFields,
fieldsToAlwaysOutput,
preservingProtoFieldNames,
ignoringUnknownFields,
printingEnumsAsInts,
Expand All @@ -475,6 +509,7 @@ public MessageMarshaller build() {
registry,
omittingInsignificantWhitespace,
includingDefaultValueFields,
fieldsToAlwaysOutput,
preservingProtoFieldNames,
ignoringUnknownFields,
printingEnumsAsInts,
Expand All @@ -495,13 +530,15 @@ private Builder() {
Map<Descriptor, TypeSpecificMarshaller<?>> preBuiltParsers,
boolean omittingInsignificantWhitespace,
boolean includingDefaultValueFields,
Set<FieldDescriptor> fieldsToAlwaysOutput,
boolean preservingProtoFieldNames,
boolean ignoringUnknownFields,
boolean printingEnumsAsInts,
boolean sortingMapKeys) {
this.preBuiltParsers = preBuiltParsers;
this.omittingInsignificantWhitespace = omittingInsignificantWhitespace;
this.includingDefaultValueFields = includingDefaultValueFields;
this.fieldsToAlwaysOutput = fieldsToAlwaysOutput;
this.preservingProtoFieldNames = preservingProtoFieldNames;
this.ignoringUnknownFields = ignoringUnknownFields;
this.printingEnumsAsInts = printingEnumsAsInts;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.asm.AsmVisitorWrapper.ForDeclaredMethods;
import net.bytebuddy.description.type.TypeDefinition;
Expand Down Expand Up @@ -133,6 +134,7 @@ T getMarshalledPrototype() {
static <T extends Message> void buildAndAdd(
T prototype,
boolean includingDefaultValueFields,
Set<FieldDescriptor> fieldsToAlwaysOutput,
boolean preservingProtoFieldNames,
boolean ignoringUnknownFields,
boolean printingEnumsAsInts,
Expand All @@ -144,6 +146,7 @@ static <T extends Message> void buildAndAdd(
buildOrFindMarshaller(
prototype,
includingDefaultValueFields,
fieldsToAlwaysOutput,
preservingProtoFieldNames,
ignoringUnknownFields,
printingEnumsAsInts,
Expand Down Expand Up @@ -177,6 +180,7 @@ static <T extends Message> void buildAndAdd(
private static <T extends Message> void buildOrFindMarshaller(
T prototype,
boolean includingDefaultValueFields,
Set<FieldDescriptor> fieldsToAlwaysOutput,
boolean preservingProtoFieldNames,
boolean ignoringUnknownFields,
boolean printingEnumsAsInts,
Expand Down Expand Up @@ -254,7 +258,11 @@ private static <T extends Message> void buildOrFindMarshaller(
.throwing(IOException.class)
.intercept(
new DoWrite(
prototype, includingDefaultValueFields, printingEnumsAsInts, sortingMapKeys));
prototype,
includingDefaultValueFields,
fieldsToAlwaysOutput,
printingEnumsAsInts,
sortingMapKeys));
try {
marshaller =
buddy
Expand All @@ -278,6 +286,7 @@ private static <T extends Message> void buildOrFindMarshaller(
buildOrFindMarshaller(
nestedPrototype,
includingDefaultValueFields,
fieldsToAlwaysOutput,
preservingProtoFieldNames,
ignoringUnknownFields,
printingEnumsAsInts,
Expand Down

0 comments on commit 49b7c0b

Please sign in to comment.