]> asedeno.scripts.mit.edu Git - cl-protobufs.git/blob - cl-protobufs.rst
Update the documentation
[cl-protobufs.git] / cl-protobufs.rst
1 .. raw:: LaTeX
2
3    \setlength{\parindent}{0pt}
4    \setlength{\parskip}{6pt plus 2pt minus 1pt}
5
6
7 =========================
8 Protobufs for Common Lisp
9 =========================
10
11
12 :Description: Protobufs for Common Lisp
13 :Author: Scott McKay <swm@google.com>
14 :Date: $Date: 2012-04-10 14:18:00 -0500 (Tue, 10 Apr 2012) $
15
16 .. contents::
17 ..
18     1  Introduction
19       1.1  Implementation notes
20       1.2  Model classes
21     2  Defining a Protobufs schema
22       2.1  .proto file to Lisp conversion
23       2.2  CLOS classes to .proto conversion
24       2.3  Using .proto files directly
25       2.4  Using the Protobufs macros
26     3  Serializing and deserializing
27       3.1  Wire format
28       3.1  Text format
29     4  Python compatibility functions
30
31
32 Introduction
33 ============
34
35 The Protobufs library provides a way for Common Lisp programs to use
36 existing (or define new) Protobufs "schemas", and serialize and
37 deserialize objects to and from the Protobufs wire and text formats.
38
39 To use it, first load the ASDF declaration file ``protobufs/protobufs.asd``
40 and then use ASDF to load the library.
41
42
43 Implementation notes
44 --------------------
45
46 The Protobufs library defines a set of model classes that describes a
47 protobufs "schema". There is a class that describes one .proto file
48 (i.e., one "schema"), options, enums and enum values, messages and
49 fields, and services and RPCs.
50
51 The library provides the means to convert several kinds of inputs into
52 the Protobufs models, including:
53
54  - Parse an existing .proto file into a set of model objects.
55  - Convert a set of related CLOS classes into a set of model objects.
56  - Compile a ``proto:define-proto`` macro call into a set of model objects.
57
58 It also provides two ways to convert the model objects into outputs:
59
60  - Print a set of model objects using the standard Protobufs v2 syntax.
61  - Print a set of model objects using the Common Lisp syntax, defined below.
62
63 There are two formats for serialization and deserialization:
64
65  - The wire format, which is compact and fast.
66  - The text format, which is human readable.
67
68 Finally, there is a validator that takes an old version of a Protobufs
69 schema and a new version of the same schema and generates a set of
70 warnings that describes any incompatibilities between the old schema and
71 the new one.
72
73
74 Model classes
75 -------------
76
77 ::
78
79   proto:protobuf                                                [Class]
80
81 The class the represents a Protobufs schema, i.e., one .proto file.
82 It has slots for the name, options, enums, messages and services.
83
84
85 ::
86
87   proto:protobuf-option                                         [Class]
88
89 The class that represents a Protobufs option.
90 It has slots for a key and a value.
91
92
93 ::
94
95   proto:protobuf-enum                                           [Class]
96
97 The class that represents a Protobufs enum type.
98 It has slots for the enum name and its values.
99
100
101 ::
102
103   proto:protobuf-enum-value                                     [Class]
104
105 The class that represents one value in a Protobufs enum type.
106 It has slots for the value name and the value index.
107
108 ::
109
110   proto:protobuf-message                                        [Class]
111
112 The class that represents a Protobufs message.
113 It has slots for the name, options, nested enums and messages, and fields.
114
115 ::
116
117   proto:protobuf-field                                          [Class]
118
119 The class that represents one field in a Protobufs message.
120 It has slots for the name, type, index and options.
121
122 ::
123
124   proto:protobuf-service                                        [Class]
125
126 The class that represents a Protobufs service.
127 It has slots for the name, options and RPCs.
128
129 ::
130
131   proto:protobuf-rpc                                            [Class]
132
133 The class that represents one RPC descriptions in a Protobufs service.
134 It has slots for the name, input type, output type and options.
135
136
137 Defining a Protobufs schema
138 ===========================
139
140 There are several ways to define a Protobufs schema: convert a .proto
141 file to a .lisp source file and then using the Lisp file; convert a set
142 of Lisp classes to a Protobufs model, and then use either the .lisp or
143 the .proto representation of the model; use a .proto file directly in as
144 ASDF system; or use the Protobufs macros in a Lisp source file.
145
146
147 .proto file to Lisp conversion
148 ------------------------------
149
150 If you have an existing .proto source file that you would like to
151 convert to Lisp classes (more precisely, to the macros defined by the
152 Protobufs library), you can use ``proto:parse-protobuf-from-file`` to read the
153 .proto file and then use ``proto:write-protobuf`` to write a new .lisp file.
154
155 ::
156
157   proto:parse-protobuf-from-file (filename)                     [Function]
158
159 Parses the contents of the file given by *filename*, and returns the
160 Protobufs model (a set object objects rooted at ``proto:protobuf``)
161 corresponding to the parsed file. The name of the Protobufs schema is
162 generated automatically from the file name.
163
164
165 ::
166
167   proto:parse-protobuf-from-stream (stream &key name class)     [Function]
168
169 Parses the contents of the stream *stream*, and returns the Protobufs
170 schema corresponding to the parsed file. If *name* is supplied, it gives
171 the Protobufs name for the schema. If *class* is supplied, it gives the
172 Lisp name.
173
174
175 ::
176
177   proto:write-protobuf (protobuf &key stream type)              [Function]
178
179 Pretty-prints the Protobufs schema *protobuf* onto the stream,
180 which defaults to ``*standard-output*``.
181
182 ``type`` can be either ``:proto`` or ``:lisp``.
183
184
185 CLOS classes to .proto conversion
186 ---------------------------------
187
188 If you have an existing set of CLOS classes that you would like to
189 convert to a Protobufs schema, you can use ``proto:generate-protobuf-schema-from-classes``.
190
191 Note that the Protobufs schema is an *approximation* of a good schema.
192 You should review it and, if necessary, change it (and probably the Lisp
193 classes as well) until you have a good Protobufs schema definition.
194
195 ::
196
197   proto:generate-protobuf-schema-for-classes (classes           [Function]
198                                               &key name package)
199
200 Given a list of class names *classes*, this generates a Protobufs schema
201 for the classes, generating any necessary enum types that correspond to
202 Lisp ``member`` types.
203
204 *name* and *package* can be supplied to give the Protobufs name and package.
205
206
207 ::
208
209   proto:write-protobuf-schema-for-classes (classes              [Function]
210                                            &key stream type name package)
211
212 Given a list of class names *classes*, this generates a Protobufs schema
213 for the classes, generating enum types as necessary, and then
214 pretty-prints the result onto *stream*. *type* can be either ``:proto``
215 (the default) or ``:lisp``.
216
217 *name* and *package* can be supplied to give the Protobufs name and package.
218
219
220 Using .proto files directly
221 ---------------------------
222
223 In addition to using the tools described above to convert between .proto
224 files and .lisp files, you can also use .proto files directly in ASDF
225 systems. Just use the ASDF module type ``:proto`` in your system, and
226 compile and load the system in the usual way. This will create both the
227 Protobufs model and the Lisp classes that correspond to the Protobufs
228 messages.
229
230
231 Using the Protobufs macros
232 --------------------------
233
234 You can define a Protobufs schema entirely within Lisp by using the
235 following macros. For example::
236
237   (proto:define-proto color-wheel
238       (:package color-wheel
239        :documentation "Color wheel example")
240     (proto:define-message color-wheel
241         (:conc-name color-wheel-)
242       (name   :type string)
243       (colors :type (proto:list-of color) :default ()))
244     (proto:define-message color
245         (:conc-name color-
246          :documentation "A (named) color")
247       (name    :type (or string null))
248       (r-value :type integer)
249       (g-value :type integer)
250       (b-value :type integer))
251     (proto:define-message get-color-request ()
252       (wheel :type color-wheel)
253       (name  :type string))
254     (proto:define-message add-color-request ()
255       (wheel :type color-wheel)
256       (color :type color))
257     (proto:define-service color-wheel ()
258       (get-color (get-color-request color)
259         :options ("deadline" "1.0")
260         :documentation "Look up a color by name")
261       (add-color (add-color-request color)
262         :options ("deadline" "1.0")
263         :documentation "Add a new color to the wheel")))
264
265 This will create the Protobufs model objects, Lisp classes and enum
266 types that correspond to the model. The .proto file of the same schema
267 looks like this::
268
269   syntax = "proto2";
270
271   package color_wheel;
272
273   message ColorWheel {
274     required string name = 1;
275     repeated Color colors = 2;
276   }
277
278   message Color {
279     optional string name = 1;
280     required int64 rValue = 2;
281     required int64 gValue = 3;
282     required int64 bValue = 4;
283   }
284
285   message GetColorRequest {
286     required ColorWheel wheel = 1;
287     required string name = 2;
288   }
289
290   message AddColorRequest {
291     required ColorWheel wheel = 1;
292     required Color color = 2;
293   }
294
295   service ColorWheel {
296     rpc GetColor (GetColorRequest) returns (Color) {
297       option deadline = "1.0";
298     }
299     rpc AddColor (AddColorRequest) returns (Color) {
300       option deadline = "1.0";
301     }
302   }
303
304
305 ::
306
307   proto:define-proto (type (&key name syntax package import     [Macro]
308                                  optimize options documentation)
309                       &body messages)
310
311 Defines a Protobufs schema whose name is given by the symbol *type*,
312 corresponding to a .proto file of that name. If *name* is not supplied,
313 the Protobufs name of the schema is the camel-cased rendition of *type*
314 (e.g., ``color-wheel`` becomes ``ColorWheel``); otherwise the Protobufs
315 name is the string *name*.
316
317 *syntax* and package* are strings that give the Protobufs syntax and
318 *package name. *imports* is a list of pathname strings to be imported.
319
320 *optimize* can be either ``:space`` (the default) or ``:speed``. When it
321  is ``:space`` the serialization methods generated for each message are
322  compact, but slower; when it is ``:speed``, the serialization methods
323  will be much faster, but will take more space.
324
325 *options* is a property list whose keys and values are both strings,
326 for example, ``:option ("java_package" "com.yoyodyne.overthruster")``.
327 The are used unchanged in the .proto file.
328
329 *documentation* is a documentation string that is preserved as a comment
330  in the .proto file.
331
332 *body* consists of any number of calls to ``proto:define-enum``,
333 ``proto:define-message`` or ``proto:define-service``.
334
335
336 ::
337
338   proto:define-enum (type (&key name conc-name alias-for        [Macro]
339                                 options documentation)
340                      &body values)
341
342 Defines a Protobufs enum type and a corresponding Lisp deftype whose name
343 is given by the symbol *type*. If *name* is not supplied, the Protobufs
344 name of the enum is the camel-cased rendition of *type*; otherwise the
345 Protobufs name is the string *name*. If *conc-name* is given, it will
346 be used as the prefix for all of the enum value names.
347
348 If *alias-for* is given, no Lisp deftype is defined. Instead, the enum
349 will be used as an alias for an enum type that already exists in Lisp.
350
351 *options*  is a property list whose keys and values are both strings.
352
353 *documentation* is a documentation string that is preserved as a comment
354  in the .proto file.
355
356 ``body`` consists of the enum values, each of which is either a symbol
357 or a list of the form ``(name index)``. By default, the indexes start at
358 0 and are incremented by 1 for each new enum value.
359
360
361 ::
362
363   proto:define-message (type (&key name conc-name alias-for     [Macro]
364                                    options documentation)
365                         &body fields)
366
367 Defines a Protobuf message and a corresponding Lisp defclass whose name
368 is given by the symbol *type*. If *name* is not supplied, the Protobufs
369 name of the enum is the camel-cased rendition of *type*; otherwise the
370 Protobufs name is the string *name*. If *conc-name* is given, it will
371 be used as the prefix for all of the slot accessor names.
372
373 If *alias-for* is given, no Lisp defclass is defined. Instead, the
374 message will be used as an alias for a class that already exists in
375 Lisp. This feature is intended to be used to define messages that will
376 be serialized from existing Lisp classes; unless you get the slot names
377 or readers exactly right for each field, it will be the case that trying
378 to (de)serialize into a Lisp object won't work.
379
380 *options*  is a property list whose keys and values are both strings.
381
382 *documentation* is a documentation string that is preserved as a comment
383  in the .proto file.
384
385 The body consists of fields, or ``proto:define-enum``,
386 ``proto:define-message`` or ``proto:define-extension`` forms.
387
388 Fields take the form ``(slot &key type name default reader)``. *slot*
389 can be either a symbol giving the slot name or a list of the form
390 ``(slot index)``. By default, the field indexes start at 1 and are
391 incremented by 1 for each new field value.  *type* is the type of the
392 slot. *name* can be used to override the defaultly generated Protobufs
393 field name (for example, ``color-name`` becomes ``colorName``).
394 *default* is the default value for the slot. *reader* is a Lisp slot
395 reader function to use to get the value during serialization, as opposed
396 to using ``slot-value``; this is meant to be used when aliasing an
397 existing class.
398
399
400 ::
401
402   proto:define-extension (from to)                              [Macro]
403
404 Defines a field extension for the indexes from *from* to *to*.
405
406
407 ::
408
409   proto:define-service (type (&key name                         [Macro]
410                                    options documentation)
411                         &body rpc-specs)
412
413 Defines a Protobufs service named *type* and corresponding Lisp
414 defgenerics for all its RPCs. If *name* is not supplied, the Protobufs
415 name of the enum is the camel-cased rendition of *type*; otherwise the
416 Protobufs name is the string *name*.
417
418 *options*  is a property list whose keys and values are both strings.
419
420 *documentation* is a documentation string that is preserved as a comment
421  in the .proto file.
422
423 The body is a set of RPC specs of the form
424 ``(name (input-type output-type) &key options documentation)``.
425 *name* is a symbol naming the RPC function. *input-type* and
426 *output-type* may either be symbols or a list of the form ``(type &key name)``.
427
428
429 Serializing and deserializing
430 =============================
431
432 You can serialize from Lisp objects or deserialize into Lisp objects
433 using either the fast and compact Protobufs wire format, or the
434 human-readable text format.
435
436
437 Wire format
438 -----------
439
440 ::
441
442   proto:serialize-object-to-stream (object type                 [Function]
443                                     &key stream visited)
444
445 Serializes the object *object* of type *type* onto the stream *stream*
446 using the wire format. *type* is the Lisp name of a Protobufs message
447 (often the name of a Lisp class) or a ``proto:protobuf-message`` object.
448 *type* defaults to the class of *object*
449
450 *visited* is a hash table used to cache object sizes. If it is supplied,
451 it will be cleared before it is used; otherwise, a fresh table will be
452 created.
453
454 The returned values are a byte vector containing the serialized object
455 and the number of bytes required to serialize the object. If the stream
456 is ``nil``, the buffer is not actually written anywhere.
457
458
459 ::
460
461   proto:serialize-object (object type buffer                    [Generic function]
462                           &optional start visited)
463
464 Serializes the object *object* of type *type* into the byte array
465 *buffer* using the wire format. *type* is the Lisp name of a Protobufs
466 message (often the name of a Lisp class) or a ``proto:protobuf-message``
467 object. *type* defaults to the class of *object*. The buffer is assumed
468 to be large enough to hold the serialized object; if it is not, an
469 out-of-bounds condition may be signalled.
470
471 The object is serialized into the byte array given by *buffer* starting
472 at the fixnum index *start* using the wire format.
473
474 *visited* is a hash table used to cache object sizes.
475
476 The returned values are the modified buffer containing the serialized
477 object and the number of bytes required to serialize the object.
478
479
480 ::
481
482   proto:deserialize-object-from-stream (type &key stream)       [Function]
483
484 Deserializes an object of the given type *type* as a Protobuf object.
485 *type* is the Lisp name of a Protobufs message (usually the name of a
486 Lisp class) or a ``proto:protobuf-message``.
487
488 The returned value is the deserialized object.
489
490
491 ::
492
493   proto:deserialize-object (type buffer &optional start end)    [Generic function]
494
495 Deserializes an object of the given type *type* as a Protobufs object.
496 *type* is the Lisp name of a Protobufs message (usually the name of a
497 Lisp class) or a ``proto:protobuf-message``.
498
499 The encoded bytes come from the byte array given by *buffer*, starting
500 at the fixnum index *start* up to the end of the buffer, given by *end*.
501 If a zero byte is encountered in in the "tag position" during
502 deserialization, this is interpreted as an "end of object" marker.
503
504 The returned values are the deserialized object and the index into the
505 buffer at which the deserialization ended.
506
507
508 ::
509
510   proto:object-size (object type &optional visited)             [Generic function]
511
512 Computes the size in bytes of the object *object* of type *type*.
513 *type* is the Lisp name of a Protobufs message (usually the name of a
514 Lisp class) or a ``proto:protobuf-message``. *type* defaults to the
515 class of *object*
516
517 *visited* is a hash table used to cache object sizes.
518
519 The returned value is the size of the serialized object in bytes.
520
521
522 Text format
523 -----------
524
525 ::
526
527   proto:print-text-format (object &optional type                [Function]
528                            &key stream suppress-line-breaks)
529
530 Prints the object *object* of type *type* onto the stream *stream* using
531 the textual format. *type* defaults to the class of *object*.
532
533 If *suppress-line-breaks* is true, all the output is put on a single line.
534
535
536 ::
537
538   proto:parse-text-format (type &key stream)                    [Function]
539
540 Parses the textual format of an object of the given type *type*. *type*
541 is the Lisp name of a Protobufs message (usually the name of a Lisp
542 class) or a ``proto:protobuf-message``. The input is read from the
543 stream *stream*.
544
545 The returned value is the object.
546
547
548 Python compatibility functions
549 ==============================
550
551 By popular demand, the Protobufs library provides an API that very
552 similar to the API of the Python Protobufs library.
553
554 ::
555
556   proto:clear (object)                                          [Generic function]
557
558 Initializes all of the fields of *object* to their default values.
559
560
561 ::
562
563   proto:is-initialized (object)                                 [Generic function]
564
565 Returns true iff all of the fields of *object* are initialized, i.e.,
566 there are no fields whose value is unbound.
567
568
569 ::
570
571   proto:serialize (object &optional buffer start end)           [Generic function]
572
573 Serializes *object* into *buffer* using the wire format, starting at the
574 index *start* and going no further than *end*. *object* is an object
575 whose Lisp class corresponds to a Protobufs message.
576
577 ::
578
579   proto:merge-from-array (object buffer &optional start end)    [Generic function]
580
581 Deserializes the object encoded in *buffer* into *object*, starting at
582 the index *start* and ending at *end*. *object* is an object whose Lisp
583 class corresponds to a Protobufs message.
584
585
586 ::
587
588   proto:octet-size (object)                                     [Generic function]
589
590 Returns the number of bytes required to serialize *object* using the
591 wire format. *object* is an object whose Lisp class corresponds to a
592 Protobufs message.