1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file or at 6 // https://developers.google.com/open-source/licenses/bsd 7 8 package com.google.protobuf; 9 10 import java.util.Iterator; 11 import java.util.Map.Entry; 12 13 /** 14 * LazyField encapsulates the logic of lazily parsing message fields. It stores the message in a 15 * ByteString initially and then parses it on-demand. 16 * 17 * <p>Most methods are implemented in {@link LazyFieldLite} but this class can contain a 18 * default instance of the message to provide {@code hashCode()}, {@code equals()}, and {@code 19 * toString()}. 20 * 21 * @author xiangl@google.com (Xiang Li) 22 */ 23 public class LazyField extends LazyFieldLite { 24 25 /** 26 * Carry a message's default instance which is used by {@code hashCode()}, {@code equals()}, and 27 * {@code toString()}. 28 */ 29 private final MessageLite defaultInstance; 30 LazyField( MessageLite defaultInstance, ExtensionRegistryLite extensionRegistry, ByteString bytes)31 public LazyField( 32 MessageLite defaultInstance, ExtensionRegistryLite extensionRegistry, ByteString bytes) { 33 super(extensionRegistry, bytes); 34 35 this.defaultInstance = defaultInstance; 36 } 37 38 @Override containsDefaultInstance()39 public boolean containsDefaultInstance() { 40 return super.containsDefaultInstance() || value == defaultInstance; 41 } 42 getValue()43 public MessageLite getValue() { 44 return getValue(defaultInstance); 45 } 46 47 @Override hashCode()48 public int hashCode() { 49 return getValue().hashCode(); 50 } 51 52 @Override equals(Object obj)53 public boolean equals(Object obj) { 54 return getValue().equals(obj); 55 } 56 57 @Override toString()58 public String toString() { 59 return getValue().toString(); 60 } 61 62 // ==================================================== 63 64 /** 65 * LazyEntry and LazyIterator are used to encapsulate the LazyField, when users iterate all fields 66 * from FieldSet. 67 */ 68 static class LazyEntry<K> implements Entry<K, Object> { 69 private Entry<K, LazyField> entry; 70 LazyEntry(Entry<K, LazyField> entry)71 private LazyEntry(Entry<K, LazyField> entry) { 72 this.entry = entry; 73 } 74 75 @Override getKey()76 public K getKey() { 77 return entry.getKey(); 78 } 79 80 @Override getValue()81 public Object getValue() { 82 LazyField field = entry.getValue(); 83 if (field == null) { 84 return null; 85 } 86 return field.getValue(); 87 } 88 getField()89 public LazyField getField() { 90 return entry.getValue(); 91 } 92 93 @Override setValue(Object value)94 public Object setValue(Object value) { 95 if (!(value instanceof MessageLite)) { 96 throw new IllegalArgumentException( 97 "LazyField now only used for MessageSet, " 98 + "and the value of MessageSet must be an instance of MessageLite"); 99 } 100 return entry.getValue().setValue((MessageLite) value); 101 } 102 } 103 104 static class LazyIterator<K> implements Iterator<Entry<K, Object>> { 105 private Iterator<Entry<K, Object>> iterator; 106 LazyIterator(Iterator<Entry<K, Object>> iterator)107 public LazyIterator(Iterator<Entry<K, Object>> iterator) { 108 this.iterator = iterator; 109 } 110 111 @Override hasNext()112 public boolean hasNext() { 113 return iterator.hasNext(); 114 } 115 116 @Override 117 @SuppressWarnings("unchecked") next()118 public Entry<K, Object> next() { 119 Entry<K, ?> entry = iterator.next(); 120 if (entry.getValue() instanceof LazyField) { 121 return new LazyEntry<K>((Entry<K, LazyField>) entry); 122 } 123 return (Entry<K, Object>) entry; 124 } 125 126 @Override remove()127 public void remove() { 128 iterator.remove(); 129 } 130 } 131 } 132