@Override @SuppressWarnings("unchecked") public Builder set(int key, Object value) { CField field = descriptor.getField(key); if (field == null) { return this; // soft ignoring unsupported fields. } if (value == null) { return clear(key); } this.unionField = field; switch (field.getType()) { case SET: this.currentValue = ((PSet) field.getDescriptor()).builder().addAll((Collection) value); break; case LIST: this.currentValue = ((PList) field.getDescriptor()).builder().addAll((Collection) value); break; case MAP: this.currentValue = ((PMap) field.getDescriptor()).builder().putAll((Map) value); break; default: this.currentValue = value; break; } return this; }
@Override @SuppressWarnings("unchecked") public PMessageBuilder mutator(int key) { CField field = descriptor.getField(key); if (field == null) { throw new IllegalArgumentException("No such unionField ID " + key); } else if (field.getType() != PType.MESSAGE) { throw new IllegalArgumentException( "Not a message unionField ID " + key + ": " + field.getName()); } if (unionField != field) { unionField = field; currentValue = null; } if (currentValue == null) { currentValue = ((PStructDescriptor) field.getDescriptor()).builder(); } else if (currentValue instanceof PMessage) { currentValue = ((PMessage) currentValue).mutate(); } else if (!(currentValue instanceof PMessageBuilder)) { // This should in theory not be possible. This is just a safe-guard. throw new IllegalArgumentException( "Invalid currentValue in map on message type: " + currentValue.getClass().getSimpleName()); } return (PMessageBuilder) currentValue; }
@Override @SuppressWarnings("unchecked") public Builder merge(CUnion from) { if (unionField == null || unionField != from.unionField()) { set(from.unionField.getKey(), from.get(from.unionField.getKey())); } else { int key = unionField.getKey(); switch (unionField.getType()) { case MESSAGE: { PMessage src = (PMessage) currentValue; PMessage toMerge = (PMessage) from.get(key); currentValue = src.mutate().merge(toMerge).build(); break; } case SET: ((PSet.Builder<Object>) currentValue).addAll((Set<Object>) from.get(key)); break; case MAP: ((PMap.Builder<Object, Object>) currentValue) .putAll((Map<Object, Object>) from.get(key)); break; default: set(key, from.get(key)); break; } } return this; }
@Override public Builder clear(int key) { if (unionField != null && unionField.getKey() == key) { this.unionField = null; this.currentValue = null; } return this; }
@Override @SuppressWarnings("unchecked") public Builder addTo(int key, Object value) { CField field = descriptor.getField(key); if (field == null) { return this; // soft ignoring unsupported fields. } if (this.unionField != field || this.currentValue == null) { this.unionField = field; switch (field.getType()) { case LIST: { PList lType = (PList) field.getDescriptor(); this.currentValue = lType.builder(); break; } case SET: { PSet lType = (PSet) field.getDescriptor(); this.currentValue = lType.builder(); break; } default: { throw new IllegalArgumentException( "Unable to accept addTo on non-list unionField " + field.getName()); } } } if (value == null) { throw new IllegalArgumentException("Adding null item to collection " + field.getName()); } switch (field.getType()) { case LIST: { ((PList.Builder) this.currentValue).add(value); break; } case SET: { ((PList.Builder) this.currentValue).add(value); break; } } return this; }
private Map<Integer, Object> getValueMap() { if (unionField == null) { return ImmutableMap.of(); } else if (currentValue == null) { throw new IllegalStateException("Union field set, but value is null."); } else { switch (unionField.getType()) { case LIST: return ImmutableMap.of( unionField.getKey(), ((PList.Builder) this.currentValue).build()); case SET: return ImmutableMap.of(unionField.getKey(), ((PSet.Builder) this.currentValue).build()); case MAP: return ImmutableMap.of(unionField.getKey(), ((PMap.Builder) this.currentValue).build()); case MESSAGE: if (currentValue instanceof PMessageBuilder) { return ImmutableMap.of(unionField.getKey(), ((PMessageBuilder) currentValue).build()); } default: return ImmutableMap.of(unionField.getKey(), this.currentValue); } } }
public void setFields(List<CField> fields) { this.fields = Maps.newHashMap(); for (CField field : fields) { this.fields.put(field.getName(), field); } }