| // Copyright (C) 2018 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package com.google.gerrit.entities.converter; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.errorprone.annotations.Immutable; |
| import com.google.gerrit.entities.Account; |
| import com.google.gerrit.entities.PatchSet; |
| import com.google.gerrit.proto.Entities; |
| import com.google.protobuf.Parser; |
| import java.time.Instant; |
| import org.eclipse.jgit.lib.ObjectId; |
| |
| @Immutable |
| public enum PatchSetProtoConverter implements SafeProtoConverter<Entities.PatchSet, PatchSet> { |
| INSTANCE; |
| |
| private final ProtoConverter<Entities.PatchSet_Id, PatchSet.Id> patchSetIdConverter = |
| PatchSetIdProtoConverter.INSTANCE; |
| private final ProtoConverter<Entities.ObjectId, ObjectId> objectIdConverter = |
| ObjectIdProtoConverter.INSTANCE; |
| private final ProtoConverter<Entities.Account_Id, Account.Id> accountIdConverter = |
| AccountIdProtoConverter.INSTANCE; |
| |
| @Override |
| public Entities.PatchSet toProto(PatchSet patchSet) { |
| Entities.PatchSet.Builder builder = |
| Entities.PatchSet.newBuilder() |
| .setId(patchSetIdConverter.toProto(patchSet.id())) |
| .setCommitId(objectIdConverter.toProto(patchSet.commitId())) |
| .setUploaderAccountId(accountIdConverter.toProto(patchSet.uploader())) |
| .setRealUploaderAccountId(accountIdConverter.toProto(patchSet.realUploader())) |
| .setCreatedOn(patchSet.createdOn().toEpochMilli()); |
| patchSet.branch().ifPresent(builder::setBranch); |
| ImmutableList<String> groups = patchSet.groups(); |
| if (!groups.isEmpty()) { |
| builder.setGroups(PatchSet.joinGroups(groups)); |
| } |
| patchSet.pushCertificate().ifPresent(builder::setPushCertificate); |
| patchSet.description().ifPresent(builder::setDescription); |
| return builder.build(); |
| } |
| |
| @Override |
| public PatchSet fromProto(Entities.PatchSet proto) { |
| PatchSet.Builder builder = |
| PatchSet.builder() |
| .id(patchSetIdConverter.fromProto(proto.getId())) |
| .groups( |
| proto.hasGroups() ? PatchSet.splitGroups(proto.getGroups()) : ImmutableList.of()); |
| if (proto.hasPushCertificate()) { |
| builder.pushCertificate(proto.getPushCertificate()); |
| } |
| if (proto.hasDescription()) { |
| builder.description(proto.getDescription()); |
| } |
| if (proto.hasBranch()) { |
| builder.branch(proto.getBranch()); |
| } |
| |
| // The following fields used to theoretically be nullable in PatchSet, but in practice no |
| // production codepath should have ever serialized an instance that was missing one of these |
| // fields. |
| // |
| // However, since some protos may theoretically be missing these fields, we need to support |
| // them. Populate specific sentinel values for each field as documented in the PatchSet javadoc. |
| // Callers that encounter one of these sentinels will likely fail, for example by failing to |
| // look up the zeroId. They would have also failed back when the fields were nullable, for |
| // example with NPE; the current behavior just fails slightly differently. |
| Account.Id uploader = |
| proto.hasUploaderAccountId() |
| ? accountIdConverter.fromProto(proto.getUploaderAccountId()) |
| : Account.id(0); |
| builder |
| .commitId( |
| proto.hasCommitId() |
| ? objectIdConverter.fromProto(proto.getCommitId()) |
| : ObjectId.zeroId()) |
| .uploader(uploader) |
| .realUploader( |
| proto.hasRealUploaderAccountId() |
| ? accountIdConverter.fromProto(proto.getRealUploaderAccountId()) |
| : uploader) |
| .createdOn( |
| proto.hasCreatedOn() ? Instant.ofEpochMilli(proto.getCreatedOn()) : Instant.EPOCH); |
| |
| return builder.build(); |
| } |
| |
| @Override |
| public Parser<Entities.PatchSet> getParser() { |
| return Entities.PatchSet.parser(); |
| } |
| |
| @Override |
| public Class<Entities.PatchSet> getProtoClass() { |
| return Entities.PatchSet.class; |
| } |
| |
| @Override |
| public Class<PatchSet> getEntityClass() { |
| return PatchSet.class; |
| } |
| } |