• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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