Skip to content

Commit f55b521

Browse files
authored
clean up readme and add table of contents (#121)
1 parent d8a4ff5 commit f55b521

File tree

2 files changed

+86
-47
lines changed

2 files changed

+86
-47
lines changed

CONTRIBUTING.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
# Contributing
22

3-
When contributing to this repository, please first discuss the change you wish to make via issue, or any other method with the owners of this repository before contributing a change.
3+
Before contributing to this repository please first discuss the change you wish
4+
to make via issue or any other method with the owners of this repository.
45

5-
Please note that we have a [code of conduct](CODE-OF-CONDUCT.md), please follow it in all your interactions with the project.
6+
Please note that we have a [code of conduct](CODE-OF-CONDUCT.md). Please follow
7+
it in all your interactions with the project.
68

79
## Pull Request Process
810

README.md

+82-45
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,42 @@ Protocol Buffer compiler and runtime for Kotlin.
88

99
Supports only version 3 of the Protocol Buffers language.
1010

11-
#### Features
11+
* [Overview](#overview)
12+
+ [Features](#features)
13+
+ [Not yet implemented](#not-yet-implemented)
14+
+ [Compatibility](#compatibility)
15+
* [Usage](#usage)
16+
+ [Gradle](#gradle)
17+
+ [Generated Code](#generated-code)
18+
* [Runtime Notes](#runtime-notes)
19+
+ [Package](#package)
20+
+ [Message](#message)
21+
+ [Enums](#enums)
22+
- [Representation](#representation)
23+
- [Naming](#naming)
24+
+ [Other Notes](#other-notes)
25+
* [Extensions](#extensions)
26+
+ [Wrapper Types](#wrapper-types)
27+
+ [Non-null fields](#non-null-fields)
28+
+ [Interface implementation](#interface-implementation)
29+
- [Messages](#messages)
30+
- [Oneof Fields](#oneof-fields)
31+
+ [BytesSlice](#bytesslice)
32+
* [gRPC code generation](#grpc-code-generation)
33+
+ [Generated gRPC code](#generated-grpc-code)
34+
+ [Integrating with gRPC's Java API](#integrating-with-grpcs-java-api)
35+
+ [Integrating with gRPC's Kotlin API](#integrating-with-grpcs-kotlin-api)
36+
* [IntelliJ integration](#intellij-integration)
37+
* [Command line code generation](#command-line-code-generation)
38+
* [Contribution](#contribution)
39+
* [Acknowledgements](#acknowledgements)
40+
+ [Authors](#authors)
41+
42+
## Overview
43+
44+
### Features
1245
- Idiomatic and concise [Kotlin builder DSL](#generated-code)
13-
- Protokt-specific options: [non-null types](#nonnull-fields),
46+
- Protokt-specific options: [non-null types](#non-null-fields),
1447
[wrapper types](#wrapper-types),
1548
[interface implementation](#interface-implementation),
1649
and more
@@ -22,25 +55,25 @@ CodedOutputStream for best performance
2255
for use with [grpc-java](#integrating-with-grpcs-java-api) or
2356
[grpc-kotlin](#integrating-with-grpcs-kotlin-api) (see examples in [examples](examples))
2457

25-
#### Not yet implemented
58+
### Not yet implemented
2659

2760
- Reflection support (in progress)
2861
- Kotlin/Native support
2962
- Kotlin/JS support
3063
- Protobuf JSON support
3164

32-
See examples in [testing](testing).
33-
34-
#### Compatibility
65+
### Compatibility
3566

3667
The Gradle plugin requires Java 8+ and Gradle 5.6+. It runs on recent versions of
3768
MacOS, Linux, and Windows.
3869

3970
The runtime and generated code are compatible with Kotlin 1.4+, Java 8+, and Android 4.4+.
4071

41-
### Usage
72+
## Usage
4273

43-
#### Gradle
74+
See examples in [testing](testing).
75+
76+
### Gradle
4477

4578
```groovy
4679
plugins {
@@ -99,13 +132,13 @@ or:
99132
compileJava.enabled = false
100133
```
101134

102-
#### Generated Code
135+
### Generated Code
103136

104137
Generated code is placed in `<buildDir>/generated-sources/<sourceSet.name>/protokt`.
105138

106139
A simple example:
107140

108-
```proto
141+
```protobuf
109142
syntax = "proto3";
110143
111144
package toasttab.protokt.sample;
@@ -249,9 +282,9 @@ any escaping mutability of the provided collection. The Java protobuf
249282
implementation takes a similar approach; it only exposes mutation methods on the
250283
builder and not assignment. Mutating the builder does a similar copy operation.
251284

252-
### Runtime Notes
285+
## Runtime Notes
253286

254-
#### Package
287+
### Package
255288

256289
By default, the Kotlin package of a generated file is the same as the protobuf
257290
package. Second in precedence is the declared `java_package` option, which can
@@ -270,7 +303,7 @@ use to prevent duplicate class issues.
270303

271304
Highest precedence is given to the `(protokt.file).kotlin_package` option:
272305

273-
```proto
306+
```protobuf
274307
syntax = "proto3";
275308
276309
import "protokt/protokt.proto";
@@ -282,7 +315,7 @@ option (protokt.file).kotlin_package = "com.example";
282315
...
283316
```
284317

285-
#### Message
318+
### Message
286319

287320
Each protokt message implements the `KtMessage` interface. `KtMessage` defines
288321
the `serialize()` method and its overloads which can serialize to a byte array,
@@ -293,9 +326,9 @@ Each protokt message has a companion object `Deserializer` that implements the
293326
overloads to construct an instance of the message from a byte array, a Java
294327
InputStream, or others.
295328

296-
#### Enums
329+
### Enums
297330

298-
##### Representation
331+
#### Representation
299332

300333
Protokt represents enum fields as sealed classes with an integer value and name.
301334
Protobuf enums cannot be represented as Kotlin enum classes since Kotlin enum
@@ -329,14 +362,14 @@ sealed class PhoneType(
329362
}
330363
```
331364

332-
##### Naming
365+
#### Naming
333366

334367
To keep enums ergonomic while promoting protobuf best practices, enums that have
335368
all values
336369
[prefixed with the enum type name](https://developers.google.com/protocol-buffers/docs/style#enums)
337370
will have that prefix stripped in their Kotlin representations.
338371

339-
#### Other Notes
372+
### Other Notes
340373

341374
- `optimize_for` is ignored.
342375
- `repeated` fields are represented as Lists.
@@ -347,13 +380,13 @@ single property.
347380
akin to `protobuf-java`'s `ByteString`.
348381
- Protokt implements proto3's `optional`.
349382

350-
### Extensions
383+
## Extensions
351384

352385
See examples of each option in the [options](testing/options/src/main/proto)
353386
project. All protokt-specific options require importing `protokt/protokt.proto`
354387
in the protocol file.
355388

356-
#### Wrapper Types
389+
### Wrapper Types
357390

358391
Sometimes a field on a protobuf message corresponds to a concrete nonprimitive
359392
type. In standard protobuf the user would be responsible for this extra
@@ -363,7 +396,7 @@ types. Some standard types are implemented in [extensions](extensions).
363396

364397
Wrap a field by invoking the `(protokt.property).wrap` option:
365398

366-
```proto
399+
```protobuf
367400
message WrapperMessage {
368401
google.protobuf.Timestamp instant = 1 [
369402
(protokt.property).wrap = "java.time.Instant"
@@ -510,7 +543,7 @@ determine what behavior should be in these cases. To represent nullable
510543
primitive wrappers use well-known types or Proto3's `optional`. For example for
511544
a nullable UUID:
512545

513-
```proto
546+
```protobuf
514547
google.protobuf.BytesValue uuid = 1 [
515548
(protokt.property).wrap = "java.util.UUID"
516549
];
@@ -523,14 +556,14 @@ optional bytes optional_uuid = 2 [
523556

524557
Wrapper types can be repeated:
525558

526-
```proto
559+
```protobuf
527560
repeated bytes uuid = 1 [
528561
(protokt.property).wrap = "java.util.UUID"
529562
];
530563
```
531564

532565
And they can also be used for map keys and values:
533-
```proto
566+
```protobuf
534567
map<string, protokt.ext.InetSocketAddress> map_string_socket_address = 1 [
535568
(protokt.property).key_wrap = "StringBox",
536569
(protokt.property).value_wrap = "java.net.InetSocketAddress"
@@ -547,12 +580,12 @@ _N.b. Well-known type nullability is implemented with
547580
for each message defined in
548581
[wrappers.proto](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/wrappers.proto)._
549582

550-
#### Nonnull fields
551-
If a message has no meaning whatsoever when a particular nonscalar field is
583+
### Non-null fields
584+
If a message has no meaning whatsoever when a particular non-scalar field is
552585
missing, you can emulate proto2's `required` key word by using the
553586
`(protokt.property).non_null` option:
554587

555-
```proto
588+
```protobuf
556589
message Sample {}
557590
558591
message NonNullSampleMessage {
@@ -567,7 +600,7 @@ without using Kotlin's `!!`.
567600

568601
Oneof fields can also be declared non-null:
569602

570-
```proto
603+
```protobuf
571604
message NonNullSampleMessage {
572605
oneof non_null_oneof {
573606
option (protokt.oneof).non_null = true;
@@ -580,9 +613,9 @@ message NonNullSampleMessage {
580613
Note that deserialization of a message with a non-nullable field will fail if the
581614
message being decoded does not contain an instance of the required field.
582615

583-
#### Interface implementation
616+
### Interface implementation
584617

585-
##### Messages
618+
#### Messages
586619

587620
To avoid the need to create domain-specific objects from protobuf messages you
588621
can declare that a protobuf message implements a custom interface with
@@ -596,7 +629,7 @@ interface Model {
596629
}
597630
```
598631

599-
```proto
632+
```protobuf
600633
package com.protokt.sample;
601634
602635
message ImplementsSampleMessage {
@@ -622,7 +655,7 @@ Messages can also implement interfaces by delegation to one of their fields;
622655
in this case the delegated interface need not live in a separate project, as
623656
protokt requires no inspection of it:
624657

625-
```proto
658+
```protobuf
626659
message ImplementsWithDelegate {
627660
option (protokt.class).implements = "Model2 by modelTwo";
628661
@@ -634,7 +667,7 @@ message ImplementsWithDelegate {
634667

635668
Note that the `by` clause references the field by its lower camel case name.
636669

637-
##### Oneof Fields
670+
#### Oneof Fields
638671

639672
Oneof fields can declare that they implement an interface with the
640673
`(protokt.oneof).implements` option. Each possible field type of the oneof must
@@ -761,15 +794,15 @@ fun printVersion(config: MyObjectWithConfig.Config) {
761794
}
762795
```
763796

764-
#### BytesSlice
797+
### BytesSlice
765798

766799
When reading messages that contain other serialized messages as `bytes` fields,
767800
protokt can keep a reference to the originating byte array to prevent a large
768801
copy operation on deserialization. This can be desirable when the wrapping
769802
message is short-lived or a thin metadata shim and doesn't include much memory
770803
overhead:
771804

772-
```proto
805+
```protobuf
773806
message SliceModel {
774807
int64 version = 1;
775808
@@ -779,7 +812,7 @@ message SliceModel {
779812
}
780813
```
781814

782-
### gRPC code generation
815+
## gRPC code generation
783816

784817
Protokt will generate code for gRPC method and service descriptors when the
785818
`generateGrpc` option is enabled:
@@ -801,11 +834,11 @@ protokt {
801834
Protokt does not yet generate full client and server stubs. It does generate the
802835
components necessary to integrate with gRPC's Java and Kotlin APIs.
803836

804-
#### Generated gRPC code
837+
### Generated gRPC code
805838

806839
Consider gRPC's canonical Health service:
807840

808-
```proto
841+
```protobuf
809842
syntax = "proto3";
810843
811844
package grpc.health.v1;
@@ -859,7 +892,7 @@ constructor-injected method implementations is included in the examples below.
859892
These two implementation styles can emulate each other, so the choice of which
860893
to use is perhaps a matter of taste.
861894

862-
#### Integrating with gRPC's Java API
895+
### Integrating with gRPC's Java API
863896

864897
A gRPC service using grpc-java (and therefore using StreamObservers for
865898
asynchronous communication):
@@ -904,7 +937,7 @@ fun checkHealth(): HealthCheckResponse =
904937
)
905938
```
906939

907-
#### Integrating with gRPC's Kotlin API
940+
### Integrating with gRPC's Kotlin API
908941

909942
To use the coroutine-based implementations provided by grpc-kotlin:
910943

@@ -950,7 +983,7 @@ suspend fun checkHealth(): HealthCheckResponse =
950983
)
951984
```
952985

953-
### IntelliJ integration
986+
## IntelliJ integration
954987

955988
If IntelliJ doesn't automatically detect the generated files as source files,
956989
you may be missing the `idea` plugin. Apply the `idea` plugin to your Gradle
@@ -962,7 +995,7 @@ plugins {
962995
}
963996
```
964997

965-
### Command line code generation
998+
## Command line code generation
966999

9671000
```sh
9681001
protokt % ./gradlew assemble
@@ -987,7 +1020,11 @@ protokt % protoc \
9871020
test.proto
9881021
```
9891022

990-
### Contribution
1023+
## Contribution
1024+
1025+
Community contributions are welcome. See the
1026+
[contribution guidelines](CONTRIBUTING.md) and the project
1027+
[code of conduct](CODE-OF-CONDUCT.md).
9911028

9921029
To enable rapid development of the code generator, the protobuf conformance
9931030
tests have been compiled and included in the `testing` project. They run on Mac
@@ -997,9 +1034,9 @@ When integration testing the Gradle plugin, note that after changing the plugin
9971034
and republishing it to the integration repository, `./gradlew clean` is needed
9981035
to trigger regeneration of the protobuf files with the fresh plugin.
9991036

1000-
### Acknowledgements
1037+
## Acknowledgements
10011038

1002-
#### Authors
1039+
### Authors
10031040

10041041
[Ben Gordon](mailto:[email protected]),
10051042
[Andrew Parmet](mailto:[email protected]),

0 commit comments

Comments
 (0)