7979import java .util .function .Predicate ;
8080import java .util .stream .Collectors ;
8181import org .jspecify .annotations .NullMarked ;
82+ import org .jspecify .annotations .Nullable ;
8283
8384@ NullMarked
8485public class HttpJsonServiceStubClassComposer extends AbstractTransportServiceStubClassComposer {
8586 private static final HttpJsonServiceStubClassComposer INSTANCE =
8687 new HttpJsonServiceStubClassComposer ();
8788
88- private static final TypeStore FIXED_REST_TYPESTORE = createStaticTypes ();
89- private static final VariableExpr TYPE_REGISTRY_VAR_EXPR =
89+ static final TypeStore FIXED_REST_TYPESTORE = createStaticTypes ();
90+ static final VariableExpr TYPE_REGISTRY_VAR_EXPR =
9091 VariableExpr .builder ()
9192 .setVariable (
9293 Variable .builder ()
@@ -266,7 +267,7 @@ protected List<MethodDefinition> createGetMethodDescriptorsMethod(
266267 .build ());
267268 }
268269
269- private BiFunction <String , List <Expr >, Function <MethodInvocationExpr , MethodInvocationExpr >>
270+ static BiFunction <String , List <Expr >, Function <MethodInvocationExpr , MethodInvocationExpr >>
270271 getMethodMaker () {
271272 return (mName , argExpr ) ->
272273 (m ) ->
@@ -277,7 +278,12 @@ protected List<MethodDefinition> createGetMethodDescriptorsMethod(
277278 .build ();
278279 }
279280
280- private List <Expr > getRequestFormatterExpr (Method protoMethod , boolean restNumericEnumsEnabled ) {
281+ static List <Expr > getRequestFormatterExpr (Method protoMethod , boolean restNumericEnumsEnabled ) {
282+ return getRequestFormatterExpr (protoMethod , restNumericEnumsEnabled , null );
283+ }
284+
285+ static List <Expr > getRequestFormatterExpr (
286+ Method protoMethod , boolean restNumericEnumsEnabled , @ Nullable String pathPrefix ) {
281287 BiFunction <String , List <Expr >, Function <MethodInvocationExpr , MethodInvocationExpr >>
282288 methodMaker = getMethodMaker ();
283289
@@ -296,14 +302,22 @@ private List<Expr> getRequestFormatterExpr(Method protoMethod, boolean restNumer
296302 .setGenerics (TypeNode .STRING .reference (), TypeNode .STRING .reference ())
297303 .build ());
298304
305+ String pathPattern = protoMethod .httpBindings ().lowerCamelPattern ();
306+ if (pathPrefix != null ) {
307+ String normalizedPrefix = pathPrefix .startsWith ("/" ) ? pathPrefix : "/" + pathPrefix ;
308+ if (normalizedPrefix .endsWith ("/" )) {
309+ normalizedPrefix = normalizedPrefix .substring (0 , normalizedPrefix .length () - 1 );
310+ }
311+ pathPattern =
312+ normalizedPrefix + (pathPattern .startsWith ("/" ) ? pathPattern : "/" + pathPattern );
313+ }
314+
299315 expr =
300316 methodMaker
301317 .apply (
302318 "setPath" ,
303319 Arrays .asList (
304- ValueExpr .withValue (
305- StringObjectValue .withValue (
306- protoMethod .httpBindings ().lowerCamelPattern ())),
320+ ValueExpr .withValue (StringObjectValue .withValue (pathPattern )),
307321 createFieldsExtractorClassInstance (
308322 protoMethod ,
309323 extractorVarType ,
@@ -318,7 +332,24 @@ private List<Expr> getRequestFormatterExpr(Method protoMethod, boolean restNumer
318332 .apply (
319333 "setAdditionalPaths" ,
320334 protoMethod .httpBindings ().lowerCamelAdditionalPatterns ().stream ()
321- .map (a -> ValueExpr .withValue (StringObjectValue .withValue (a )))
335+ .map (
336+ a -> {
337+ String additionalPath = a ;
338+ if (pathPrefix != null ) {
339+ String normalizedPrefix =
340+ pathPrefix .startsWith ("/" ) ? pathPrefix : "/" + pathPrefix ;
341+ if (normalizedPrefix .endsWith ("/" )) {
342+ normalizedPrefix =
343+ normalizedPrefix .substring (0 , normalizedPrefix .length () - 1 );
344+ }
345+ additionalPath =
346+ normalizedPrefix
347+ + (additionalPath .startsWith ("/" )
348+ ? additionalPath
349+ : "/" + additionalPath );
350+ }
351+ return ValueExpr .withValue (StringObjectValue .withValue (additionalPath ));
352+ })
322353 .collect (Collectors .toList ()))
323354 .apply (expr );
324355 }
@@ -371,7 +402,7 @@ private List<Expr> getRequestFormatterExpr(Method protoMethod, boolean restNumer
371402 return Collections .singletonList (expr );
372403 }
373404
374- private List <Expr > setResponseParserExpr (Method protoMethod ) {
405+ static List <Expr > setResponseParserExpr (Method protoMethod ) {
375406 BiFunction <String , List <Expr >, Function <MethodInvocationExpr , MethodInvocationExpr >>
376407 methodMaker = getMethodMaker ();
377408
@@ -726,7 +757,7 @@ private List<Expr> setPollingRequestFactoryExpr(
726757 .build ());
727758 }
728759
729- private Expr createBodyFieldsExtractorClassInstance (
760+ private static Expr createBodyFieldsExtractorClassInstance (
730761 Method method ,
731762 TypeNode extractorReturnType ,
732763 Set <HttpBinding > httpBindingFieldNames ,
@@ -839,7 +870,7 @@ private Expr createBodyFieldsExtractorClassInstance(
839870 .build ();
840871 }
841872
842- private Expr createFieldsExtractorClassInstance (
873+ private static Expr createFieldsExtractorClassInstance (
843874 Method method ,
844875 TypeNode extractorReturnType ,
845876 Set <HttpBinding > httpBindingFieldNames ,
@@ -993,7 +1024,7 @@ private Expr createFieldsExtractorClassInstance(
9931024 }
9941025
9951026 @ VisibleForTesting
996- String getBindingFieldMethodName (
1027+ static String getBindingFieldMethodName (
9971028 HttpBinding httpBindingField , int descendantFieldsLengths , int index , String currFieldName ) {
9981029 if (index == descendantFieldsLengths - 1 ) {
9991030 if (httpBindingField .isRepeated ()) {
@@ -1006,13 +1037,13 @@ String getBindingFieldMethodName(
10061037 return String .format ("get%s" , currFieldName );
10071038 }
10081039
1009- private List <Expr > getHttpMethodTypeExpr (Method protoMethod ) {
1040+ static List <Expr > getHttpMethodTypeExpr (Method protoMethod ) {
10101041 return Collections .singletonList (
10111042 ValueExpr .withValue (
10121043 StringObjectValue .withValue (protoMethod .httpBindings ().httpVerb ().toString ())));
10131044 }
10141045
1015- private List <Expr > getMethodTypeExpr (Method protoMethod ) {
1046+ static List <Expr > getMethodTypeExpr (Method protoMethod ) {
10161047 MethodType methodType ;
10171048 switch (protoMethod .stream ()) {
10181049 case NONE :
@@ -1042,6 +1073,10 @@ private List<Expr> getMethodTypeExpr(Method protoMethod) {
10421073 return Collections .singletonList (expr );
10431074 }
10441075
1076+ static String getProtoRpcName (Service protoService , Method protoMethod ) {
1077+ return INSTANCE .getProtoRpcFullMethodName (protoService , protoMethod );
1078+ }
1079+
10451080 @ Override
10461081 protected List <Expr > createOperationsStubInitExpr (
10471082 GapicContext context ,
@@ -1365,7 +1400,8 @@ private List<MethodDefinition> createInvalidClassMethods(Service service) {
13651400 .setType (FIXED_TYPESTORE .get ("UnsupportedOperationException" ))
13661401 .setMessageExpr (
13671402 String .format (
1368- "Not implemented: %s(). %s transport is not implemented for this method yet." ,
1403+ "Not implemented: %s(). %s transport is not implemented for"
1404+ + " this method yet." ,
13691405 callableName , getTransportContext ().transport ()))
13701406 .build ())))
13711407 .build ());
0 commit comments