API¶
The Coco Platform currently provides APIs for the following language:
Whilst the API is customised to fit in naturally with each language, there are some common principles that are language independent. This section outlines these general principles, whilst the language-specific documentation is contained in the above sections.
Implementation¶
The API for each of the above languages is implemented using a thin wrapper over the top of gRPC
which communicates with a separate server process called coco-platform-server
running on the same host. Whilst the
fact that the API internally uses gRPC to communicate with a remote server process should not be visible to users of the
API, there are several important points to consider:
When an override of one of the virtual classes is executed (e.g. on
DiagnosticConsumer
), it will be executed on one of the gRPC threads, rather than one of the normal application threads.Most objects are actually just thin wrappers around a server-side object. For example, the lifetime of the
ProjectTreeNode
nodes returned by theSession
object is determined by the lifetime of the Session object. If the Session object is garbage-collected before theProjectTreeNode
nodes are no longer required, then the API will crash. In general, the following classes should be treated as owning memory of all objects that are returned by any of their methods:Listeners (e.g.
DiagnosticConsumer
orSessionListener
) are not retained by the receiving object even when using methods such asaddDiagnosticsConsumer
. This means that when the garbage collector next runs, the listener will be collected, meaning that further events will be silently dropped. For example, consider the following:APIClient client = ...; StandaloneContext context = new StandaloneContext(client); MyDiagnosticLogger listener = new MyDiagnosticLogger(client); context.addDiagnosticsConsumer(listener); // no further references to listener are made context.loadModule("File.coco");
If the garbage collector runs whilst
loadModule
is executing, thenlistener
will be garbage collected, meaning that diagnostics will be silently dropped.To avoid this, when calling methods such as
addDiagnosticsConsumer
always ensure to retain a reference to the listener for as long as thelistener
is relevant.
Licensing¶
Usage of the API requires a license in the same way as other Coco Platform tools. Under normal usage the API will share the same licenses as the other Coco Platform tools, meaning that if a user has already signed into, for example, Eclipse, then they will not need to do anything in order to use the API.
Warning
It is vital that you check if the user has a valid license before attempting to construct any of the other API classes. Failure to do so will result in the application terminating abruptly. For example, the following code illustrates how the Java API can be used to check the license status:
UserInfo userInfo = new UserInfo(apiClient);
LicenseResponse response = userInfo.hasLicense(Arrays.asList(ProductFeature.CocoPlatformBase));
if (response.getLicensed()) {
// Ok: a valid license has been found
} else {
// Not ok: do not continue to use the API.
System.out.println("Failed to acquire license: " + response.getNonLicensedReason());
}
General Advice¶
The API provides two main ways of loading Coco files, the Context API and the Session API, which have different strengths and weaknesses. This section gives an overview of these two different methods in order to help determine which one is most appropriate for a given use case.
The Session API, as documented in Session
, provides a high-level API that is ideally suited for implementing
IDE-like features. The Session API allows a user to add several folders to a single object, and is capable of
asynchronously loading the files in the background whilst also asynchronously verifying and generating code. It also
monitors the filesystem for any relevant changes, and will automatically reload relevant projects when changes are
detected. It also automatically handles Coco packages (as specified by Coco.toml
files).
In contrast, the Context API StandaloneContext
provides a lower-level API that is better suited to applications
that generate Coco and fully manage all coco files, and their lifecycle. In contrast to the Session API, all methods are
synchronous and the API will not automatically reload anything. In fact, the StandaloneContext
does not support
reloading at all: instead a new StandaloneContext
should be created to handle the new version of the file.