[tor-commits] [metrics-lib/master] Use Java 7's switch-on-String wherever possible.

karsten at torproject.org karsten at torproject.org
Fri Dec 25 09:02:44 UTC 2015


commit 2b4d7732f65a8d030f7b747ed9931e5541956332
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date:   Tue Dec 22 12:55:44 2015 +0100

    Use Java 7's switch-on-String wherever possible.
    
    Rather than writing chained if-else statements with String comparison
    for equals(), we can now switch on a String instance.
    
    Suggested by iwakeh, implements #17824.
---
 .../descriptor/DescriptorSourceFactory.java        |   13 +-
 .../descriptor/impl/BridgeNetworkStatusImpl.java   |   51 +++--
 .../impl/DirectoryKeyCertificateImpl.java          |   95 ++++----
 .../descriptor/impl/ExtraInfoDescriptorImpl.java   |  228 ++++++++++++--------
 .../descriptor/impl/MicrodescriptorImpl.java       |   74 ++++---
 .../descriptor/impl/NetworkStatusEntryImpl.java    |   38 ++--
 .../descriptor/impl/RelayDirectoryImpl.java        |   75 ++++---
 .../impl/RelayNetworkStatusConsensusImpl.java      |   73 ++++---
 .../descriptor/impl/RelayNetworkStatusImpl.java    |   80 ++++---
 .../impl/RelayNetworkStatusVoteImpl.java           |  127 +++++++----
 .../descriptor/impl/ServerDescriptorImpl.java      |  199 ++++++++++-------
 .../descriptor/impl/TorperfResultImpl.java         |   87 +++++---
 12 files changed, 700 insertions(+), 440 deletions(-)

diff --git a/src/org/torproject/descriptor/DescriptorSourceFactory.java b/src/org/torproject/descriptor/DescriptorSourceFactory.java
index 49fcdc6..8bab13e 100644
--- a/src/org/torproject/descriptor/DescriptorSourceFactory.java
+++ b/src/org/torproject/descriptor/DescriptorSourceFactory.java
@@ -53,14 +53,19 @@ public final class DescriptorSourceFactory {
     Object object;
     String clazzName = null;
     try {
-      if (PARSER_PROPERTY.equals(type)) {
+      switch (type) {
+      case PARSER_PROPERTY:
         clazzName = System.getProperty(type, PARSER_DEFAULT);
-      } else if (LOADER_PROPERTY.equals(type)) {
+        break;
+      case LOADER_PROPERTY:
         clazzName = System.getProperty(type, LOADER_DEFAULT);
-      } else if (READER_PROPERTY.equals(type)) {
+        break;
+      case READER_PROPERTY:
         clazzName = System.getProperty(type, READER_DEFAULT);
-      } else if (COLLECTOR_PROPERTY.equals(type)) {
+        break;
+      case COLLECTOR_PROPERTY:
         clazzName = System.getProperty(type, COLLECTOR_DEFAULT);
+        break;
       }
       object = ClassLoader.getSystemClassLoader().loadClass(clazzName).
           newInstance();
diff --git a/src/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java b/src/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java
index d5e6d8f..fcc9b64 100644
--- a/src/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java
+++ b/src/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java
@@ -73,18 +73,23 @@ public class BridgeNetworkStatusImpl extends NetworkStatusImpl
       String line = s.next();
       String[] parts = line.split("[ \t]+");
       String keyword = parts[0];
-      if (keyword.equals("published")) {
+      switch (keyword) {
+      case "published":
         this.parsePublishedLine(line, parts);
-      } else if (keyword.equals("flag-thresholds")) {
+        break;
+      case "flag-thresholds":
         this.parseFlagThresholdsLine(line, parts);
-      } else if (this.failUnrecognizedDescriptorLines) {
-        throw new DescriptorParseException("Unrecognized line '" + line
-            + "' in bridge network status.");
-      } else {
-        if (this.unrecognizedLines == null) {
-          this.unrecognizedLines = new ArrayList<>();
+        break;
+      default:
+        if (this.failUnrecognizedDescriptorLines) {
+          throw new DescriptorParseException("Unrecognized line '" + line
+              + "' in bridge network status.");
+        } else {
+          if (this.unrecognizedLines == null) {
+            this.unrecognizedLines = new ArrayList<>();
+          }
+          this.unrecognizedLines.add(line);
         }
-        this.unrecognizedLines.add(line);
       }
     }
   }
@@ -105,27 +110,37 @@ public class BridgeNetworkStatusImpl extends NetworkStatusImpl
         ParseHelper.parseKeyValueStringPairs(line, parts, 1, "=");
     try {
       for (Map.Entry<String, String> e : flagThresholds.entrySet()) {
-        if (e.getKey().equals("stable-uptime")) {
+        switch (e.getKey()) {
+        case "stable-uptime":
           this.stableUptime = Long.parseLong(e.getValue());
-        } else if (e.getKey().equals("stable-mtbf")) {
+          break;
+        case "stable-mtbf":
           this.stableMtbf = Long.parseLong(e.getValue());
-        } else if (e.getKey().equals("fast-speed")) {
+          break;
+        case "fast-speed":
           this.fastBandwidth = Long.parseLong(e.getValue());
-        } else if (e.getKey().equals("guard-wfu")) {
+          break;
+        case "guard-wfu":
           this.guardWfu = Double.parseDouble(e.getValue().
               replaceAll("%", ""));
-        } else if (e.getKey().equals("guard-tk")) {
+          break;
+        case "guard-tk":
           this.guardTk = Long.parseLong(e.getValue());
-        } else if (e.getKey().equals("guard-bw-inc-exits")) {
+          break;
+        case "guard-bw-inc-exits":
           this.guardBandwidthIncludingExits =
               Long.parseLong(e.getValue());
-        } else if (e.getKey().equals("guard-bw-exc-exits")) {
+          break;
+        case "guard-bw-exc-exits":
           this.guardBandwidthExcludingExits =
               Long.parseLong(e.getValue());
-        } else if (e.getKey().equals("enough-mtbf")) {
+          break;
+        case "enough-mtbf":
           this.enoughMtbfInfo = Integer.parseInt(e.getValue());
-        } else if (e.getKey().equals("ignoring-advertised-bws")) {
+          break;
+        case "ignoring-advertised-bws":
           this.ignoringAdvertisedBws = Integer.parseInt(e.getValue());
+          break;
         }
       }
     } catch (NumberFormatException ex) {
diff --git a/src/org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java b/src/org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java
index 152ffeb..fcbf3f7 100644
--- a/src/org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java
+++ b/src/org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java
@@ -60,65 +60,82 @@ public class DirectoryKeyCertificateImpl extends DescriptorImpl
   private void parseDescriptorBytes() throws DescriptorParseException {
     Scanner s = new Scanner(new String(this.rawDescriptorBytes)).
         useDelimiter("\n");
-    String nextCrypto = null;
+    String nextCrypto = "";
     StringBuilder crypto = null;
     while (s.hasNext()) {
       String line = s.next();
       String[] parts = line.split("[ \t]+");
       String keyword = parts[0];
-      if (keyword.equals("dir-key-certificate-version")) {
+      switch (keyword) {
+      case "dir-key-certificate-version":
         this.parseDirKeyCertificateVersionLine(line, parts);
-      } else if (keyword.equals("dir-address")) {
+        break;
+      case "dir-address":
         this.parseDirAddressLine(line, parts);
-      } else if (keyword.equals("fingerprint")) {
+        break;
+      case "fingerprint":
         this.parseFingerprintLine(line, parts);
-      } else if (keyword.equals("dir-identity-key")) {
+        break;
+      case "dir-identity-key":
         this.parseDirIdentityKeyLine(line, parts);
         nextCrypto = "dir-identity-key";
-      } else if (keyword.equals("dir-key-published")) {
+        break;
+      case "dir-key-published":
         this.parseDirKeyPublishedLine(line, parts);
-      } else if (keyword.equals("dir-key-expires")) {
+        break;
+      case "dir-key-expires":
         this.parseDirKeyExpiresLine(line, parts);
-      } else if (keyword.equals("dir-signing-key")) {
+        break;
+      case "dir-signing-key":
         this.parseDirSigningKeyLine(line, parts);
         nextCrypto = "dir-signing-key";
-      } else if (keyword.equals("dir-key-crosscert")) {
+        break;
+      case "dir-key-crosscert":
         this.parseDirKeyCrosscertLine(line, parts);
         nextCrypto = "dir-key-crosscert";
-      } else if (keyword.equals("dir-key-certification")) {
+        break;
+      case "dir-key-certification":
         this.parseDirKeyCertificationLine(line, parts);
         nextCrypto = "dir-key-certification";
-      } else if (line.startsWith("-----BEGIN")) {
-        crypto = new StringBuilder();
-        crypto.append(line + "\n");
-      } else if (line.startsWith("-----END")) {
-        crypto.append(line + "\n");
-        String cryptoString = crypto.toString();
-        crypto = null;
-        if (nextCrypto.equals("dir-identity-key")) {
-          this.dirIdentityKey = cryptoString;
-        } else if (nextCrypto.equals("dir-signing-key")) {
-          this.dirSigningKey = cryptoString;
-        } else if (nextCrypto.equals("dir-key-crosscert")) {
-          this.dirKeyCrosscert = cryptoString;
-        } else if (nextCrypto.equals("dir-key-certification")) {
-          this.dirKeyCertification = cryptoString;
-        } else {
-          throw new DescriptorParseException("Unrecognized crypto "
-              + "block in directory key certificate.");
-        }
-        nextCrypto = null;
-      } else if (crypto != null) {
-        crypto.append(line + "\n");
-      } else {
-        if (this.failUnrecognizedDescriptorLines) {
-          throw new DescriptorParseException("Unrecognized line '"
-              + line + "' in directory key certificate.");
+        break;
+      default:
+        if (line.startsWith("-----BEGIN")) {
+          crypto = new StringBuilder();
+          crypto.append(line + "\n");
+        } else if (line.startsWith("-----END")) {
+          crypto.append(line + "\n");
+          String cryptoString = crypto.toString();
+          crypto = null;
+          switch (nextCrypto) {
+          case "dir-identity-key":
+            this.dirIdentityKey = cryptoString;
+            break;
+          case "dir-signing-key":
+            this.dirSigningKey = cryptoString;
+            break;
+          case "dir-key-crosscert":
+            this.dirKeyCrosscert = cryptoString;
+            break;
+          case "dir-key-certification":
+            this.dirKeyCertification = cryptoString;
+            break;
+          default:
+            throw new DescriptorParseException("Unrecognized crypto "
+                + "block in directory key certificate.");
+          }
+          nextCrypto = "";
+        } else if (crypto != null) {
+          crypto.append(line + "\n");
         } else {
-          if (this.unrecognizedLines == null) {
-            this.unrecognizedLines = new ArrayList<>();
+          if (this.failUnrecognizedDescriptorLines) {
+            throw new DescriptorParseException("Unrecognized line '"
+                + line + "' in directory key certificate.");
+          } else {
+            if (this.unrecognizedLines == null) {
+              this.unrecognizedLines = new ArrayList<>();
+            }
+            this.unrecognizedLines.add(line);
           }
-          this.unrecognizedLines.add(line);
         }
       }
     }
diff --git a/src/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java b/src/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
index ff8df51..36ff269 100644
--- a/src/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
+++ b/src/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
@@ -79,7 +79,7 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
   private void parseDescriptorBytes() throws DescriptorParseException {
     Scanner s = new Scanner(new String(this.rawDescriptorBytes)).
         useDelimiter("\n");
-    String nextCrypto = null;
+    String nextCrypto = "";
     List<String> cryptoLines = null;
     while (s.hasNext()) {
       String line = s.next();
@@ -87,145 +87,203 @@ public abstract class ExtraInfoDescriptorImpl extends DescriptorImpl
           line.substring("opt ".length()) : line;
       String[] partsNoOpt = lineNoOpt.split("[ \t]+");
       String keyword = partsNoOpt[0];
-      if (keyword.equals("extra-info")) {
+      switch (keyword) {
+      case "extra-info":
         this.parseExtraInfoLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("published")) {
+        break;
+      case "published":
         this.parsePublishedLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("read-history")) {
+        break;
+      case "read-history":
         this.parseReadHistoryLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("write-history")) {
+        break;
+      case "write-history":
         this.parseWriteHistoryLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("geoip-db-digest")) {
+        break;
+      case "geoip-db-digest":
         this.parseGeoipDbDigestLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("geoip6-db-digest")) {
+        break;
+      case "geoip6-db-digest":
         this.parseGeoip6DbDigestLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("geoip-start-time")) {
+        break;
+      case "geoip-start-time":
         this.parseGeoipStartTimeLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("geoip-client-origins")) {
+        break;
+      case "geoip-client-origins":
         this.parseGeoipClientOriginsLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("dirreq-stats-end")) {
+        break;
+      case "dirreq-stats-end":
         this.parseDirreqStatsEndLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("dirreq-v2-ips")) {
+        break;
+      case "dirreq-v2-ips":
         this.parseDirreqV2IpsLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("dirreq-v3-ips")) {
+        break;
+      case "dirreq-v3-ips":
         this.parseDirreqV3IpsLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("dirreq-v2-reqs")) {
+        break;
+      case "dirreq-v2-reqs":
         this.parseDirreqV2ReqsLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("dirreq-v3-reqs")) {
+        break;
+      case "dirreq-v3-reqs":
         this.parseDirreqV3ReqsLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("dirreq-v2-share")) {
+        break;
+      case "dirreq-v2-share":
         this.parseDirreqV2ShareLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("dirreq-v3-share")) {
+        break;
+      case "dirreq-v3-share":
         this.parseDirreqV3ShareLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("dirreq-v2-resp")) {
+        break;
+      case "dirreq-v2-resp":
         this.parseDirreqV2RespLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("dirreq-v3-resp")) {
+        break;
+      case "dirreq-v3-resp":
         this.parseDirreqV3RespLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("dirreq-v2-direct-dl")) {
+        break;
+      case "dirreq-v2-direct-dl":
         this.parseDirreqV2DirectDlLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("dirreq-v3-direct-dl")) {
+        break;
+      case "dirreq-v3-direct-dl":
         this.parseDirreqV3DirectDlLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("dirreq-v2-tunneled-dl")) {
+        break;
+      case "dirreq-v2-tunneled-dl":
         this.parseDirreqV2TunneledDlLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("dirreq-v3-tunneled-dl")) {
+        break;
+      case "dirreq-v3-tunneled-dl":
         this.parseDirreqV3TunneledDlLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("dirreq-read-history")) {
+        break;
+      case "dirreq-read-history":
         this.parseDirreqReadHistoryLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("dirreq-write-history")) {
+        break;
+      case "dirreq-write-history":
         this.parseDirreqWriteHistoryLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("entry-stats-end")) {
+        break;
+      case "entry-stats-end":
         this.parseEntryStatsEndLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("entry-ips")) {
+        break;
+      case "entry-ips":
         this.parseEntryIpsLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("cell-stats-end")) {
+        break;
+      case "cell-stats-end":
         this.parseCellStatsEndLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("cell-processed-cells")) {
+        break;
+      case "cell-processed-cells":
         this.parseCellProcessedCellsLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("cell-queued-cells")) {
+        break;
+      case "cell-queued-cells":
         this.parseCellQueuedCellsLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("cell-time-in-queue")) {
+        break;
+      case "cell-time-in-queue":
         this.parseCellTimeInQueueLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("cell-circuits-per-decile")) {
+        break;
+      case "cell-circuits-per-decile":
         this.parseCellCircuitsPerDecileLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("conn-bi-direct")) {
+        break;
+      case "conn-bi-direct":
         this.parseConnBiDirectLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("exit-stats-end")) {
+        break;
+      case "exit-stats-end":
         this.parseExitStatsEndLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("exit-kibibytes-written")) {
+        break;
+      case "exit-kibibytes-written":
         this.parseExitKibibytesWrittenLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("exit-kibibytes-read")) {
+        break;
+      case "exit-kibibytes-read":
         this.parseExitKibibytesReadLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("exit-streams-opened")) {
+        break;
+      case "exit-streams-opened":
         this.parseExitStreamsOpenedLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("bridge-stats-end")) {
+        break;
+      case "bridge-stats-end":
         this.parseBridgeStatsEndLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("bridge-ips")) {
+        break;
+      case "bridge-ips":
         this.parseBridgeStatsIpsLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("bridge-ip-versions")) {
+        break;
+      case "bridge-ip-versions":
         this.parseBridgeIpVersionsLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("bridge-ip-transports")) {
+        break;
+      case "bridge-ip-transports":
         this.parseBridgeIpTransportsLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("transport")) {
+        break;
+      case "transport":
         this.parseTransportLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("hidserv-stats-end")) {
+        break;
+      case "hidserv-stats-end":
         this.parseHidservStatsEndLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("hidserv-rend-relayed-cells")) {
+        break;
+      case "hidserv-rend-relayed-cells":
         this.parseHidservRendRelayedCellsLine(line, lineNoOpt,
             partsNoOpt);
-      } else if (keyword.equals("hidserv-dir-onions-seen")) {
+        break;
+      case "hidserv-dir-onions-seen":
         this.parseHidservDirOnionsSeenLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("identity-ed25519")) {
+        break;
+      case "identity-ed25519":
         this.parseIdentityEd25519Line(line, lineNoOpt, partsNoOpt);
         nextCrypto = "identity-ed25519";
-      } else if (keyword.equals("master-key-ed25519")) {
+        break;
+      case "master-key-ed25519":
         this.parseMasterKeyEd25519Line(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("router-sig-ed25519")) {
+        break;
+      case "router-sig-ed25519":
         this.parseRouterSigEd25519Line(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("router-signature")) {
+        break;
+      case "router-signature":
         this.parseRouterSignatureLine(line, lineNoOpt, partsNoOpt);
         nextCrypto = "router-signature";
-      } else if (keyword.equals("router-digest")) {
+        break;
+      case "router-digest":
         this.parseRouterDigestLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("router-digest-sha256")) {
+        break;
+      case "router-digest-sha256":
         this.parseRouterDigestSha256Line(line, lineNoOpt, partsNoOpt);
-      } else if (line.startsWith("-----BEGIN")) {
-        cryptoLines = new ArrayList<>();
-        cryptoLines.add(line);
-      } else if (line.startsWith("-----END")) {
-        cryptoLines.add(line);
-        StringBuilder sb = new StringBuilder();
-        for (String cryptoLine : cryptoLines) {
-          sb.append("\n" + cryptoLine);
-        }
-        String cryptoString = sb.toString().substring(1);
-        if ("router-signature".equals(nextCrypto)) {
-          this.routerSignature = cryptoString;
-        } else if ("identity-ed25519".equals(nextCrypto)) {
-          this.identityEd25519 = cryptoString;
-          this.parseIdentityEd25519CryptoBlock(cryptoString);
-        } else if (this.failUnrecognizedDescriptorLines) {
-          throw new DescriptorParseException("Unrecognized crypto "
-              + "block '" + cryptoString + "' in extra-info descriptor.");
-        } else {
-          if (this.unrecognizedLines == null) {
-            this.unrecognizedLines = new ArrayList<>();
+        break;
+      default:
+        if (line.startsWith("-----BEGIN")) {
+          cryptoLines = new ArrayList<>();
+          cryptoLines.add(line);
+        } else if (line.startsWith("-----END")) {
+          cryptoLines.add(line);
+          StringBuilder sb = new StringBuilder();
+          for (String cryptoLine : cryptoLines) {
+            sb.append("\n" + cryptoLine);
           }
-          this.unrecognizedLines.addAll(cryptoLines);
-        }
-        cryptoLines = null;
-        nextCrypto = null;
-      } else if (cryptoLines != null) {
-        cryptoLines.add(line);
-      } else {
-        ParseHelper.parseKeyword(line, partsNoOpt[0]);
-        if (this.failUnrecognizedDescriptorLines) {
-          throw new DescriptorParseException("Unrecognized line '"
-              + line + "' in extra-info descriptor.");
+          String cryptoString = sb.toString().substring(1);
+          switch (nextCrypto) {
+          case "router-signature":
+            this.routerSignature = cryptoString;
+            break;
+          case "identity-ed25519":
+            this.identityEd25519 = cryptoString;
+            this.parseIdentityEd25519CryptoBlock(cryptoString);
+            break;
+          default:
+            if (this.failUnrecognizedDescriptorLines) {
+              throw new DescriptorParseException("Unrecognized crypto "
+                  + "block '" + cryptoString + "' in extra-info "
+                  + "descriptor.");
+            } else {
+              if (this.unrecognizedLines == null) {
+                this.unrecognizedLines = new ArrayList<>();
+              }
+              this.unrecognizedLines.addAll(cryptoLines);
+            }
+          }
+          cryptoLines = null;
+          nextCrypto = "";
+        } else if (cryptoLines != null) {
+          cryptoLines.add(line);
         } else {
-          if (this.unrecognizedLines == null) {
-            this.unrecognizedLines = new ArrayList<>();
+          ParseHelper.parseKeyword(line, partsNoOpt[0]);
+          if (this.failUnrecognizedDescriptorLines) {
+            throw new DescriptorParseException("Unrecognized line '"
+                + line + "' in extra-info descriptor.");
+          } else {
+            if (this.unrecognizedLines == null) {
+              this.unrecognizedLines = new ArrayList<>();
+            }
+            this.unrecognizedLines.add(line);
           }
-          this.unrecognizedLines.add(line);
         }
       }
     }
diff --git a/src/org/torproject/descriptor/impl/MicrodescriptorImpl.java b/src/org/torproject/descriptor/impl/MicrodescriptorImpl.java
index 3e7f466..a70493d 100644
--- a/src/org/torproject/descriptor/impl/MicrodescriptorImpl.java
+++ b/src/org/torproject/descriptor/impl/MicrodescriptorImpl.java
@@ -57,7 +57,7 @@ public class MicrodescriptorImpl extends DescriptorImpl
   private void parseDescriptorBytes() throws DescriptorParseException {
     Scanner s = new Scanner(new String(this.rawDescriptorBytes)).
         useDelimiter("\n");
-    String nextCrypto = null;
+    String nextCrypto = "";
     StringBuilder crypto = null;
     while (s.hasNext()) {
       String line = s.next();
@@ -66,47 +66,57 @@ public class MicrodescriptorImpl extends DescriptorImpl
       }
       String[] parts = line.split("[ \t]+");
       String keyword = parts[0];
-      if (keyword.equals("onion-key")) {
+      switch (keyword) {
+      case "onion-key":
         this.parseOnionKeyLine(line, parts);
         nextCrypto = "onion-key";
-      } else if (keyword.equals("ntor-onion-key")) {
+        break;
+      case "ntor-onion-key":
         this.parseNtorOnionKeyLine(line, parts);
-      } else if (keyword.equals("a")) {
+        break;
+      case "a":
         this.parseALine(line, parts);
-      } else if (keyword.equals("family")) {
+        break;
+      case "family":
         this.parseFamilyLine(line, parts);
-      } else if (keyword.equals("p")) {
+        break;
+      case "p":
         this.parsePLine(line, parts);
-      } else if (keyword.equals("p6")) {
+        break;
+      case "p6":
         this.parseP6Line(line, parts);
-      } else if (keyword.equals("id")) {
+        break;
+      case "id":
         this.parseIdLine(line, parts);
-      } else if (line.startsWith("-----BEGIN")) {
-        crypto = new StringBuilder();
-        crypto.append(line + "\n");
-      } else if (line.startsWith("-----END")) {
-        crypto.append(line + "\n");
-        String cryptoString = crypto.toString();
-        crypto = null;
-        if (nextCrypto.equals("onion-key")) {
-          this.onionKey = cryptoString;
-        } else {
-          throw new DescriptorParseException("Unrecognized crypto "
-              + "block in microdescriptor.");
-        }
-        nextCrypto = null;
-      } else if (crypto != null) {
-        crypto.append(line + "\n");
-      } else {
-        ParseHelper.parseKeyword(line, parts[0]);
-        if (this.failUnrecognizedDescriptorLines) {
-          throw new DescriptorParseException("Unrecognized line '"
-              + line + "' in microdescriptor.");
+        break;
+      default:
+        if (line.startsWith("-----BEGIN")) {
+          crypto = new StringBuilder();
+          crypto.append(line + "\n");
+        } else if (line.startsWith("-----END")) {
+          crypto.append(line + "\n");
+          String cryptoString = crypto.toString();
+          crypto = null;
+          if (nextCrypto.equals("onion-key")) {
+            this.onionKey = cryptoString;
+          } else {
+            throw new DescriptorParseException("Unrecognized crypto "
+                + "block in microdescriptor.");
+          }
+          nextCrypto = "";
+        } else if (crypto != null) {
+          crypto.append(line + "\n");
         } else {
-          if (this.unrecognizedLines == null) {
-            this.unrecognizedLines = new ArrayList<>();
+          ParseHelper.parseKeyword(line, parts[0]);
+          if (this.failUnrecognizedDescriptorLines) {
+            throw new DescriptorParseException("Unrecognized line '"
+                + line + "' in microdescriptor.");
+          } else {
+            if (this.unrecognizedLines == null) {
+              this.unrecognizedLines = new ArrayList<>();
+            }
+            this.unrecognizedLines.add(line);
           }
-          this.unrecognizedLines.add(line);
         }
       }
     }
diff --git a/src/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java b/src/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java
index 4f2b69b..c5f0704 100644
--- a/src/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java
+++ b/src/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java
@@ -79,28 +79,38 @@ public class NetworkStatusEntryImpl implements NetworkStatusEntry {
       String[] parts = !line.startsWith("opt ") ? line.split("[ \t]+") :
           line.substring("opt ".length()).split("[ \t]+");
       String keyword = parts[0];
-      if (keyword.equals("a")) {
+      switch (keyword) {
+      case "a":
         this.parseALine(line, parts);
-      } else if (keyword.equals("s")) {
+        break;
+      case "s":
         this.parseSLine(line, parts);
-      } else if (keyword.equals("v")) {
+        break;
+      case "v":
         this.parseVLine(line, parts);
-      } else if (keyword.equals("w")) {
+        break;
+      case "w":
         this.parseWLine(line, parts);
-      } else if (keyword.equals("p")) {
+        break;
+      case "p":
         this.parsePLine(line, parts);
-      } else if (keyword.equals("m")) {
+        break;
+      case "m":
         this.parseMLine(line, parts);
-      } else if (keyword.equals("id")) {
+        break;
+      case "id":
         this.parseIdLine(line, parts);
-      } else if (this.failUnrecognizedDescriptorLines) {
-        throw new DescriptorParseException("Unrecognized line '" + line
-            + "' in status entry.");
-      } else {
-        if (this.unrecognizedLines == null) {
-          this.unrecognizedLines = new ArrayList<>();
+        break;
+      default:
+        if (this.failUnrecognizedDescriptorLines) {
+          throw new DescriptorParseException("Unrecognized line '" + line
+              + "' in status entry.");
+        } else {
+          if (this.unrecognizedLines == null) {
+            this.unrecognizedLines = new ArrayList<>();
+          }
+          this.unrecognizedLines.add(line);
         }
-        this.unrecognizedLines.add(line);
       }
     }
   }
diff --git a/src/org/torproject/descriptor/impl/RelayDirectoryImpl.java b/src/org/torproject/descriptor/impl/RelayDirectoryImpl.java
index 0b82328..4d583aa 100644
--- a/src/org/torproject/descriptor/impl/RelayDirectoryImpl.java
+++ b/src/org/torproject/descriptor/impl/RelayDirectoryImpl.java
@@ -189,7 +189,7 @@ public class RelayDirectoryImpl extends DescriptorImpl
   private void parseHeader(byte[] headerBytes)
       throws DescriptorParseException {
     Scanner s = new Scanner(new String(headerBytes)).useDelimiter("\n");
-    String publishedLine = null, nextCrypto = null,
+    String publishedLine = null, nextCrypto = "",
         runningRoutersLine = null, routerStatusLine = null;
     StringBuilder crypto = null;
     while (s.hasNext()) {
@@ -201,9 +201,11 @@ public class RelayDirectoryImpl extends DescriptorImpl
           line.substring("opt ".length()) : line;
       String[] partsNoOpt = lineNoOpt.split("[ \t]+");
       String keyword = partsNoOpt[0];
-      if (keyword.equals("signed-directory")) {
+      switch (keyword) {
+      case "signed-directory":
         this.parseSignedDirectoryLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("published")) {
+        break;
+      case "published":
         if (publishedLine != null) {
           throw new DescriptorParseException("Keyword 'published' is "
               + "contained more than once, but must be contained exactly "
@@ -211,41 +213,48 @@ public class RelayDirectoryImpl extends DescriptorImpl
         } else {
           publishedLine = line;
         }
-      } else if (keyword.equals("dir-signing-key")) {
+        break;
+      case "dir-signing-key":
         this.parseDirSigningKeyLine(line, lineNoOpt, partsNoOpt);
         nextCrypto = "dir-signing-key";
-      } else if (keyword.equals("recommended-software")) {
+        break;
+      case "recommended-software":
         this.parseRecommendedSoftwareLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("running-routers")) {
+        break;
+      case "running-routers":
         runningRoutersLine = line;
-      } else if (keyword.equals("router-status")) {
+        break;
+      case "router-status":
         routerStatusLine = line;
-      } else if (line.startsWith("-----BEGIN")) {
-        crypto = new StringBuilder();
-        crypto.append(line + "\n");
-      } else if (line.startsWith("-----END")) {
-        crypto.append(line + "\n");
-        String cryptoString = crypto.toString();
-        crypto = null;
-        if (nextCrypto.equals("dir-signing-key") &&
-            this.dirSigningKey == null) {
-          this.dirSigningKey = cryptoString;
-        } else {
-          throw new DescriptorParseException("Unrecognized crypto "
-              + "block in v1 directory.");
-        }
-        nextCrypto = null;
-      } else if (crypto != null) {
-        crypto.append(line + "\n");
-      } else {
-        if (this.failUnrecognizedDescriptorLines) {
-          throw new DescriptorParseException("Unrecognized line '"
-              + line + "' in v1 directory.");
+        break;
+      default:
+        if (line.startsWith("-----BEGIN")) {
+          crypto = new StringBuilder();
+          crypto.append(line + "\n");
+        } else if (line.startsWith("-----END")) {
+          crypto.append(line + "\n");
+          String cryptoString = crypto.toString();
+          crypto = null;
+          if (nextCrypto.equals("dir-signing-key") &&
+              this.dirSigningKey == null) {
+            this.dirSigningKey = cryptoString;
+          } else {
+            throw new DescriptorParseException("Unrecognized crypto "
+                + "block in v1 directory.");
+          }
+          nextCrypto = "";
+        } else if (crypto != null) {
+          crypto.append(line + "\n");
         } else {
-          if (this.unrecognizedLines == null) {
-            this.unrecognizedLines = new ArrayList<>();
+          if (this.failUnrecognizedDescriptorLines) {
+            throw new DescriptorParseException("Unrecognized line '"
+                + line + "' in v1 directory.");
+          } else {
+            if (this.unrecognizedLines == null) {
+              this.unrecognizedLines = new ArrayList<>();
+            }
+            this.unrecognizedLines.add(line);
           }
-          this.unrecognizedLines.add(line);
         }
       }
     }
@@ -296,7 +305,7 @@ public class RelayDirectoryImpl extends DescriptorImpl
       throws DescriptorParseException {
     Scanner s = new Scanner(new String(directorySignatureBytes)).
         useDelimiter("\n");
-    String nextCrypto = null;
+    String nextCrypto = "";
     StringBuilder crypto = null;
     while (s.hasNext()) {
       String line = s.next();
@@ -320,7 +329,7 @@ public class RelayDirectoryImpl extends DescriptorImpl
           throw new DescriptorParseException("Unrecognized crypto "
               + "block in v2 network status.");
         }
-        nextCrypto = null;
+        nextCrypto = "";
       } else if (crypto != null) {
         crypto.append(line + "\n");
       } else if (this.failUnrecognizedDescriptorLines) {
diff --git a/src/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java b/src/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
index d92718c..13b9142 100644
--- a/src/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
+++ b/src/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
@@ -95,36 +95,50 @@ public class RelayNetworkStatusConsensusImpl extends NetworkStatusImpl
       String line = s.next();
       String[] parts = line.split("[ \t]+");
       String keyword = parts[0];
-      if (keyword.equals("network-status-version")) {
+      switch (keyword) {
+      case "network-status-version":
         this.parseNetworkStatusVersionLine(line, parts);
-      } else if (keyword.equals("vote-status")) {
+        break;
+      case "vote-status":
         this.parseVoteStatusLine(line, parts);
-      } else if (keyword.equals("consensus-method")) {
+        break;
+      case "consensus-method":
         this.parseConsensusMethodLine(line, parts);
-      } else if (keyword.equals("valid-after")) {
+        break;
+      case "valid-after":
         this.parseValidAfterLine(line, parts);
-      } else if (keyword.equals("fresh-until")) {
+        break;
+      case "fresh-until":
         this.parseFreshUntilLine(line, parts);
-      } else if (keyword.equals("valid-until")) {
+        break;
+      case "valid-until":
         this.parseValidUntilLine(line, parts);
-      } else if (keyword.equals("voting-delay")) {
+        break;
+      case "voting-delay":
         this.parseVotingDelayLine(line, parts);
-      } else if (keyword.equals("client-versions")) {
+        break;
+      case "client-versions":
         this.parseClientVersionsLine(line, parts);
-      } else if (keyword.equals("server-versions")) {
+        break;
+      case "server-versions":
         this.parseServerVersionsLine(line, parts);
-      } else if (keyword.equals("known-flags")) {
+        break;
+      case "known-flags":
         this.parseKnownFlagsLine(line, parts);
-      } else if (keyword.equals("params")) {
+        break;
+      case "params":
         this.parseParamsLine(line, parts);
-      } else if (this.failUnrecognizedDescriptorLines) {
-        throw new DescriptorParseException("Unrecognized line '" + line
-            + "' in consensus.");
-      } else {
-        if (this.unrecognizedLines == null) {
-          this.unrecognizedLines = new ArrayList<>();
+        break;
+      default:
+        if (this.failUnrecognizedDescriptorLines) {
+          throw new DescriptorParseException("Unrecognized line '" + line
+              + "' in consensus.");
+        } else {
+          if (this.unrecognizedLines == null) {
+            this.unrecognizedLines = new ArrayList<>();
+          }
+          this.unrecognizedLines.add(line);
         }
-        this.unrecognizedLines.add(line);
       }
     }
   }
@@ -153,17 +167,22 @@ public class RelayNetworkStatusConsensusImpl extends NetworkStatusImpl
       String line = s.next();
       String[] parts = line.split("[ \t]+");
       String keyword = parts[0];
-      if (keyword.equals("directory-footer")) {
-      } else if (keyword.equals("bandwidth-weights")) {
+      switch (keyword) {
+      case "directory-footer":
+        break;
+      case "bandwidth-weights":
         this.parseBandwidthWeightsLine(line, parts);
-      } else if (this.failUnrecognizedDescriptorLines) {
-        throw new DescriptorParseException("Unrecognized line '" + line
-            + "' in consensus.");
-      } else {
-        if (this.unrecognizedLines == null) {
-          this.unrecognizedLines = new ArrayList<>();
+        break;
+      default:
+        if (this.failUnrecognizedDescriptorLines) {
+          throw new DescriptorParseException("Unrecognized line '" + line
+              + "' in consensus.");
+        } else {
+          if (this.unrecognizedLines == null) {
+            this.unrecognizedLines = new ArrayList<>();
+          }
+          this.unrecognizedLines.add(line);
         }
-        this.unrecognizedLines.add(line);
       }
     }
   }
diff --git a/src/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java b/src/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java
index c2735e7..a10ed7a 100644
--- a/src/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java
+++ b/src/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java
@@ -88,7 +88,7 @@ public class RelayNetworkStatusImpl extends NetworkStatusImpl
   protected void parseHeader(byte[] headerBytes)
       throws DescriptorParseException {
     Scanner s = new Scanner(new String(headerBytes)).useDelimiter("\n");
-    String nextCrypto = null;
+    String nextCrypto = "";
     StringBuilder crypto = null;
     while (s.hasNext()) {
       String line = s.next();
@@ -97,49 +97,61 @@ public class RelayNetworkStatusImpl extends NetworkStatusImpl
       }
       String[] parts = line.split("[ \t]+");
       String keyword = parts[0];
-      if (keyword.equals("network-status-version")) {
+      switch (keyword) {
+      case "network-status-version":
         this.parseNetworkStatusVersionLine(line, parts);
-      } else if (keyword.equals("dir-source")) {
+        break;
+      case "dir-source":
         this.parseDirSourceLine(line, parts);
-      } else if (keyword.equals("fingerprint")) {
+        break;
+      case "fingerprint":
         this.parseFingerprintLine(line, parts);
-      } else if (keyword.equals("contact")) {
+        break;
+      case "contact":
         this.parseContactLine(line, parts);
-      } else if (keyword.equals("dir-signing-key")) {
+        break;
+      case "dir-signing-key":
         this.parseDirSigningKeyLine(line, parts);
         nextCrypto = "dir-signing-key";
-      } else if (keyword.equals("client-versions")) {
+        break;
+      case "client-versions":
         this.parseClientVersionsLine(line, parts);
-      } else if (keyword.equals("server-versions")) {
+        break;
+      case "server-versions":
         this.parseServerVersionsLine(line, parts);
-      } else if (keyword.equals("published")) {
+        break;
+      case "published":
         this.parsePublishedLine(line, parts);
-      } else if (keyword.equals("dir-options")) {
+        break;
+      case "dir-options":
         this.parseDirOptionsLine(line, parts);
-      } else if (line.startsWith("-----BEGIN")) {
-        crypto = new StringBuilder();
-        crypto.append(line + "\n");
-      } else if (line.startsWith("-----END")) {
-        crypto.append(line + "\n");
-        String cryptoString = crypto.toString();
-        crypto = null;
-        if (nextCrypto.equals("dir-signing-key")) {
-          this.dirSigningKey = cryptoString;
+        break;
+      default:
+        if (line.startsWith("-----BEGIN")) {
+          crypto = new StringBuilder();
+          crypto.append(line + "\n");
+        } else if (line.startsWith("-----END")) {
+          crypto.append(line + "\n");
+          String cryptoString = crypto.toString();
+          crypto = null;
+          if (nextCrypto.equals("dir-signing-key")) {
+            this.dirSigningKey = cryptoString;
+          } else {
+            throw new DescriptorParseException("Unrecognized crypto "
+                + "block in v2 network status.");
+          }
+          nextCrypto = "";
+        } else if (crypto != null) {
+          crypto.append(line + "\n");
+        } else if (this.failUnrecognizedDescriptorLines) {
+          throw new DescriptorParseException("Unrecognized line '" + line
+              + "' in v2 network status.");
         } else {
-          throw new DescriptorParseException("Unrecognized crypto "
-              + "block in v2 network status.");
+          if (this.unrecognizedLines == null) {
+            this.unrecognizedLines = new ArrayList<>();
+          }
+          this.unrecognizedLines.add(line);
         }
-        nextCrypto = null;
-      } else if (crypto != null) {
-        crypto.append(line + "\n");
-      } else if (this.failUnrecognizedDescriptorLines) {
-        throw new DescriptorParseException("Unrecognized line '" + line
-            + "' in v2 network status.");
-      } else {
-        if (this.unrecognizedLines == null) {
-          this.unrecognizedLines = new ArrayList<>();
-        }
-        this.unrecognizedLines.add(line);
       }
     }
   }
@@ -154,7 +166,7 @@ public class RelayNetworkStatusImpl extends NetworkStatusImpl
       throws DescriptorParseException {
     Scanner s = new Scanner(new String(directorySignatureBytes)).
         useDelimiter("\n");
-    String nextCrypto = null;
+    String nextCrypto = "";
     StringBuilder crypto = null;
     while (s.hasNext()) {
       String line = s.next();
@@ -176,7 +188,7 @@ public class RelayNetworkStatusImpl extends NetworkStatusImpl
           throw new DescriptorParseException("Unrecognized crypto "
               + "block in v2 network status.");
         }
-        nextCrypto = null;
+        nextCrypto = "";
       } else if (crypto != null) {
         crypto.append(line + "\n");
       } else if (this.failUnrecognizedDescriptorLines) {
diff --git a/src/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java b/src/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
index b8f0412..d74ef65 100644
--- a/src/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
+++ b/src/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
@@ -79,65 +79,90 @@ public class RelayNetworkStatusVoteImpl extends NetworkStatusImpl
       String line = s.next();
       String[] parts = line.split("[ \t]+");
       String keyword = parts[0];
-      if (keyword.equals("network-status-version")) {
+      switch (keyword) {
+      case "network-status-version":
         this.parseNetworkStatusVersionLine(line, parts);
-      } else if (keyword.equals("vote-status")) {
+        break;
+      case "vote-status":
         this.parseVoteStatusLine(line, parts);
-      } else if (keyword.equals("consensus-methods")) {
+        break;
+      case "consensus-methods":
         this.parseConsensusMethodsLine(line, parts);
-      } else if (keyword.equals("published")) {
+        break;
+      case "published":
         this.parsePublishedLine(line, parts);
-      } else if (keyword.equals("valid-after")) {
+        break;
+      case "valid-after":
         this.parseValidAfterLine(line, parts);
-      } else if (keyword.equals("fresh-until")) {
+        break;
+      case "fresh-until":
         this.parseFreshUntilLine(line, parts);
-      } else if (keyword.equals("valid-until")) {
+        break;
+      case "valid-until":
         this.parseValidUntilLine(line, parts);
-      } else if (keyword.equals("voting-delay")) {
+        break;
+      case "voting-delay":
         this.parseVotingDelayLine(line, parts);
-      } else if (keyword.equals("client-versions")) {
+        break;
+      case "client-versions":
         this.parseClientVersionsLine(line, parts);
-      } else if (keyword.equals("server-versions")) {
+        break;
+      case "server-versions":
         this.parseServerVersionsLine(line, parts);
-      } else if (keyword.equals("known-flags")) {
+        break;
+      case "known-flags":
         this.parseKnownFlagsLine(line, parts);
-      } else if (keyword.equals("flag-thresholds")) {
+        break;
+      case "flag-thresholds":
         this.parseFlagThresholdsLine(line, parts);
-      } else if (keyword.equals("params")) {
+        break;
+      case "params":
         this.parseParamsLine(line, parts);
-      } else if (keyword.equals("dir-source")) {
+        break;
+      case "dir-source":
         this.parseDirSourceLine(line, parts);
-      } else if (keyword.equals("contact")) {
+        break;
+      case "contact":
         this.parseContactLine(line, parts);
-      } else if (keyword.equals("dir-key-certificate-version")) {
+        break;
+      case "dir-key-certificate-version":
         this.parseDirKeyCertificateVersionLine(line, parts);
-      } else if (keyword.equals("dir-address")) {
+        break;
+      case "dir-address":
         this.parseDirAddressLine(line, parts);
-      } else if (keyword.equals("fingerprint")) {
+        break;
+      case "fingerprint":
         this.parseFingerprintLine(line, parts);
-      } else if (keyword.equals("legacy-dir-key")) {
+        break;
+      case "legacy-dir-key":
         this.parseLegacyDirKeyLine(line, parts);
-      } else if (keyword.equals("dir-key-published")) {
+        break;
+      case "dir-key-published":
         this.parseDirKeyPublished(line, parts);
-      } else if (keyword.equals("dir-key-expires")) {
+        break;
+      case "dir-key-expires":
         this.parseDirKeyExpiresLine(line, parts);
-      } else if (keyword.equals("dir-identity-key") ||
-          keyword.equals("dir-signing-key") ||
-          keyword.equals("dir-key-crosscert") ||
-          keyword.equals("dir-key-certification")) {
-      } else if (line.startsWith("-----BEGIN")) {
-        skipCrypto = true;
-      } else if (line.startsWith("-----END")) {
-        skipCrypto = false;
-      } else if (!skipCrypto) {
-        if (this.failUnrecognizedDescriptorLines) {
-          throw new DescriptorParseException("Unrecognized line '"
-              + line + "' in vote.");
-        } else {
-          if (this.unrecognizedLines == null) {
-            this.unrecognizedLines = new ArrayList<>();
+        break;
+      case "dir-identity-key":
+      case "dir-signing-key":
+      case "dir-key-crosscert":
+      case "dir-key-certification":
+        break;
+      default:
+        if (line.startsWith("-----BEGIN")) {
+          skipCrypto = true;
+        } else if (line.startsWith("-----END")) {
+          skipCrypto = false;
+        } else if (!skipCrypto) {
+          if (this.failUnrecognizedDescriptorLines) {
+            throw new DescriptorParseException("Unrecognized line '"
+                + line + "' in vote.");
+          } else {
+            if (this.unrecognizedLines == null) {
+              this.unrecognizedLines = new ArrayList<>();
+            }
+            this.unrecognizedLines.add(line);
           }
-          this.unrecognizedLines.add(line);
         }
       }
     }
@@ -257,27 +282,37 @@ public class RelayNetworkStatusVoteImpl extends NetworkStatusImpl
         ParseHelper.parseKeyValueStringPairs(line, parts, 1, "=");
     try {
       for (Map.Entry<String, String> e : flagThresholds.entrySet()) {
-        if (e.getKey().equals("stable-uptime")) {
+        switch (e.getKey()) {
+        case "stable-uptime":
           this.stableUptime = Long.parseLong(e.getValue());
-        } else if (e.getKey().equals("stable-mtbf")) {
+          break;
+        case "stable-mtbf":
           this.stableMtbf = Long.parseLong(e.getValue());
-        } else if (e.getKey().equals("fast-speed")) {
+          break;
+        case "fast-speed":
           this.fastBandwidth = Long.parseLong(e.getValue());
-        } else if (e.getKey().equals("guard-wfu")) {
+          break;
+        case "guard-wfu":
           this.guardWfu = Double.parseDouble(e.getValue().
               replaceAll("%", ""));
-        } else if (e.getKey().equals("guard-tk")) {
+          break;
+        case "guard-tk":
           this.guardTk = Long.parseLong(e.getValue());
-        } else if (e.getKey().equals("guard-bw-inc-exits")) {
+          break;
+        case "guard-bw-inc-exits":
           this.guardBandwidthIncludingExits =
               Long.parseLong(e.getValue());
-        } else if (e.getKey().equals("guard-bw-exc-exits")) {
+          break;
+        case "guard-bw-exc-exits":
           this.guardBandwidthExcludingExits =
               Long.parseLong(e.getValue());
-        } else if (e.getKey().equals("enough-mtbf")) {
+          break;
+        case "enough-mtbf":
           this.enoughMtbfInfo = Integer.parseInt(e.getValue());
-        } else if (e.getKey().equals("ignoring-advertised-bws")) {
+          break;
+        case "ignoring-advertised-bws":
           this.ignoringAdvertisedBws = Integer.parseInt(e.getValue());
+          break;
         }
       }
     } catch (NumberFormatException ex) {
diff --git a/src/org/torproject/descriptor/impl/ServerDescriptorImpl.java b/src/org/torproject/descriptor/impl/ServerDescriptorImpl.java
index ddca784..4ed311e 100644
--- a/src/org/torproject/descriptor/impl/ServerDescriptorImpl.java
+++ b/src/org/torproject/descriptor/impl/ServerDescriptorImpl.java
@@ -54,7 +54,7 @@ public abstract class ServerDescriptorImpl extends DescriptorImpl
   private void parseDescriptorBytes() throws DescriptorParseException {
     Scanner s = new Scanner(new String(this.rawDescriptorBytes)).
         useDelimiter("\n");
-    String nextCrypto = null;
+    String nextCrypto = "";
     List<String> cryptoLines = null;
     while (s.hasNext()) {
       String line = s.next();
@@ -65,124 +65,169 @@ public abstract class ServerDescriptorImpl extends DescriptorImpl
           line.substring("opt ".length()) : line;
       String[] partsNoOpt = lineNoOpt.split("[ \t]+");
       String keyword = partsNoOpt[0];
-      if (keyword.equals("router")) {
+      switch (keyword) {
+      case "router":
         this.parseRouterLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("or-address")) {
+        break;
+      case "or-address":
         this.parseOrAddressLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("bandwidth")) {
+        break;
+      case "bandwidth":
         this.parseBandwidthLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("platform")) {
+        break;
+      case "platform":
         this.parsePlatformLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("published")) {
+        break;
+      case "published":
         this.parsePublishedLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("fingerprint")) {
+        break;
+      case "fingerprint":
         this.parseFingerprintLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("hibernating")) {
+        break;
+      case "hibernating":
         this.parseHibernatingLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("uptime")) {
+        break;
+      case "uptime":
         this.parseUptimeLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("onion-key")) {
+        break;
+      case "onion-key":
         this.parseOnionKeyLine(line, lineNoOpt, partsNoOpt);
         nextCrypto = "onion-key";
-      } else if (keyword.equals("signing-key")) {
+        break;
+      case "signing-key":
         this.parseSigningKeyLine(line, lineNoOpt, partsNoOpt);
         nextCrypto = "signing-key";
-      } else if (keyword.equals("accept")) {
+        break;
+      case "accept":
         this.parseAcceptLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("reject")) {
+        break;
+      case "reject":
         this.parseRejectLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("router-signature")) {
+        break;
+      case "router-signature":
         this.parseRouterSignatureLine(line, lineNoOpt, partsNoOpt);
         nextCrypto = "router-signature";
-      } else if (keyword.equals("contact")) {
+        break;
+      case "contact":
         this.parseContactLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("family")) {
+        break;
+      case "family":
         this.parseFamilyLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("read-history")) {
+        break;
+      case "read-history":
         this.parseReadHistoryLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("write-history")) {
+        break;
+      case "write-history":
         this.parseWriteHistoryLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("eventdns")) {
+        break;
+      case "eventdns":
         this.parseEventdnsLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("caches-extra-info")) {
+        break;
+      case "caches-extra-info":
         this.parseCachesExtraInfoLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("extra-info-digest")) {
+        break;
+      case "extra-info-digest":
         this.parseExtraInfoDigestLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("hidden-service-dir")) {
+        break;
+      case "hidden-service-dir":
         this.parseHiddenServiceDirLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("protocols")) {
+        break;
+      case "protocols":
         this.parseProtocolsLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("allow-single-hop-exits")) {
+        break;
+      case "allow-single-hop-exits":
         this.parseAllowSingleHopExitsLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("dircacheport")) {
+        break;
+      case "dircacheport":
         this.parseDircacheportLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("router-digest")) {
+        break;
+      case "router-digest":
         this.parseRouterDigestLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("router-digest-sha256")) {
+        break;
+      case "router-digest-sha256":
         this.parseRouterDigestSha256Line(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("ipv6-policy")) {
+        break;
+      case "ipv6-policy":
         this.parseIpv6PolicyLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("ntor-onion-key")) {
+        break;
+      case "ntor-onion-key":
         this.parseNtorOnionKeyLine(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("identity-ed25519")) {
+        break;
+      case "identity-ed25519":
         this.parseIdentityEd25519Line(line, lineNoOpt, partsNoOpt);
         nextCrypto = "identity-ed25519";
-      } else if (keyword.equals("master-key-ed25519")) {
+        break;
+      case "master-key-ed25519":
         this.parseMasterKeyEd25519Line(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("router-sig-ed25519")) {
+        break;
+      case "router-sig-ed25519":
         this.parseRouterSigEd25519Line(line, lineNoOpt, partsNoOpt);
-      } else if (keyword.equals("onion-key-crosscert")) {
+        break;
+      case "onion-key-crosscert":
         this.parseOnionKeyCrosscert(line, lineNoOpt, partsNoOpt);
         nextCrypto = "onion-key-crosscert";
-      } else if (keyword.equals("ntor-onion-key-crosscert")) {
+        break;
+      case "ntor-onion-key-crosscert":
         this.parseNtorOnionKeyCrosscert(line, lineNoOpt, partsNoOpt);
         nextCrypto = "ntor-onion-key-crosscert";
-      } else if (line.startsWith("-----BEGIN")) {
-        cryptoLines = new ArrayList<>();
-        cryptoLines.add(line);
-      } else if (line.startsWith("-----END")) {
-        cryptoLines.add(line);
-        StringBuilder sb = new StringBuilder();
-        for (String cryptoLine : cryptoLines) {
-          sb.append("\n" + cryptoLine);
-        }
-        String cryptoString = sb.toString().substring(1);
-        if ("onion-key".equals(nextCrypto)) {
-          this.onionKey = cryptoString;
-        } else if ("signing-key".equals(nextCrypto)) {
-          this.signingKey = cryptoString;
-        } else if ("router-signature".equals(nextCrypto)) {
-          this.routerSignature = cryptoString;
-        } else if ("identity-ed25519".equals(nextCrypto)) {
-          this.identityEd25519 = cryptoString;
-          this.parseIdentityEd25519CryptoBlock(cryptoString);
-        } else if ("onion-key-crosscert".equals(nextCrypto)) {
-          this.onionKeyCrosscert = cryptoString;
-        } else if ("ntor-onion-key-crosscert".equals(nextCrypto)) {
-          this.ntorOnionKeyCrosscert = cryptoString;
-        } else if (this.failUnrecognizedDescriptorLines) {
-          throw new DescriptorParseException("Unrecognized crypto "
-              + "block '" + cryptoString + "' in server descriptor.");
-        } else {
-          if (this.unrecognizedLines == null) {
-            this.unrecognizedLines = new ArrayList<>();
+        break;
+      default:
+        if (line.startsWith("-----BEGIN")) {
+          cryptoLines = new ArrayList<>();
+          cryptoLines.add(line);
+        } else if (line.startsWith("-----END")) {
+          cryptoLines.add(line);
+          StringBuilder sb = new StringBuilder();
+          for (String cryptoLine : cryptoLines) {
+            sb.append("\n" + cryptoLine);
           }
-          this.unrecognizedLines.addAll(cryptoLines);
-        }
-        cryptoLines = null;
-        nextCrypto = null;
-      } else if (cryptoLines != null) {
-        cryptoLines.add(line);
-      } else {
-        ParseHelper.parseKeyword(line, partsNoOpt[0]);
-        if (this.failUnrecognizedDescriptorLines) {
-          throw new DescriptorParseException("Unrecognized line '"
-              + line + "' in server descriptor.");
+          String cryptoString = sb.toString().substring(1);
+          switch (nextCrypto) {
+          case "onion-key":
+            this.onionKey = cryptoString;
+            break;
+          case "signing-key":
+            this.signingKey = cryptoString;
+            break;
+          case "router-signature":
+            this.routerSignature = cryptoString;
+            break;
+          case "identity-ed25519":
+            this.identityEd25519 = cryptoString;
+            this.parseIdentityEd25519CryptoBlock(cryptoString);
+            break;
+          case "onion-key-crosscert":
+            this.onionKeyCrosscert = cryptoString;
+            break;
+          case "ntor-onion-key-crosscert":
+            this.ntorOnionKeyCrosscert = cryptoString;
+            break;
+          default:
+            if (this.failUnrecognizedDescriptorLines) {
+              throw new DescriptorParseException("Unrecognized crypto "
+                  + "block '" + cryptoString + "' in server descriptor.");
+            } else {
+              if (this.unrecognizedLines == null) {
+                this.unrecognizedLines = new ArrayList<>();
+              }
+              this.unrecognizedLines.addAll(cryptoLines);
+            }
+          }
+          cryptoLines = null;
+          nextCrypto = "";
+        } else if (cryptoLines != null) {
+          cryptoLines.add(line);
         } else {
-          if (this.unrecognizedLines == null) {
-            this.unrecognizedLines = new ArrayList<>();
+          ParseHelper.parseKeyword(line, partsNoOpt[0]);
+          if (this.failUnrecognizedDescriptorLines) {
+            throw new DescriptorParseException("Unrecognized line '"
+                + line + "' in server descriptor.");
+          } else {
+            if (this.unrecognizedLines == null) {
+              this.unrecognizedLines = new ArrayList<>();
+            }
+            this.unrecognizedLines.add(line);
           }
-          this.unrecognizedLines.add(line);
         }
       }
     }
diff --git a/src/org/torproject/descriptor/impl/TorperfResultImpl.java b/src/org/torproject/descriptor/impl/TorperfResultImpl.java
index aad8e32..26e0e4a 100644
--- a/src/org/torproject/descriptor/impl/TorperfResultImpl.java
+++ b/src/org/torproject/descriptor/impl/TorperfResultImpl.java
@@ -79,60 +79,85 @@ public class TorperfResultImpl extends DescriptorImpl
       String key = keyValueParts[0];
       this.markKeyAsParsed(key, line);
       String value = keyValueParts[1];
-      if (key.equals("SOURCE")) {
+      switch (key) {
+      case "SOURCE":
         this.parseSource(value, keyValue, line);
-      } else if (key.equals("FILESIZE")) {
+        break;
+      case "FILESIZE":
         this.parseFileSize(value, keyValue, line);
-      } else if (key.equals("START")) {
+        break;
+      case "START":
         this.parseStart(value, keyValue, line);
-      } else if (key.equals("SOCKET")) {
+        break;
+      case "SOCKET":
         this.parseSocket(value, keyValue, line);
-      } else if (key.equals("CONNECT")) {
+        break;
+      case "CONNECT":
         this.parseConnect(value, keyValue, line);
-      } else if (key.equals("NEGOTIATE")) {
+        break;
+      case "NEGOTIATE":
         this.parseNegotiate(value, keyValue, line);
-      } else if (key.equals("REQUEST")) {
+        break;
+      case "REQUEST":
         this.parseRequest(value, keyValue, line);
-      } else if (key.equals("RESPONSE")) {
+        break;
+      case "RESPONSE":
         this.parseResponse(value, keyValue, line);
-      } else if (key.equals("DATAREQUEST")) {
+        break;
+      case "DATAREQUEST":
         this.parseDataRequest(value, keyValue, line);
-      } else if (key.equals("DATARESPONSE")) {
+        break;
+      case "DATARESPONSE":
         this.parseDataResponse(value, keyValue, line);
-      } else if (key.equals("DATACOMPLETE")) {
+        break;
+      case "DATACOMPLETE":
         this.parseDataComplete(value, keyValue, line);
-      } else if (key.equals("WRITEBYTES")) {
+        break;
+      case "WRITEBYTES":
         this.parseWriteBytes(value, keyValue, line);
-      } else if (key.equals("READBYTES")) {
+        break;
+      case "READBYTES":
         this.parseReadBytes(value, keyValue, line);
-      } else if (key.equals("DIDTIMEOUT")) {
+        break;
+      case "DIDTIMEOUT":
         this.parseDidTimeout(value, keyValue, line);
-      } else if (key.startsWith("DATAPERC")) {
-        this.parseDataPercentile(value, keyValue, line);
-      } else if (key.equals("LAUNCH")) {
+        break;
+      case "LAUNCH":
         this.parseLaunch(value, keyValue, line);
-      } else if (key.equals("USED_AT")) {
+        break;
+      case "USED_AT":
         this.parseUsedAt(value, keyValue, line);
-      } else if (key.equals("PATH")) {
+        break;
+      case "PATH":
         this.parsePath(value, keyValue, line);
-      } else if (key.equals("BUILDTIMES")) {
+        break;
+      case "BUILDTIMES":
         this.parseBuildTimes(value, keyValue, line);
-      } else if (key.equals("TIMEOUT")) {
+        break;
+      case "TIMEOUT":
         this.parseTimeout(value, keyValue, line);
-      } else if (key.equals("QUANTILE")) {
+        break;
+      case "QUANTILE":
         this.parseQuantile(value, keyValue, line);
-      } else if (key.equals("CIRC_ID")) {
+        break;
+      case "CIRC_ID":
         this.parseCircId(value, keyValue, line);
-      } else if (key.equals("USED_BY")) {
+        break;
+      case "USED_BY":
         this.parseUsedBy(value, keyValue, line);
-      } else if (this.failUnrecognizedDescriptorLines) {
-        throw new DescriptorParseException("Unrecognized key '" + key
-            + "' in line '" + line + "'.");
-      } else {
-        if (this.unrecognizedLines == null) {
-          this.unrecognizedLines = new ArrayList<>();
+        break;
+      default:
+        if (key.startsWith("DATAPERC")) {
+          this.parseDataPercentile(value, keyValue, line);
+        } else if (this.failUnrecognizedDescriptorLines) {
+          throw new DescriptorParseException("Unrecognized key '" + key
+              + "' in line '" + line + "'.");
+        } else {
+          if (this.unrecognizedLines == null) {
+            this.unrecognizedLines = new ArrayList<>();
+          }
+          this.unrecognizedLines.add(line);
         }
-        this.unrecognizedLines.add(line);
       }
     }
     this.checkAllRequiredKeysParsed(line);





More information about the tor-commits mailing list