Protocol buffers are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages. Protocol Buffers are Schema Of Messages. They are language agnostic. They can be converted to binary and converted back to message formats using the code generated by the protoc compiler for various languages.
1/*
2* Language Syntax
3*/
4
5/*
6* Specifying Syntax Of Protocol Buffer Version
7* Specifying Which Protocol Buffer Version To Use
8* It can be usually proto3 or proto2
9*/
10syntax = "proto3";
11
12/*
13* Declaring Message In Protocol Buffer:
14* As you can see, each field in the message definition has a unique number.
15* These field numbers are used to identify your fields in the message binary format,
16* and should not be changed once your message type is in use.
17* Note that field numbers in the range 1 through 15 take one byte to encode, including the field number and the field's type (you can find out more about this in Protocol Buffer Encoding).
18* Field numbers in the range 16 through 2047 take two bytes. So you should reserve the numbers 1 through 15 for very frequently occurring message elements.
19* Remember to leave some room for frequently occurring elements that might be added in the future.
20* The smallest field number you can specify is 1, and the largest is 2^29 - 1, or 536,870,911.
21* You also cannot use the numbers 19000 through 19999 (FieldDescriptor::kFirstReservedNumber through FieldDescriptor::kLastReservedNumber),
22* as they are reserved for the Protocol Buffers implementation - the protocol buffer compiler will complain if you use one of these reserved numbers in your .proto.
23* Similarly, you cannot use any previously reserved field numbers.
24*
25*/
26
27/*
28Syntax For Declaring Message:
29 message ${MessageName} {
30 ${Scalar Value Type} ${FieldName1} = ${Tag Number1};
31 .
32 .
33 .
34 ${Scalar Value Type} ${FieldNameN} = ${Tag NumberN};
35 }
36
37Default Values Will be applied any case if the message doesn't contain a existing field defined
38in the message definition
39*/
40
41message MessageTypes {
42 /*
43 * Scalar Value Types
44 */
45 string stringType = 1; // A string must always contain UTF-8 encoded or 7-bit ASCII text. Default value = ""
46
47 // Number Types, Default Value = 0
48 int32 int32Type = 2; // Uses Variable Length Encoding. Inefficient For Negative Numbers, Instead Use sint32.
49 int64 int64Type = 3; // Uses Variable Length Encoding. Inefficient For Negative Numbers, Instead Use sint64.
50 uint32 uInt32Type = 4; // Uses Variable Length Encoding
51 uint64 uInt64Type = 5; // Uses Variable Length Encoding
52 sint32 sInt32Type = 6; // Uses Variable Length Encoding. They are efficient in encoding for negative numbers.
53 // Use this instead of int32 for negative numbers
54 sint64 sInt64Type = 7; // Uses Variable Length Encoding. They are efficient in encoding for negative numbers.
55 // Use this instead of int64 for negative numbers.
56
57 fixed32 fixed32Type = 8; // Always four bytes. More efficient than uint32 if values are often greater than 2^28.
58 fixed64 fixed64Type = 9; // Always eight bytes. More efficient than uint64 if values are often greater than 2^56
59
60 sfixed32 sfixed32Type = 10; // Always four bytes.
61 sfixed64 sfixed64Type = 11; // Always Eight bytes.
62
63 bool boolType = 12; // Boolean Type. Default Value = false
64
65 bytes bytesType = 13; // May contain any arbitrary sequence of bytes. Default Value = Empty Bytes
66
67 double doubleType = 14;
68 float floatType = 15;
69
70 enum Week {
71 UNDEFINED = 0; // Tag 0 is always used as default in case of enum
72 SUNDAY = 1;
73 MONDAY = 2;
74 TUESDAY = 3;
75 WEDNESDAY = 4;
76 THURSDAY = 5;
77 FRIDAY = 6;
78 SATURDAY = 7;
79 }
80 Week wkDayType = 16;
81
82 /*
83 * Defining Collection Of Scalar Value Type
84 * Syntax: repeated ${ScalarType} ${name} = TagValue
85 */
86 repeated string listOfString = 17; // List[String]
87}
88
89/*
90* Defining Defined Message Types In Other Message Definition
91*/
92message Person {
93 string fname = 1;
94 string sname = 2;
95}
96
97message City {
98 Person p = 1;
99}
100
101/*
102* Nested Message Definitions
103*/
104
105message NestedMessages {
106 message FirstLevelNestedMessage {
107 string firstString = 1;
108 message SecondLevelNestedMessage {
109 string secondString = 2;
110 }
111 }
112 FirstLevelNestedMessage msg = 1;
113 FirstLevelNestedMessage.SecondLevelNestedMessage msg2 = 2;
114}
115
116/*
117* Importing Message From A File
118*/
119
120// one.proto
121// message One {
122// string oneMsg = 1;
123// }
124
125// two.proto
126// import "myproject/one.proto"
127// message Two {
128// string twoMsg = 2;
129// }
130
131
132/*
133* Advanced Topics
134*/
135
136/*
137* Handling Message Type Changes:
138* Never Change/Use The TagNumber Of A Message Field Which Was Removed
139* We should use reserved in case of message definition update.
140* (https://developers.google.com/protocol-buffers/docs/proto3#updating)
141*/
142
143/*
144* Reserved Fields
145* It's used in case if we need to add/remove new fields into message.
146* Using Reserved Backward and Forward Compatibility Of Messages can be achieved
147*/
148
149
150message ReservedMessage {
151 reserved 0, 1, 2, 3 to 10; // Set Of Tag Numbers Which Can't be reused.
152 reserved "firstMsg", "secondMsg", "thirdMsg"; // Set Of Labels Which Can't Be reused.
153}
154
155/*
156* Any
157* The Any message type lets you use messages as embedded types without having their .proto definition.
158* An Any contains an arbitrary serialized message as bytes,
159* along with a URL that acts as a globally unique identifier for and resolves to that message's type.
160* For Any to work we need to import it as shown below.
161*/
162/*
163 import "google/protobuf/any.proto";
164 message AnySampleMessage {
165 repeated google.protobuf.Any.details = 1;
166 }
167
168*/
169
170
171/*
172* OneOf
173* There are cases, wherein only one field at-most might be present as part of the message.
174* Note: OneOf messages can't be repeated.
175*/
176
177message OneOfMessage {
178 oneof msg {
179 string fname = 1;
180 string sname = 2;
181 };
182}
183
184/*
185* Maps
186* Map fields cannot be repeated.
187* Ordering Of A Map Is Not Guaranteed.
188*/
189
190message MessageWithMaps {
191 map<string, string> mapOfMessages = 1;
192}
193
194
195/*
196* Packages
197* Used for preventing name clashes between protocol message types
198* Syntax:
199 package ${packageName};
200
201 To Access the package;
202 ${packageName}.${messageName} = ${tagNumber};
203*/
204
205/*
206* Services
207* Message Types Defined For Using In RPC system.
208* When protoc compiler generates for various languages it generates stub methods for the services.
209*/
210
211message SearchRequest {
212 string queryString = 1;
213}
214
215message SearchResponse {
216 string queryResponse = 1;
217}
218service SearchService {
219 rpc Search (SearchRequest) returns (SearchResponse);
220}
Generating Classes In Various Languages For Protocol Buffers ¶
1protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR --go_out=DST_DIR --ruby_out=DST_DIR --objc_out=DST_DIR --csharp_out=DST_DIR path/to/file.proto