Browse Source

Moving internal code to InternalNano and rename MapUtil to MapFactories.

Jisi Liu 11 năm trước cách đây
mục cha
commit
3c0355ef37

+ 167 - 0
javanano/src/main/java/com/google/protobuf/nano/InternalNano.java

@@ -30,8 +30,11 @@
 
 package com.google.protobuf.nano;
 
+import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.util.Arrays;
+import java.util.Map;
+import java.util.Map.Entry;
 
 /**
  * The classes contained within are used internally by the Protocol Buffer
@@ -349,5 +352,169 @@ public final class InternalNano {
     }
     return result;
   }
+  private static final byte[] emptyBytes = new byte[0];
+  private static Object primitiveDefaultValue(int type) {
+    switch (type) {
+      case TYPE_BOOL:
+        return Boolean.FALSE;
+      case TYPE_BYTES:
+        return emptyBytes;
+      case TYPE_STRING:
+        return "";
+      case TYPE_FLOAT:
+        return Float.valueOf(0);
+      case TYPE_DOUBLE:
+        return Double.valueOf(0);
+      case TYPE_ENUM:
+      case TYPE_FIXED32:
+      case TYPE_INT32:
+      case TYPE_UINT32:
+      case TYPE_SINT32:
+      case TYPE_SFIXED32:
+        return Integer.valueOf(0);
+      case TYPE_INT64:
+      case TYPE_UINT64:
+      case TYPE_SINT64:
+      case TYPE_FIXED64:
+      case TYPE_SFIXED64:
+        return Long.valueOf(0L);
+      case TYPE_MESSAGE:
+      case TYPE_GROUP:
+      default:
+        throw new IllegalArgumentException(
+            "Type: " + type + " is not a primitive type.");
+    }
+  }
+
+  /**
+   * Merges the map entry into the map field. Note this is only supposed to
+   * be called by generated messages.
+   *
+   * @param map the map field; may be null, in which case a map will be
+   *        instantiated using the {@link MapUtil.MapFactory}
+   * @param input the input byte buffer
+   * @param keyType key type, as defined in InternalNano.TYPE_*
+   * @param valueType value type, as defined in InternalNano.TYPE_*
+   * @param valueClazz class of the value field if the valueType is
+   *        TYPE_MESSAGE; otherwise the parameter is ignored and can be null.
+   * @param keyTag wire tag for the key
+   * @param valueTag wire tag for the value
+   * @return the map field
+   * @throws IOException
+   */
+  @SuppressWarnings("unchecked")
+  public static final <K, V> Map<K, V> mergeMapEntry(
+      CodedInputByteBufferNano input,
+      Map<K, V> map,
+      int keyType,
+      int valueType,
+      Class<V> valueClazz,
+      int keyTag,
+      int valueTag) throws IOException {
+    map = MapFactories.getMapFactory().forMap(map);
+    final int length = input.readRawVarint32();
+    final int oldLimit = input.pushLimit(length);
+    byte[] payload = null;
+    K key = null;
+    V value = null;
+    while (true) {
+      int tag = input.readTag();
+      if (tag == 0) {
+        break;
+      }
+      if (tag == keyTag) {
+        key = (K) input.readData(keyType);
+      } else if (tag == valueTag) {
+        if (valueType == TYPE_MESSAGE) {
+          payload = input.readBytes();
+        } else {
+          value = (V) input.readData(valueType);
+        }
+      } else {
+        if (!input.skipField(tag)) {
+          break;
+        }
+      }
+    }
+    input.checkLastTagWas(0);
+    input.popLimit(oldLimit);
+
+    if (key == null) {
+      key = (K) primitiveDefaultValue(keyType);
+    }
 
+    // Special case: merge the value when the value is a message.
+    if (valueType == TYPE_MESSAGE) {
+      MessageNano oldMessageValue = (MessageNano) map.get(key);
+      if (oldMessageValue != null) {
+        if (payload != null) {
+          MessageNano.mergeFrom(oldMessageValue, payload);
+        }
+        return map;
+      }
+      // Otherwise, create a new value message.
+      try {
+        value = valueClazz.newInstance();
+      } catch (InstantiationException e) {
+        throw new IOException(
+            "Unable to create value message " + valueClazz.getName()
+            + " in maps.");
+      } catch (IllegalAccessException e) {
+        throw new IOException(
+            "Unable to create value message " + valueClazz.getName()
+            + " in maps.");
+      }
+      if (payload != null) {
+        MessageNano.mergeFrom((MessageNano) value, payload);
+      }
+    }
+
+    if (value == null) {
+      value = (V) primitiveDefaultValue(valueType);
+    }
+
+    map.put(key, value);
+    return map;
+  }
+
+  public static <K, V> void serializeMapField(
+      CodedOutputByteBufferNano output,
+      Map<K, V> map, int number, int keyType, int valueType)
+          throws IOException {
+    for (Entry<K, V> entry: map.entrySet()) {
+      K key = entry.getKey();
+      V value = entry.getValue();
+      if (key == null || value == null) {
+        throw new IllegalStateException(
+            "keys and values in maps cannot be null");
+      }
+      int entrySize =
+          CodedOutputByteBufferNano.computeFieldSize(1, keyType, key) +
+          CodedOutputByteBufferNano.computeFieldSize(2, valueType, value);
+      output.writeTag(number, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
+      output.writeRawVarint32(entrySize);
+      output.writeField(1, keyType, key);
+      output.writeField(2, valueType, value);
+    }
+  }
+
+  public static <K, V> int computeMapFieldSize(
+      Map<K, V> map, int number, int keyType, int valueType) {
+    int size = 0;
+    int tagSize = CodedOutputByteBufferNano.computeTagSize(number);
+    for (Entry<K, V> entry: map.entrySet()) {
+      K key = entry.getKey();
+      V value = entry.getValue();
+      if (key == null || value == null) {
+        throw new IllegalStateException(
+            "keys and values in maps cannot be null");
+      }
+      int entrySize =
+          CodedOutputByteBufferNano.computeFieldSize(1, keyType, key) +
+          CodedOutputByteBufferNano.computeFieldSize(2, valueType, value);
+      size += tagSize + entrySize
+          + CodedOutputByteBufferNano.computeRawVarint32Size(entrySize);
+    }
+    return size;
+  }
 }

+ 63 - 0
javanano/src/main/java/com/google/protobuf/nano/MapFactories.java

@@ -0,0 +1,63 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2013 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package com.google.protobuf.nano;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Utility class for maps support.
+ */
+public final class MapFactories {
+  public static interface MapFactory {
+    <K, V> Map<K, V> forMap(Map<K, V> oldMap);
+  }
+
+  public static void setMapFactory(MapFactory newMapFactory) {
+    mapFactory = newMapFactory;
+  }
+
+  public static MapFactory getMapFactory() {
+    return mapFactory;
+  }
+
+  private static class DefaultMapFactory implements MapFactory {
+    public <K, V> Map<K, V> forMap(Map<K, V> oldMap) {
+      if (oldMap == null) {
+        return new HashMap<K, V>();
+      }
+      return oldMap;
+    }
+  }
+  private static volatile MapFactory mapFactory = new DefaultMapFactory();
+
+  private MapFactories() {}
+}

+ 0 - 234
javanano/src/main/java/com/google/protobuf/nano/MapUtil.java

@@ -1,234 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2013 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-package com.google.protobuf.nano;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Utility class for maps support.
- */
-public final class MapUtil {
-  public static interface MapFactory {
-    <K, V> Map<K, V> forMap(Map<K, V> oldMap);
-  }
-  public static void setMapFactory(MapFactory newMapFactory) {
-    mapFactory = newMapFactory;
-  }
-
-  private static class DefaultMapFactory implements MapFactory {
-    public <K, V> Map<K, V> forMap(Map<K, V> oldMap) {
-      if (oldMap == null) {
-        return new HashMap<K, V>();
-      }
-      return oldMap;
-    }
-  }
-  private static volatile MapFactory mapFactory = new DefaultMapFactory();
-
-  /**
-   * Internal utilities to implement maps for generated messages.
-   * Do NOT use it explicitly.
-   */
-  public static class Internal {
-    private static final byte[] emptyBytes = new byte[0];
-    private static Object primitiveDefaultValue(int type) {
-      switch (type) {
-        case InternalNano.TYPE_BOOL:
-          return Boolean.FALSE;
-        case InternalNano.TYPE_BYTES:
-          return emptyBytes;
-        case InternalNano.TYPE_STRING:
-          return "";
-        case InternalNano.TYPE_FLOAT:
-          return Float.valueOf(0);
-        case InternalNano.TYPE_DOUBLE:
-          return Double.valueOf(0);
-        case InternalNano.TYPE_ENUM:
-        case InternalNano.TYPE_FIXED32:
-        case InternalNano.TYPE_INT32:
-        case InternalNano.TYPE_UINT32:
-        case InternalNano.TYPE_SINT32:
-        case InternalNano.TYPE_SFIXED32:
-          return Integer.valueOf(0);
-        case InternalNano.TYPE_INT64:
-        case InternalNano.TYPE_UINT64:
-        case InternalNano.TYPE_SINT64:
-        case InternalNano.TYPE_FIXED64:
-        case InternalNano.TYPE_SFIXED64:
-          return Long.valueOf(0L);
-        case InternalNano.TYPE_MESSAGE:
-        case InternalNano.TYPE_GROUP:
-        default:
-          throw new IllegalArgumentException(
-              "Type: " + type + " is not a primitive type.");
-      }
-    }
-
-    /**
-     * Merges the map entry into the map field. Note this is only supposed to
-     * be called by generated messages.
-     *
-     * @param map the map field; may be null, in which case a map will be
-     *        instantiated using the {@link MapUtil.MapFactory}
-     * @param input the input byte buffer
-     * @param keyType key type, as defined in InternalNano.TYPE_*
-     * @param valueType value type, as defined in InternalNano.TYPE_*
-     * @param valueClazz class of the value field if the valueType is
-     *        TYPE_MESSAGE; otherwise the parameter is ignored and can be null.
-     * @param keyTag wire tag for the key
-     * @param valueTag wire tag for the value
-     * @return the map field
-     * @throws IOException
-     */
-    @SuppressWarnings("unchecked")
-    public static final <K, V> Map<K, V> mergeEntry(
-        CodedInputByteBufferNano input,
-        Map<K, V> map,
-        int keyType,
-        int valueType,
-        Class<V> valueClazz,
-        int keyTag,
-        int valueTag) throws IOException {
-      map = mapFactory.forMap(map);
-      final int length = input.readRawVarint32();
-      final int oldLimit = input.pushLimit(length);
-      byte[] payload = null;
-      K key = null;
-      V value = null;
-      while (true) {
-        int tag = input.readTag();
-        if (tag == 0) {
-          break;
-        }
-        if (tag == keyTag) {
-          key = (K) input.readData(keyType);
-        } else if (tag == valueTag) {
-          if (valueType == InternalNano.TYPE_MESSAGE) {
-            payload = input.readBytes();
-          } else {
-            value = (V) input.readData(valueType);
-          }
-        } else {
-          if (!input.skipField(tag)) {
-            break;
-          }
-        }
-      }
-      input.checkLastTagWas(0);
-      input.popLimit(oldLimit);
-
-      if (key == null) {
-        key = (K) primitiveDefaultValue(keyType);
-      }
-
-      // Special case: merge the value when the value is a message.
-      if (valueType == InternalNano.TYPE_MESSAGE) {
-        MessageNano oldMessageValue = (MessageNano) map.get(key);
-        if (oldMessageValue != null) {
-          if (payload != null) {
-            MessageNano.mergeFrom(oldMessageValue, payload);
-          }
-          return map;
-        }
-        // Otherwise, create a new value message.
-        try {
-          value = valueClazz.newInstance();
-        } catch (InstantiationException e) {
-          throw new IOException(
-              "Unable to create value message " + valueClazz.getName()
-              + " in maps.");
-        } catch (IllegalAccessException e) {
-          throw new IOException(
-              "Unable to create value message " + valueClazz.getName()
-              + " in maps.");
-        }
-        if (payload != null) {
-          MessageNano.mergeFrom((MessageNano) value, payload);
-        }
-      }
-
-      if (value == null) {
-        value = (V) primitiveDefaultValue(valueType);
-      }
-
-      map.put(key, value);
-      return map;
-    }
-
-    public static <K, V> void serializeMapField(
-        CodedOutputByteBufferNano output,
-        Map<K, V> map, int number, int keyType, int valueType)
-            throws IOException {
-      for (Entry<K, V> entry: map.entrySet()) {
-        K key = entry.getKey();
-        V value = entry.getValue();
-        if (key == null || value == null) {
-          throw new IllegalStateException(
-              "keys and values in maps cannot be null");
-        }
-        int entrySize =
-            CodedOutputByteBufferNano.computeFieldSize(1, keyType, key) +
-            CodedOutputByteBufferNano.computeFieldSize(2, valueType, value);
-        output.writeTag(number, WireFormatNano.WIRETYPE_LENGTH_DELIMITED);
-        output.writeRawVarint32(entrySize);
-        output.writeField(1, keyType, key);
-        output.writeField(2, valueType, value);
-      }
-    }
-
-    public static <K, V> int computeMapFieldSize(
-        Map<K, V> map, int number, int keyType, int valueType) {
-      int size = 0;
-      int tagSize = CodedOutputByteBufferNano.computeTagSize(number);
-      for (Entry<K, V> entry: map.entrySet()) {
-        K key = entry.getKey();
-        V value = entry.getValue();
-        if (key == null || value == null) {
-          throw new IllegalStateException(
-              "keys and values in maps cannot be null");
-        }
-        int entrySize =
-            CodedOutputByteBufferNano.computeFieldSize(1, keyType, key) +
-            CodedOutputByteBufferNano.computeFieldSize(2, valueType, value);
-        size += tagSize + entrySize
-            + CodedOutputByteBufferNano.computeRawVarint32Size(entrySize);
-      }
-      return size;
-    }
-
-    private Internal() {}
-  }
-
-  private MapUtil() {}
-}

+ 3 - 3
src/google/protobuf/compiler/javanano/javanano_map_field.cc

@@ -133,7 +133,7 @@ GenerateClearCode(io::Printer* printer) const {
 void MapFieldGenerator::
 GenerateMergingCode(io::Printer* printer) const {
   printer->Print(variables_,
-    "this.$name$ = com.google.protobuf.nano.MapUtil.Internal.mergeEntry(\n"
+    "this.$name$ = com.google.protobuf.nano.InternalNano.mergeMapEntry(\n"
     "  input, this.$name$,\n"
     "  com.google.protobuf.nano.InternalNano.$key_desc_type$,\n"
     "  com.google.protobuf.nano.InternalNano.$value_desc_type$,\n"
@@ -146,7 +146,7 @@ void MapFieldGenerator::
 GenerateSerializationCode(io::Printer* printer) const {
   printer->Print(variables_,
     "if (this.$name$ != null) {\n"
-    "  com.google.protobuf.nano.MapUtil.Internal.serializeMapField(\n"
+    "  com.google.protobuf.nano.InternalNano.serializeMapField(\n"
     "    output, this.$name$, $number$,\n"
     "  com.google.protobuf.nano.InternalNano.$key_desc_type$,\n"
     "  com.google.protobuf.nano.InternalNano.$value_desc_type$);\n"
@@ -157,7 +157,7 @@ void MapFieldGenerator::
 GenerateSerializedSizeCode(io::Printer* printer) const {
   printer->Print(variables_,
     "if (this.$name$ != null) {\n"
-    "  size += com.google.protobuf.nano.MapUtil.Internal.computeMapFieldSize(\n"
+    "  size += com.google.protobuf.nano.InternalNano.computeMapFieldSize(\n"
     "    this.$name$, $number$,\n"
     "  com.google.protobuf.nano.InternalNano.$key_desc_type$,\n"
     "  com.google.protobuf.nano.InternalNano.$value_desc_type$);\n"