• 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 static com.google.protobuf.Internal.checkNotNull;
11 
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.List;
15 
16 /**
17  * Information for the layout of a protobuf message class. This describes all of the fields
18  * contained within a message.
19  */
20 @ExperimentalApi
21 @CheckReturnValue
22 final class StructuralMessageInfo implements MessageInfo {
23   private final ProtoSyntax syntax;
24   private final boolean messageSetWireFormat;
25   private final int[] checkInitialized;
26   private final FieldInfo[] fields;
27   private final MessageLite defaultInstance;
28 
29   /**
30    * Constructor.
31    *
32    * @param checkInitialized fields to check in isInitialized().
33    * @param fields the set of fields for the message, in field number order.
34    */
StructuralMessageInfo( ProtoSyntax syntax, boolean messageSetWireFormat, int[] checkInitialized, FieldInfo[] fields, Object defaultInstance)35   StructuralMessageInfo(
36       ProtoSyntax syntax,
37       boolean messageSetWireFormat,
38       int[] checkInitialized,
39       FieldInfo[] fields,
40       Object defaultInstance) {
41     this.syntax = syntax;
42     this.messageSetWireFormat = messageSetWireFormat;
43     this.checkInitialized = checkInitialized;
44     this.fields = fields;
45     this.defaultInstance = (MessageLite) checkNotNull(defaultInstance, "defaultInstance");
46   }
47 
48   /** Gets the syntax for the message (e.g. PROTO2, PROTO3). */
49   @Override
getSyntax()50   public ProtoSyntax getSyntax() {
51     return syntax;
52   }
53 
54   /** Indicates whether or not the message should be represented with message set wire format. */
55   @Override
isMessageSetWireFormat()56   public boolean isMessageSetWireFormat() {
57     return messageSetWireFormat;
58   }
59 
60   /** An array of field numbers that need to be checked for isInitialized(). */
getCheckInitialized()61   public int[] getCheckInitialized() {
62     return checkInitialized;
63   }
64 
65   /**
66    * Gets the information for all fields within this message, sorted in ascending order by their
67    * field number.
68    */
getFields()69   public FieldInfo[] getFields() {
70     return fields;
71   }
72 
73   @Override
getDefaultInstance()74   public MessageLite getDefaultInstance() {
75     return defaultInstance;
76   }
77 
78   /** Helper method for creating a new builder for {@link MessageInfo}. */
newBuilder()79   public static Builder newBuilder() {
80     return new Builder();
81   }
82 
83   /** Helper method for creating a new builder for {@link MessageInfo}. */
newBuilder(int numFields)84   public static Builder newBuilder(int numFields) {
85     return new Builder(numFields);
86   }
87 
88   /** A builder of {@link MessageInfo} instances. */
89   public static final class Builder {
90     private final List<FieldInfo> fields;
91     private ProtoSyntax syntax;
92     private boolean wasBuilt;
93     private boolean messageSetWireFormat;
94     private int[] checkInitialized = null;
95     private Object defaultInstance;
96 
Builder()97     public Builder() {
98       fields = new ArrayList<FieldInfo>();
99     }
100 
Builder(int numFields)101     public Builder(int numFields) {
102       fields = new ArrayList<FieldInfo>(numFields);
103     }
104 
withDefaultInstance(Object defaultInstance)105     public void withDefaultInstance(Object defaultInstance) {
106       this.defaultInstance = defaultInstance;
107     }
108 
withSyntax(ProtoSyntax syntax)109     public void withSyntax(ProtoSyntax syntax) {
110       this.syntax = checkNotNull(syntax, "syntax");
111     }
112 
withMessageSetWireFormat(boolean messageSetWireFormat)113     public void withMessageSetWireFormat(boolean messageSetWireFormat) {
114       this.messageSetWireFormat = messageSetWireFormat;
115     }
116 
withCheckInitialized(int[] checkInitialized)117     public void withCheckInitialized(int[] checkInitialized) {
118       this.checkInitialized = checkInitialized;
119     }
120 
withField(FieldInfo field)121     public void withField(FieldInfo field) {
122       if (wasBuilt) {
123         throw new IllegalStateException("Builder can only build once");
124       }
125       fields.add(field);
126     }
127 
build()128     public StructuralMessageInfo build() {
129       if (wasBuilt) {
130         throw new IllegalStateException("Builder can only build once");
131       }
132       if (syntax == null) {
133         throw new IllegalStateException("Must specify a proto syntax");
134       }
135       wasBuilt = true;
136       Collections.sort(fields);
137       return new StructuralMessageInfo(
138           syntax,
139           messageSetWireFormat,
140           checkInitialized,
141           fields.toArray(new FieldInfo[0]),
142           defaultInstance);
143     }
144   }
145 }
146